Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 适配器模式:类适配器与对象适配器_Oop_Design Patterns_Adapter_Software Design - Fatal编程技术网

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

Oop 适配器模式:类适配器与对象适配器,oop,design-patterns,adapter,software-design,Oop,Design Patterns,Adapter,Software Design,我对适配器模式有几个问题。我知道类适配器从适配器继承,而对象适配器将适配器作为对象,而不是从它继承 什么时候在对象适配器上使用类适配器,反之亦然?另外,使用类适配器和对象适配器的权衡是什么?类适配器非常古老,在每种面向对象的语言中都可以使用,而对象适配器是一种经典的类适配器形式 与类适配器(因此继承)相比,对象适配器的最大好处是客户端和适配器。我可以看到对象适配器的一个优点,这取决于您的编程语言:如果后者不支持多重继承(例如Java),则,如果您想在一次操作中适应多个适配器,则必须使用对象适配器

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


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

类适配器
非常古老,在每种面向对象的语言中都可以使用,而
对象适配器
是一种经典的类适配器形式


类适配器
(因此
继承
)相比,
对象适配器
的最大好处是客户端和适配器。

我可以看到对象适配器的一个优点,这取决于您的编程语言:如果后者不支持多重继承(例如Java),则,如果您想在一次操作中适应多个适配器,则必须使用对象适配器


对象适配器的另一个要点是,在实例化适配器时,您可以让包装好的适配器过自己想要的生活(特别是实例化,只要在适配器之后实例化适配器),而不必指定所有参数(适配器的部分和适配器的部分,因为继承)。这种方法在我看来更灵活。

更喜欢使用组合,而不是继承

首先说我们有一个用户

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; }
}
现在,假设出于任何原因,需要为用户类提供一个适配器,然后我们有两个aproach,通过继承或复合

//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; } }
}
你完全可以,但是如果系统不增长。。。假设您需要实现一个超级用户类,以便处理新的需求

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; } }
}
通过使用继承,您将无法重复使用您的适配器类,从而弄乱了您的代码(因为您必须实现另一个适配器,从超级用户继承,而超级用户将执行与另一个类完全相同的操作!!!)。。。接口的使用都是关于不耦合的,这是我99%可能使用它们的主要原因,当然,如果选择由我决定的话。

  • 类适配器通过提交到特定适配器类来将Adaptee适配到目标当我们想要适配一个类及其子类时,它将不起作用
  • 对象适配器允许单个适配器与多个适配器一起工作(适配器和所有适配器层次结构)

类适配器使用多重继承将一个接口调整到另一个接口:(取决于您的编程语言:Java&C不支持多重继承)

对象适配器取决于对象组成:

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

除此之外,我想添加类适配器的一个优点

在类适配器中,如果需要,您可以轻松地覆盖适配器的行为,因为您只是对它进行子类化。而且在对象适配器中更难

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