Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pluggable Adapter as mentioned in the GOF

The related Posts on Stackover flow for this topic : Post_1 and Post_2

Above posts are good but still I could not get answer to my confusion, hence I am putting it as a new post here.
MY Questions based on the GOF's Elements of Reusable Object-Oriented Software book content about Pluggable Adapters (mentioned after questions below), hence I would appreciate if the discussions/answers/comments are more focused on the existing examples from GOF regarding the pluggable Adapters rather than other examples

Q1) What do we mean by built-in interface adaptation ?
Q2) How is Pluggable Interface special as compared to usual Adapters ? Usual Adapters also adapt one interface to another.
Q3) Even in the both the use cases, we see both the methods of the Extracted "Narrow Interface" GetChildren(Node) and CreateGraphicNode(Node)depending on Node. Node is an internal to Toolkit. Is Node same as GraphicNode and is the parameter passed in CreateGraphicNode only for populating the states like (name, parentID, etc) of an already created Node object ?

As per the GOF (I have marked few words/sentences as bold to emphasis the content related to my Questions)

ObjectWorks\Smalltalk [Par90] uses the term pluggable adapter to describe classes with built-in interface adaptation.

Consider a TreeDisplay widget that can display tree structures graphically. If this were a special-purpose widget for use in just one application, then we might require the objects that it displays to have a specific interface; that is, all must descend from a Tree abstract class. But if we wanted to make TreeDisplay more reusable (say we wanted to make it part of a toolkit of useful widgets), then that requirement would be unreasonable. Applications will define their own classes for tree structures. They shouldn't be forced to use our Tree abstract class. Different tree structures will have different interfaces.

Pluggable adapters. Let's look at three ways to implement pluggable adapters for the TreeDisplay widget described earlier, which can lay out and display a hierarchical structure automatically. The first step, which is common to all three of the implementations discussed here, is to find a "narrow" interface for Adaptee, that is, the smallest subset of operations that lets us do the adaptation. A narrow interface consisting of only a couple of operations is easier to adapt than an interface with dozens of operations. For TreeDisplay, the adaptee is any hierarchical structure. A minimalist interface might include two operations, one that defines how to present a node in the hierarchical structure graphically, and another that retrieves the node's children.

Then there are two use cases

  1. "Narrow Interface" being made as abstract and part of the TreeDisplay Class enter image description here

  2. Narrow Interface extracted out as a separate interface and having a composition of it in the TreeDisplay class enter image description here

(There is a 3rd approach of Parameterized adapter also but skipping it for simplicity, Also this 3rd one is I guess more specific to Small talk)

like image 445
nits.kk Avatar asked Dec 14 '22 08:12

nits.kk


1 Answers

When we talk about the Adapter design pattern, we typically consider two preexisting APIs that we would like to integrate, but which don't match up because they were implemented at different times with different domains. An Adapter may need to do a lot of mapping from one API to the other, because neither API was designed with this sort of extensibility in mind.

But what if the Target API had been designed with future adaptations in mind? A Target API can simplify the job of future Adapters by minimizing assumptions and providing the narrowest possible interface for Adapters to implement. Note this design requires a priori planning. Unlike typical use cases for the Adapter pattern, you cannot insert a Pluggable Adapter between any two APIs. The Target API must have been designed to support pluggable adaptations.

Q1) This is what the GoF means by built-in interface adaptation: an interface is built into the Target API in order to support future adaptations.

Q2) As mentioned, this is a relatively unusual scenario for an Adapter, since the typical strength of the pattern is its ability to handle APIs that have no common design.

The GoF lists three different approaches to design a Target API for adaptation. The first two are recognizable as a couple of their Behavioral design patterns.

  1. Template Method
  2. Strategy
  3. Closures (what Smalltalk calls code blocks)

Q3) Without getting caught up in details of the GoF's GUI examples, the basic idea behind designing what they call a "narrow interface" is to remove as much domain specificity as possible. In Java, the starting point for a domain-agnostic API would almost certainly be the functional interfaces.

A Target API with dependencies on these interfaces should be much simpler to adapt than an API built around domain-specific methods. The former allows for creation of Pluggable Adapters, while the latter would require a more typical Adapter with heavy mapping between APIs.

like image 158
jaco0646 Avatar answered Dec 28 '22 03:12

jaco0646