【问题标题】:Adapter Pattern: Class Adapter vs Object Adapter适配器模式:类适配器与对象适配器
【发布时间】:2011-07-24 22:22:13
【问题描述】:

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

什么时候你会在对象适配器上使用类适配器,反之亦然?还有,使用类适配器和对象适配器的取舍是什么?

【问题讨论】:

    标签: oop design-patterns adapter software-design


    【解决方案1】:

    除了what renatoargh has mentioned in his answer,我想补充一个类适配器的优点

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

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

    【讨论】:

      【解决方案2】:

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

      Object AdapterClass Adapter(因此Inheritance)相比最大的好处是客户和适配者的loose coupling

      【讨论】:

        【解决方案3】:

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

        对象适配器依赖于对象组合:

        图片来源:Design Pattern (Elements of Reusable Object-Oriented Software) 一书

        【讨论】:

          【解决方案4】:
          • 类适配器在我们想要适配一个类及其子类时,通过提交特定的适配器类将 Adaptee 适配到 Target 将不起作用。
          • 对象适配器让单个适配器与多个 Adaptee(Adaptee 和所有 Adaptee 层次结构)一起工作

          【讨论】:

            【解决方案5】:

            我可以看到对象适配器的一个优势,具体取决于您的编程语言:如果后者不支持多重继承(例如 Java),并且您想一次性适配多个适配器,您将必须使用对象适配器。

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

            【讨论】:

              【解决方案6】:

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

              首先说我们有一个用户;

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

              现在,假设出于任何原因,您需要为用户类提供一个适配器,那么我们有两种方法,通过继承或通过组合;

              //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 相同的操作!!! )... 接口的使用都是关于 uncopling 的,这就是我 99% 可能会使用它们的主要原因,当然,如果选择取决于我的话。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-09-28
                • 1970-01-01
                • 2011-01-05
                • 1970-01-01
                • 1970-01-01
                • 2012-01-16
                • 1970-01-01
                • 2018-05-23
                相关资源
                最近更新 更多