6
ACCESSOR METHODS

DESCRIPTION

The Accessor Methods pattern is one of the most commonly used patterns in the area of object-oriented programming. In fact, this pattern has been used in most of the examples discussed in this book for different patterns. In general, the values of different instance variables of an object, at a given point of time, constitute its state. The state of an object can be grouped into two categories — public and private. The public state of an object is available to different client objects to access, whereas the private state of an object is meant to be used internally by the object itself and not to be accessed by other objects.

Consider the class representation of a customer in Figure 6.1.

The instance variable ID is maintained separately and used internally by each Customer class instance and is not to be known by other objects. This makes the variable ID the private state of a Customer object to be used internally by the Customer object. On the other hand, variables such as name, SSN (Social Security Number) and the address make up the public state of the Customer object and are supposed to be used by client objects. In case of such an object, the Accessor Method pattern recommends:

  • All instance variables being declared as private and provide public methods known as accessor methods to access the public state of an object. This prevents external client objects from accessing object instance variables directly. In addition, accessor methods hide from the client whether a property is stored as a direct attribute or as a derived one.

Customer
ID:int
name:String
SSN:String
address:String

Figure 6.1 Customer Class


  • Client objects can make use of accessor methods to move a Customer object from one state (source) to another state (target). In general, if the object cannot reach the target state, it should notify the caller object that the transition could not be completed. This can be accomplished by having the accessor method throw an exception.
  • An object can access its private variables directly. But doing so could greatly affect the maintainability of an application, which the object is part of. When there is a change in the way a particular instance variable is to be defined, it requires changes to be made in every place of the application code where the instance variable is referenced directly. Similar to its client objects, if an object is designed to access its instance variables through accessor methods, any change to the definition of an instance variable requires a change only to its accessor methods.

ACCESSOR METHOD NOMENCLATURE

There is no specific requirement for an accessor method to be named following a certain naming convention. But most commonly the following naming rules are followed:


• To access a non-Boolean instance variable:

  • Define a getXXXX method to read the values of an instance variable XXXX. E.g., define a getFirstName() method to read the value of an instance variable named firstName.
  • Define a setXXXX(new value) method to alter the value of an instance variable XXXX. E.g., define a setFirstName(String) method to alter the value of an instance variable named firstName.


• To access a Boolean instance variable:

  • Define an isXXXX() method to check if the value of an instance variable XXXX is true or false. E.g., define an isActive() method on a Customer object to check if the customer represented by the Customer object is active.
  • Define a setXXXX(new value) method to alter the value of a Boolean instance variable XXXX. E.g., define a setActive(boolean) method on a Customer object to mark the customer as active.

The following Customer class example explains the usage of accessor methods.


EXAMPLE

Suppose that you are designing a Customer class as part of a large application. A generic representation of a customer in its simplest form can be designed as in Figure 6.2.

Applying the Accessor Method pattern, the set of accessor methods listed in Table 6.1 can be defined corresponding to each of the instance variables (Listing 6.1).

Figure 6.3 shows the resulting class structure.

i_Image1

Figure 6.2 Customer Representation


Table 6.1 List of Accessor Methods


Different client objects can access the object state variables using the accessor methods listed in Table 6.1. The Customer object itself can access its state variables directly, but using the accessor methods will greatly improve the maintainability of the Customer class code. This in turn contributes to the overall application maintainability.


DIRECT REFERENCE VERSUS ACCESSOR METHODS

Let us suppose that we need to add the following two new methods to the Customer class.

1. isValidCustomer — To check if the customer data is valid.

2. save — To save the customer data to a data file.

As can be seen from the Customer class implementation in Listing 6.2, the newly added methods access different instance variables directly. Different client objects can use the Customer class in this form without any difficulty. But when there is a change in the definition of any of the instance variables, it requires a change to the implementation of all the methods that access these instance variables directly. For example, if the address variable need to be changed from its current definition as a string to a StringBuffer or something different, then all methods that refer to the address variable directly needs to be altered.


Listing 6.1 Customer Class with Accessor Methods

public class Customer { 
   private String firstName; 
   private String lastName; 
   private String address; 
   private boolean active; 
   public String getFirstName() { 
     return firstName; 
   } 
   public String getLastName() { 
     return lastName; 
  } 
  public String getAddress() { 
    return address; 
  } 
  public boolean isActive() { 
    return active; 
  } 
  public void setFirstName(String newValue) { 
    firstName = newValue; 
  } 
  public void setLastName(String newValue) { 
    lastName = newValue; 
  } 
  public void setAddress(String newValue) { 
    address = newValue; 
  } 
  public void isActive(boolean newValue) { 
    active = newValue; 
  } 
}

As an alternative approach, Customer object methods can be redesigned to access the object state through its accessor methods (Listing 6.3).

Customer
firstName:String
lastName:String
active:boolean
address:String
________________________
getFirstName():String
getLastName():String
getAddress():String
isActive():boolean
setFirstName(newValue:String)
setLastName(newValue:String)
setAddress(newValue:String)
setActive(newValue:boolean)

Figure 6.3 Customer Class with Accessor Methods


In this approach, any change to the definition of any of the instance variables requires a change only to the implementation of the corresponding accessor methods. No changes are required for any other part of the class implementation and the class becomes more maintainable.


PRACTICE QUESTIONS

1. Design an Order class with accessor methods for its instance variables.

2. Identify the effect of using accessor methods when a class is subclassed.


Listing 6.2 Customer Class Directly Accessing Its Instance Variables

   public class Customer { 
             … 
             … 
   public String getFirstName() { 
    return firstName; 
   } 
             … 
             … 
   public boolean isValidCustomer() { 
      if ((firstName.length() > 0) && (lastName.length() > 0) &&
         (address.length() > 0)) 
      return true; 
     return false; 
   } 
  public void save() { 
    String data = 
      firstName + ”," + lastName + ”," + address + 
     ”," + active; 
    FileUtil futil = new FileUtil(); 
    futil.writeToFile("customer.txt”,data, true, true); 
  } 
 }

Listing 6.3 Customer Class Using Accessor Methods to Access Its Instance Variables

   public class Customer { 
              … 
              … 
   public String getFirstName() { 
     return firstName; 
   } 
              … 
              … 
   public boolean isValidCustomer() { 
     if ((getFirstName().length() > 0) &&
         (getLastName().length() > 0) &&
         (getAddress().length() > 0)) 
      return true; 
     return false; 
   } 
   public void save() { 
     String data = 
       getFirstName() + ”," + getLastName() + ”," + 
       getAddress() + ”," + isActive(); 
     FileUtil futil = new FileUtil(); 
     futil.writeToFile("customer.txt”,data, true, true); 
   } 
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.123.155