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);
conn.Open();
//...talk
conn.Close();
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);
confCall.Open();
Connection joinCall = new Connection(confCall,p7,p8,conn);
joinCall.Open();
look at the TAPI protocol for more examples