适配器模式:类适配器与对象适配器

时间:2011-03-29 01:41:21

标签: oop design-patterns adapter software-design

我对适配器模式有几个问题。我知道类适配器继承自adaptee,而对象适配器将adaptee作为对象而不是继承自它。

何时在对象适配器上使用类适配器,反之亦然?另外,使用类适配器和对象适配器的权衡有什么权衡?

6 个答案:

答案 0 :(得分:23)

我可以看到对象适配器的一个优点,具体取决于您的编程语言:如果后者不支持多重继承(例如Java),并且您希望一次性调整多个适应器,那么您将会被迫使用对象适配器。

对象适配器的另一个要点是,你可以让被包装的自适应生活在他想要的生活中(特别是实例化,只要你在你的适配器之后实例化你的适配器),而不必指定所有参数(适配器的部件和实例化适配器时,由于继承而适应的部分。这种方法对我来说更灵活。

答案 1 :(得分:13)

喜欢使用合成,而不是继承

首先说我们有一个用户;

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; }
}

现在,想象一下,由于任何原因,您需要为用户类提供适配器,我们有两个aproaches,通过继承或复合;

//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; } }
}

你完全没问题,但是如果系统没有增长......想象一下你需要实现一个SuperUser类,以便处理新的需求;

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; } }
}

通过使用继承,你将无法重新使用你的适配器类,弄乱你的代码(因为你必须实现另一个适配器,从SuperUser继承,它将执行ECXATLY与其他类相同的东西! )...界面使用是关于无法解决的,这是我99%可能使用它们的主要原因,当然,如果选择取决于我。

答案 2 :(得分:11)

Class Adapter是普通的Inheritance,可用于所有面向对象的语言,而Object AdapterAdapter Design Pattern的经典形式。

Object Adapter(以及Class Adapter)相比,Inheritance的最大好处是loose coupling客户和适应者。

答案 3 :(得分:4)

类适配器使用多重继承来使一个接口适应另一个接口:(取决于您的编程语言:Java& C#不支持多重继承) enter image description here

对象适配器取决于对象组成: enter image description here

图像源:设计模式(可重用面向对象软件的元素)一书

答案 4 :(得分:1)

what renatoargh has mentioned in his answer之外,我想添加类适配器的优势

在类适配器中,如果需要,您可以轻松覆盖适配器的行为,因为您只是继承它。对象适配器更难。

然而,对象适配器的优点通常超过了类适配器的这一微小优势。

答案 5 :(得分:0)

    当我们想要调整类及其子类时,
  • 类适配器通过提交到特定的适配器类来适应Adaptee到Target。
  • 对象适配器允许单个适配器与许多Adaptee一起使用(Adaptee和所有适配器层次结构)