Design Patterns Series 9 - Adapter Pattern
In this post and coming posts, you will get inside scoop on patterns and OOP. Patterns have great deal to say about OOP and about how to improve your object-oriented experience.
Sometimes objects doesn't fit together as they should, a class may have changed, or an object turns out to be too difficult to work with. We will introduce you a rescue by converting two design pattern,Adapter Pattern and Facade Pattern.
The Adapter Pattern:
It lets you adapt what an object or class has to offer so that another object or class can make use of it. It lets you adapt what an object or class exposes to what another object or class expects.
Adapter pattern lets you fix the interface between objects and classes without to modify the objects or classes directly.
It lets you convert the interface of a class into another interface the clients expects. Adapter pattern lets classes work togthter that couldn't otherwise because of incompatible interfaces.
Although the official definition of the adapter pattern talks about classes, this pattern actually has two variations:one for objects and another for classes, we will discover both at this post.
This design pattern is particularly good when you are working with legacy code that can not be changed, while the software that interacts with that code does change.
Suppose you get hotel availability from kayak and it represent hotel address as street,City,state, and country in a separated properties and in your code you deal with hotel address as one property. Of course you can not change the kayak response so you have two choices, change your class or using adapter pattern We chose the second one.
The following code is the hotel class from kayak
Using object composition to wrap the adapted object is good object-oriented design. And note that if you subclass the adapted object, the adapter wrapper will be able to handle the sub-classed objects with minimal changes
Inheriting class adapters :
While object adapters use composition to store the object they are adapting, class adapters are designed to use multiple inheritance to merge the adapted class and the class your are adapting to it. But C# doesn't support multiple inheritance so the adapter class will inherit from the class that we want to wrap.
So Object adapters relay on object composition, while class adapters rely on inheritance. Object adapters can be more flexible because they can work with not just the objects they have been designed to adapt but also sub-classed objects of the adapted objects. But with class adapters, you have to modify the class adapter to do the same thing. To be more flexible, in general, don't forget the design principle that says you should favor composition over inheritance..
One final note on adapters -- beside adapting the behaviour of a class or object, adapters can also improve that behaviour by adding their own methods.
Drawbacks of adapters :
Mostly that there's an additional layer of code added, and so to maintain. But if rewriting legacy code is not an option, adapters provide a good option.
you can download the full source code here
Sometimes objects doesn't fit together as they should, a class may have changed, or an object turns out to be too difficult to work with. We will introduce you a rescue by converting two design pattern,Adapter Pattern and Facade Pattern.
The Adapter Pattern:
It lets you adapt what an object or class has to offer so that another object or class can make use of it. It lets you adapt what an object or class exposes to what another object or class expects.
Adapter pattern lets you fix the interface between objects and classes without to modify the objects or classes directly.
It lets you convert the interface of a class into another interface the clients expects. Adapter pattern lets classes work togthter that couldn't otherwise because of incompatible interfaces.
Although the official definition of the adapter pattern talks about classes, this pattern actually has two variations:one for objects and another for classes, we will discover both at this post.
This design pattern is particularly good when you are working with legacy code that can not be changed, while the software that interacts with that code does change.
Suppose you get hotel availability from kayak and it represent hotel address as street,City,state, and country in a separated properties and in your code you deal with hotel address as one property. Of course you can not change the kayak response so you have two choices, change your class or using adapter pattern We chose the second one.
The following code is the hotel class from kayak
public class KayakHotel
{
public String City { get; set; }
public String Street { get; set; }
public String State { get; set; }
public String Country { get; set; }
}
To implement the adapter pattern we should create an interface that your hotel class will implement, it contains one method that will return hotel address
public interface IHotel
{
String Address();
}
your hotel class be as follows
public class Hotel : IHotel
{
private String _Address;
public String Address ()
{
return _Address;
}
}
Now we will implement our adapter pattern. Object adapters work by composition, the adapter stores the object it's adapting inside itself. You can pass that object to the adapter's constructor.
public class HotelAdapter : IHotel
{
private KayakHotel khotel;
public HotelAdapter(KayakHotel _khotel)
{
khotel = _khotel;
}
public String Address()
{
return khotel.Street + "," + khotel.City + "," + khotel.State + "," + khotel.Country;
}
}
Note we passed the kayak hotel object into our adapter constructor to composite it into our hotel object and the Address method concatenates the address properties from kayak and return one string for hotel address. You can test this adapter by the following code fragment.
KayakHotel khotel = new KayakHotel();
khotel.Street = "nile st.";
khotel.City = "Maadi";
khotel.State = "Cairo";
khotel.Country = "Egypt";
HotelAdapter adapter = new HotelAdapter(khotel);
Console.WriteLine("Hotel Address is : {0}", adapter.Address());
This code will print out the hotel address as follows
Hotel Address is : nile st.,Maadi,Cairo,Egypt
Just as expected. An adapter uses composition to store the object it's supposed to adapt, and when the adapter's methods are called, it translate those calls into something the adapted object can understand and passes the calls onto the adapted object. The code that calls the adapter never need to know that it's not dealing with the kind of object it thinks it is, but an adapted object instead.Using object composition to wrap the adapted object is good object-oriented design. And note that if you subclass the adapted object, the adapter wrapper will be able to handle the sub-classed objects with minimal changes
Inheriting class adapters :
While object adapters use composition to store the object they are adapting, class adapters are designed to use multiple inheritance to merge the adapted class and the class your are adapting to it. But C# doesn't support multiple inheritance so the adapter class will inherit from the class that we want to wrap.
So Object adapters relay on object composition, while class adapters rely on inheritance. Object adapters can be more flexible because they can work with not just the objects they have been designed to adapt but also sub-classed objects of the adapted objects. But with class adapters, you have to modify the class adapter to do the same thing. To be more flexible, in general, don't forget the design principle that says you should favor composition over inheritance..
One final note on adapters -- beside adapting the behaviour of a class or object, adapters can also improve that behaviour by adding their own methods.
Drawbacks of adapters :
Mostly that there's an additional layer of code added, and so to maintain. But if rewriting legacy code is not an option, adapters provide a good option.
you can download the full source code here
Comments
Post a Comment