Saturday 19 July 2014

Adapter Pattern vs Visitor Pattern

Adapter pattern converts the interface of a class into another interface client expects. It helps two incompatible classes to work together. Adapter is useful when dealing with the legacy code especially for that code that was written a while ago and to which one might not have access and need adapting some functionality. Also, it is useful for off-the-shelf code, for toolkits, for libraries or any third party software’s.
Visitor pattern is a way of separating algorithm from the object structure upon which it operates. This helps to add new operations to existing object structure without modifying those structures.
Similarities:
  • Visitor pattern allows us to change the class structure without changing the actual class. An adapter pattern also accomplishes its task without changing the actual class.
  • Adapter and visitor pattern can be used to add functionalities to existing classes.
  • Adapter pattern and visitor pattern promotes flexibility by providing a level of indirection to another object.
  • Adapter pattern create reusable classes that cooperates with unrelated classes with incompatible interfaces. Visitor pattern also creates reusable classes with different object structure.
  • Adding or modifying operation is comparatively easy in both of these patterns.
Dissimilarities:
  • The main purpose of Adapter pattern is to make two incompatible objects work together. But, in visitor pattern the purpose is the separation of concerns.
  • Adapter pattern provides solution for composing or constructing large, complex structures that exhibit desired properties. On the other hand, Visitor pattern is most specifically concerned with communication between objects.
  • In adapter pattern, adapter doesn’t need to bother about the functionalities of the class it is adapting. But, in visitor pattern the visitor has to consider the internal functionalities of the class it is visiting.
  • Adapter pattern works in such a way that it doesn’t break the encapsulation property of OOP. In Visitor pattern, encapsulation of the composite classes is broken when the visitor is used, where the designer is forced to provide public operation that accesses the elements internal states.
  • Single class hierarchy is used in adapter pattern to adapt one interface to another whereas in visitor pattern two class hierarchies are used, one for the element being operated on and one for visitors that defined the operations on elements.
Example of adapter pattern:
Adapter pattern can be applied to an application where it needs to connect to a book provider web service to get a list of book names based on the search query term. Consider the BookServiceGateway class is the API that we need to work with. This is the Adaptee class. It has a method that returns the list of books as a generic list (in the format that is not compatible to our requirements) based on the search query term. The IBookGateway is an interface that represents the Target component and the BookGatewayAdapter class is the implementation of the Adapter. BookGatewayAdapter is the class that the client will be interacting with. It does the heavy work of resolving the incompatibility issue and acts as a bridge between the Adaptee and the client.BookGatewayAdapter will iterate through the list of books and will return the list of book names to the client.

Figure 1. Applying Adapter pattern in adapting web services APIs.
In the above example it is not possible to apply visitor pattern, because in visitor pattern it is required to know the detail codes of object structure. It is required to add call back function in the web service APIs. But in this case it is not possible to modify the web service API as because it is a 3rd party service or it can also be a DLL which is completely hidden and cannot be modified any way. So based on this it is correct to apply adapter pattern here. Also, the encapsulation is maintained accurately and two incompatible classes can work together to server the desired purpose of the client.
Visitor Pattern Example:
Let’s consider creating a reporting module in an application to make statistics about a group of customers. The statistics should be made very detailed so all the data related to the customer must be parsed. All the entities involved in this hierarchy must accept a visitor. Let’s consider CustomerGroup, Customer, Order and Item are the visitable classes. IVisitor and IVisitable are the respective interfaces for visitor and visitable. A CustomerGroup represents a group of customers, each Customer can have one or more orders and each order can have one or more Items. GeneralReport is a visitor class and implements the IVisitor interface. Other Visitors (other reports or other types of visitors) can be added by implementing the IVisitor interface

Figure. 2: Visitor pattern in customer report generation.
Here visitor pattern is applied accurately. The report generation is done by the visitor is dependent on the statistics object structure thereby adapter cannot be used in this situation. Here it is very easy to extend with new operations by adding a concrete visitor class. However, Adapter pattern is used to make two incompatible classes to work together. Also, adapter pattern doesn’t break the encapsulation, but in this case usage of  CustomerGroup composite breaks the encapsulation to accomplish the purpose of seperation of concerns and for better flexibility. Here visitor pattern is used to add capabilities to a composite of objects if required. Also, The polymorhic dispatching takes care of all of the decision making which is not the case in Adapetr pattern.

No comments:

Post a Comment