Design question: does the Phone dial the PhoneNumber, or does the PhoneNumber dial itself on the Phone?

This is re-posted from something I posted on the DDD Yahoo! group.

All things being equal, do you write phone.dial(phoneNumber) or phoneNumber.dialOn(phone)? Keep in mind possible future requirements (account numbers in addition to phone numbers, calculators in addition to phones).

The choice tends to illustrate how the idioms of Information Expert, Single Responsibility Principle, and Tell Don't Ask are at odds with each other.

phoneNumber.dialOn(phone) favors Information Expert and Tell Don't Ask, while phone.dial(phoneNumber) favors Single Responsibility Principle.

If you are familiar with Ken Pugh's work in Prefactoring, this is the Spreadsheet Conundrum; do you add rows or columns?

-------------Problems Reply------------

Choosing whether to give the column objects or the row objects the dial method doesn't change how the program will scale.

The dial method is just going to be itself a sequence of row and column methods. You have to ask what those methods depend on.

If the sequence of row methods doesn't depend on knowing exactly which column object is involved (but does depend on which particular row object is involved) and vice versa for the sequence of column methods, then the problem scales as m + n (m = num. rows, n = num. cols). When you create a new row it doesn't actually save you any work had the column method been assigned the 'dial' method. You still have to specify a unique sequence of row methods for use in 'dial' somewhere!

If, however, say the sequence of column methods inside 'dial' doesn't even depend on which column object is involved (they use one 'generic' sequence of column methods), then the problem just scales as m. It doesn't actually matter if you've assigned the 'dial' method to the column objects, the program still scales as m; essentially no work is required to make a new dial method when adding 1 more column object and you clearly have the option of abstracting all those dial methods themselves into one generic dial method.

phone.dial(), because it's the phone that does the dialing.

Actor.Verb( inputs ) -> outputs.

Meh - User.Dial(number). The phone is meaningless in the given context. SOL (speak out loud) is a nice way to think this through (idioms and principles aside):

Phones have a dial. They can't dial themselves. Phone numbers are digits. Users dial PhoneNumbers on a Phone Dial.

the question assumes the context of the answer, and thus creates a false dilemma

the 'spreadsheet conundrum' is a false dichotomy in this example: rows and columns are the presentation layer, not necessarily the data layer. The comments below tell me i misunderstood the analogy, but i don't think so - saying 'should this be a row or a column, which one is more likely to change' is forcing an unnecessary choice on the problem space - they are both equally likely to change. And in this specific example, this leads to choosing the wrong [yes wrong] paradigm for the solution. Dialing a phone is how old mechanical devices initiated a connection to another old mechanical device; this is hardly an apt analogy for modern telephony. And assuming that there is a 'user' to initiate the call simply moves the problem - although it moves it in the correct direction, i.e. away from the rotary-phone model ;-)

If you look at how the TAPI [sorry about the typo earlier, it's TAPI not ATAPI!] protocol works, there is a call controller - equivalent to the 'user' i suppose in some sense - that manages the connections between devices. One device does not call another, the call controller connects devices. So the example below is still essentially correct. It might be more correct to use a CallController object instead of a generic Connection, but the analogy should be clear enough as is.

In this example, a phone is a device with an address aka a 'phone number'. The 'dial' operator establishes a connection between the two devices. So the answer is:

Phone p1 = new Phone(phoneNumber1);
Phone p2 = new Phone(phoneNumber2);
Connection conn = new Connection(p1,p2);

this will support multi-party calls as well, by overloading Connection to include a list of devices or other connections, e.g.

Connection confCall = new Connection(p1,p2,p3,p4,p5,p6);

Connection joinCall = new Connection(confCall,p7,p8,conn);

look at the TAPI protocol for more examples

If your writing OO then you start with the basic object, which is not the number, the number is going INTO the phone, so phone.dial() that way you can also phone.answer() phone.disconnect() phone.powerOFF, ect.

Another way to look at it is does the phone dial the number or does the number dial the phone?

Clearly, phone.Dial(number)

Neither. The User dials a Phone Number on a Phone.

Clearly the PhoneUserInterface interface, which you can get an implementation of from the PhoneUserFactory.CreatePhoneUser() method, has a method dial(Phone, Number) that you can use to dial the phone.

EDIT: Answering the comment. Neither. The phone should have a buttonPressed() or something like that. The user enters the digits/characters of the phone number via that interface.

A: phone.dial(phone_number)

The PhoneNumber is dumb and is only a dataset. When the "dialling" happens, should the the PhoneNumber object know how to dial? There are many states to keep track of, like:

  • Is the phone already on another call? (if yes/no, what to do?)
  • What happens if the method of dialling changes? (global roaming, different carrier, etc.)
  • Also, what about scope? When a call is made, the phone number needs to be added to the list of recent outgoing calls.

If your PhoneNumber object needs to know all this, it's not DRY and your code will be less portable and more likely to break.

I would say that Steven A. Lowe has it down. This should be done by a Controller type object to handle the different states, etc. Keep your PhoneNumber object dumb and give the smarts to the middle-man who needs to worry about keeping the phone humming along.

Not to be the negative one here, but these kinds of questions are very academic. It completely depends on the application. I can think of very good reasons for doing it either way, and I've seen too many good programmers get bogged down in this kind of moot design details.

I'm not sure how that relates to the spreadsheet conundrum. Do you expect, in the future, to use phones to dial account numbers? To use phone numbers on calculators? Your example of "future requirements preparedness" is not very good...

Plus, you use the verb "dial". Sure, I could imagine "dialing" an account number on a phone. (It's a big stretch, though.) But if this phone number is to be used on a calculator, would you call the action "dialing"? If the name of the function changes depending on the type of parameter it gets passed, you have a design error.

In a typical OO design, objects get sent messages carrying data, not the other way around.

phone.dial() +1.

What is the variant state or behavior of a PhoneNumber? The only thing that comes to mind are "dialing rules" (dial country code if outside, dial "9" to get outside line, etc.). That context seems well suited to the Phone.

If your object model doesn't require variance -- a number is just a sequence of digits, "dial" is just foreach(digit in phonenumber) { press(digit); } I'm with Rob Conery: meh.

I wouldn't have phone number as a class at all as it does not have any behavior, it's just a data element.

Category:oop Views:4 Time:2008-09-16
Tags: oop

Related post

  • Too many columns design question 2009-07-27

    I have a design question. I have to store approx 100 different attributes in a table which should be searchable also. So each attribute will be stored in its own column. The value of each attribute will always be less than 200, so I decided to use TI

  • Authorization System Design Question 2009-07-27

    I'm trying to come up with a good way to do authentication and authorization. Here is what I have. Comments are welcome and what I am hoping for. I have php on a mac server. I have Microsoft AD for user accounts. I am using LDAP to query the AD when

  • WPF design question (custom control or mvvm) 2009-08-20

    Here is the scenario: I have a visual that displays some data The data to the visual can come in one of two ways Via user input through the keyboard or mouse Via some backend source Both these data inputs can be of one of two forms Control data or Ra

  • DB Design question: Tree (one table) vs. Two tables for tweets and retweets? 2009-09-29

    I've heard that on stackoverflow questions and answers are stored in the same DB table. If you were to build a twitter like service that only would allow 1 level of commenting. ie 1 tweet and then comments/replies to that tweet but no re-comments or

  • General Design Question 2009-11-02

    I have a general design question: There is a junction, with four roads connecting to it. Each road has 2 lanes. What would be the best way to design a program to handle such junction. It should allow 2 cars 2 go through the junction if they don't int

  • WPF Custom Control Design question 2009-12-03

    I have a design question: If you had to make a WPF Combobox with search support, (= combobox that shows a popup with some Buttons, Search TextBox, List.. etc the selected item feed to the default's ComboBox TextBox.) What would you do? Write a custom

  • MVP, design question 2009-12-04

    I working on a MVP designed application and have some design questions. When writing code in the presenter-layer how should the communication go between different presenters/views? Lets say I have a WindowPresenter with its WindowView and I want to s

  • SQLite design question 2009-12-26

    Similar to a feed reader, I'm storing a bunch of articles, each pertaining to a source (feed) and each feed can belong to a category. What I'm trying to do is: Retrieve the articles of the feeds that belong to a certain category. Group the articles.

  • Design Question: Which is Better practice? (part 2) 2010-01-12

    I've got a web interface from which I will gather user data (username,pass,email,etc..) and the backend has to provision these data into 3 other systems (SystemA, SystemB, SystemC). The provisioning is being done by 3 different APIs one for each syst

  • Spring MVC, Design Question 2010-01-30

    I am starting out with web development under Java EE and spring and have a high level design question: I have a basic shell set up: I have coded some domain objects (mainly getters and setters for various object attributes which I ultimately want dis

  • WCF Design questions 2010-02-07

    I am designing a WCF service. I am using netTCP binding. The Service could be called from multi-threaded clients. The multi-threaded clients are not sharing the proxy. 1. WCF Service design question. Client has to sent these 2 values in every call: U

  • Design Question - OO food application 2010-02-17

    Say I have a number of usercontrols, each usercontrol inside a tabitem, inside a window. For example, let say this is a food collection application. Then we have tabs Fruit, Vegetables and Snacks. Each tab will show a list of food of that subject, an

  • Java Object Oriented Design Question: update internal state or return new object 2010-02-23

    This is a design question. The design is pseudo-code and represents a small example but I may add a lot more methods, data, logic in the future. In this example, I am considering two approaches. In the execute method below, should I return an immutab

  • Grid related UI design question 2010-04-26

    Grid related UI design question I want some 16-grid (4 rows and 4 columns) user interface, and fill the grid with some round shapes. I also want to use the MouseOver, mouse left button down, and Mouse Left Button Up events to set the state of grids a

  • Java Design Questions - Class, Function, Access Modifiers 2010-05-04

    I am newbie to Java. I have some design questions. Say I have a crawler application, that does the following: 1. Crawls a url and gets its content 2. Parses the contents 3. Displays the contents How do you decide between implementing a function or a

  • Appropriate programming design questions 2010-05-29

    I have a few questions on good programming design. I'm going to first describe the project I'm building so you are better equipped to help me out. I am coding a Remote Assistance Tool similar to TeamViewer, Microsoft Remote Desktop, CrossLoop. It wil

  • Big table or multiple separate tables? (database design question) 2010-05-30

    This is a database design question. I want to build an invoice web application, an invoice can have many items, and each user can have an inventory list of product items that they can store and choose to add to an invoice item. My questions are: 1. S

  • Threadpool design question 2010-06-14

    I have a design question. I want some feedback to know if a ThreadPool is appropriate for the client program I am writing. I am having a client running as a service processing database records. Each of these records contains connection information to

  • Objective-C Design Question. Proper use of Observers? Events? LF code strategy advice 2010-07-22

    Okay this is a design question. I, like many, are still learning Objective-C and Cocoa, and am a little rusty to boot. Anyway, here is the question: Assume I have a ViewController class 'A'. Assume I have a "Camera" class 'B', which is a singleton. A

Copyright (C), All Rights Reserved.

processed in 0.089 (s). 11 q(s)