January 11, 2011 Design Patterns
January 11, 2011 Design Patterns
For some reason I have thought about good example for Adapter design pattern for a long period of time. There might be straightforward example with two classes, one of which has OperationA and other has OpA and we need to adapt them, but there is no analogy in that example. In this case it would not worse reading this post. Also I thought about example in which we have complex objects with many properties and methods, where you would need to perform some real conversion. But by the way of thinking there was always electricity adapter in my head circling. In Lviv there is still many apartments where old thin sockets exist, to overcome this people buy small adapters, almost as on the picture on the right, except not that cruel.
So we have our notebook charger that easily fits wide European socket. In your apartment all sockets are new, so you get used to it. Your NewElectricitySystem has method MatchWideSocket. But in your friend’s apartment there is still old one and his OldElectricitySystem has only method MatchThinSocket. Unfortunately you cannot drill sockets in someone else’s flat, you have to buy Adapter, that allows you consume the same electricity, but with old system.
ADAPTER
Adapter – is design pattern that allows us use object, which we cannot change, by providing its functionality thought known interface.
// Adaptee class OldElectricitySystem { public string MatchThinSocket() { return "220V"; } } // known interface in our code interface INewElectricitySystem { string MatchWideSocket(); } class NewElectricitySystem : INewElectricitySystem { public string MatchWideSocket() { return "220V"; } } // Adapter class Adapter : INewElectricitySystem { private readonly OldElectricitySystem _adaptee; public Adapter(OldElectricitySystem adaptee) { _adaptee = adaptee; } // All the magic lives here // in our adapter we translate from // what we (code) cannot use straightway into what we can public string MatchWideSocket() { return _adaptee.MatchThinSocket(); } } class ElectricityConsumer { // Charging device can be used only with new system public static void ChargeNotebook(INewElectricitySystem electricitySystem) { Console.WriteLine(electricitySystem.MatchWideSocket()); } } public class AdapterDemo { public static void Run() { // We can easily operate with our new system var newElectricitySystem = new NewElectricitySystem(); ElectricityConsumer.ChargeNotebook(newElectricitySystem); // We have to adapt to old system using adapter var oldElectricitySystem = new OldElectricitySystem(); var adapter = new Adapter(oldElectricitySystem); ElectricityConsumer.ChargeNotebook(adapter); } }
Yet another name for this pattern is Wrapper. That is because it wraps functionality of some object, representing it in another interface.
Actually we can also implement it slightly differently than I have it here. In the example above we use composition, but our adapter can easily implement two interfaces of the old and new system and then once created by one of the constructors we would use our adapter in both directions.
code
more code
~~~~