The Class Adapter
In the class adapter approach, we derive a new class from ListBox (or the grid or tree control) and add the desired methods to it. In this class adapter example, we create a new class called MyList, which is derived from the ListBox class and that implements the following interface.
public interface ListAdapter { void Add(Swimmer sw) ; void Clear() ; void clearSelection() ; }
The derived MyList class is as follows.
public class MyList : System.Windows.Forms.ListBox, ListAdapter { private System.ComponentModel.Container components = null; //----- public MyList() { InitializeComponent(); } //----- public void Add(string s) { this.Items.Add (s); } //----- public void Add(Swimmer sw) { this.Items.Add (sw.getName() + "\t" + sw.getAge ().ToString () ); } //----- public void Clear() { this.Items.Clear (); } //----- public void clearSelection() { this.SelectedIndex = -1; }
The class diagram is shown in Figure 14-4. The remaining code is much the same as in the object adapter version.
Figure 14-4 The class adapter approach to the list adapter
There are also some differences between the class and the object adapter approaches, although they are less significant than in C++.
The class adapter won't work when we want to adapt a class and all of its subclasses, since you define the class it derives from when you create it.
The class adapter lets the adapter change some of the adapted class's methods but still allows the others to be used unchanged.
The object adapter could allow subclasses to be adapted by simply passing them in as part of a constructor.
The object adapter requires that you specifically bring any of the adapted object's methods to the surface that you wish to make available.
Two-Way Adapters
The two-way adapter is a clever concept that allows an object to be viewed by different classes as being either of type ListBox or type DataGrid. This is most easily done with a class adapter, since all of the methods of the base class are automatically available to the derived class. However, this can only work if you do not override any of the base class's methods with any that behave differently.
Object versus Class Adapters in C#
The C# List, Tree, and Grid adapters illustrated previously are all object adapters. That is, they are all classes that contain the visual component we are adapting. However, it is equally easy to write a List or Tree Class adapter that is derived from the base class and contains the new add method.
In the case of the DataGrid, this is probably not a good idea because we would have to create instances of DataTables and Columns inside the DataGrid class, which makes one large complex class with too much knowledge of how other classes work.
Pluggable Adapters
A pluggable adapter is one that adapts dynamically to one of several classes. Of course, the adapter can only adapt to classes it can recognize, and usually the adapter decides which class it is adapting based on differing constructors or setParameter methods.