I have a few questions about the Adapter pattern. I understand that the class adapter inherits from the adaptee while the object adapter has the adaptee as an object rather than inheriting from it.
When would you use a class adapter over an object adapter and vice versa? Also, what are the trade-offs of using the class adapter and the trade-offs of the object adapter?
I can see one advantage for the object adapter, depending on your programming language: if the latter does not support multiple inheritance (such as Java, for instance), and you want to adapt several adaptees in one shot, you'll be obliged to use an object adapter.
Another point for object adapter is that you can have the wrapped adaptee live his life as wanted (instantiation notably, as long as you instantiate your adapter AFTER your adaptee), without having to specify all parameters (the part for your adapter AND the part for your adaptee because of the inheritance) when you instantiate your adapter. This approach appears more flexible to me.
Prefer to use composition, over inheritance
First say we have a user;
public interface IUser
{
public String Name { get; }
public String Surname { get; }
}
public class User : IUser
{
public User(String name, String surname)
{
this.Name = name;
this.Surname = surname;
}
public String Name { get; private set; }
public String Surname { get; private set; }
}
Now, imagine that for any reason, youre required to have an adapter for the user class, we have then two aproaches, by inheritance, or by composite;
//Inheritance
public class UserAdapter1 : User
{
public String CompleteName { get { return base.Name + " " + base.Surname } }
}
//Composition
public class UserAdapter2
{
private IUser user;
public UserAdapter2(IUser user)
{
this.user = user;
}
public String CompleteName { get { return this.user.Name + " " + this.user.Surname; } }
}
You are totally ok, but just if the system don't grow... Imagine youre required to implement a SuperUser class, in order to deal with a new requirement;
public class SuperUser : IUser
{
public SuperUser(String name, String surname)
{
this.Name = name;
this.Surname = surname;
}
public String Name { get; private set; }
public String Surname { get; private set; }
public Int32 SupernessLevel { get { return this.Name.Length * 100; } }
}
By using inheritance you would not be able to re-use your adapter class, messing up your code (as your would have to implement another adapter, inheriting from SuperUser that would do ECXATLY the same thing of the other class!!!)... Interface usage is all about uncopling, thats the main reason that I'm 99% likely to use them, of course, if the choice is up to me.
Class Adapter
is plain old Inheritance, available in every object-oriented language, while Object Adapter
is a classic form of an Adapter Design Pattern.
The biggest benefit of Object Adapter
compared to Class Adapter
( and thus Inheritance
) is loose coupling of client and adaptee.
A class adapter uses multiple inheritance to adapt one interface to another: (depending on your programming language: Java & C# does not support multiple inheritance)
An object adapter depends on object composition:
Images Source: Design Pattern (Elements of Reusable Object-Oriented Software) book
In addition to what renatoargh has mentioned in his answer I would like to add an advantage of class adapter.
In class adapter you can easily override the behavior of the adaptee if you need to because you are just subclassing it. And it is harder in Object adapter.
However advantages of object adapter usually outweighs this tiny advantage of class adapter.