Touching the void: The sequel

The code for this part of the lecture can be found here.

Consider the following class diagram representing a list of contacts:

  
 
                        +---------+
                        | IPhList |
		        +---------+
                        +---------+
                             |
                            / \
                            ---
                             |
                -----------------------------
                |                           |
         +------------+             +----------------+
         | MtPhList   |             | ConsPhList     |
         +------------+             +----------------+
         +------------+          +--| PhEntry first  |
                                 |  | IPhList  rest  |
                                 |  +----------------+
                                 |
                                 V
                        +----------------+
                        | PhEntry        |
                        +----------------+
                        | String  name   |
                        | int     num    |
                        +----------------+
                        
                        

We want to design a method that removes from this IPhList the first PhEntry with the given name.

We cannot remove an item from an empty list and so in the class MtPhList the method will just alert the user that an illegal operation has been attempted:

    //remove the first phone entry with the given name from this list
    IPhList remove(String name){ 
     throw new IllegalOperationException("item to remove it's not in the list"); 
    } 
    

In class ConsPhList we can try the following:

    //remove the first phone entry with the given name from this list
    IPhList remove(String name){ 
     if (name.equals(this.first.name))
         return this.rest;
     else
       return new ConsIPhList(this.first,this.rest.rmove(name));
  } 
   

But this way we create a new whole new list. If my database referred to this list of numbers, I would have to notify the database that we now have a whole new list. And, of course, I do not know what other parts of the database use my phone list --- and they all would need to know. We need to find a way to change the numbers the list contains in such a way that whoever refers to the list always refers to the same object - only the contents of the object that represents the list of phone numbers keeps changing.

In order to do that we introduce a wrapper class that contains a reference to the current state of the list:

     
    +----------------+
    | PhList         |
    +----------------+
    | IPhList phlist |
    +----------------+

   
//wrapper class for IPhList
class PhList{
  IPhList phlist;

  PhList(IPhList phlist){
    this.phlist=phlist;
}
   

Now we can rewrite the remove method.

In class PhList we add the following piece of code:

  //effect:mutate this list so that the first phone entry with 
  //the given name is removed
  void remove(String name){ 
    this.phlist=this.phlist.remove(name); 
  } 
    

We can also design now a method that adds a given PhEntry to this Phlist.

In class PhList we add the following piece of code:

  //effect:mutate this list so that a given entry is added
  void add(PhEntry phone){ 
    this.phlist=
      new ConsPhList(phone, this.phlist); 
  }
    

Of course, we should run tests. For now we only observe the effects. We will see soon how to design the tests correctly.