• 设计模式之美:Extension Object(扩展对象)


    索引

    意图

    预期对象的接口将在未来被扩展。通过额外的接口来定义扩展对象。

    Anticipate that an object’s interface needs to be extended in the future.

    Additional interfaces are defined by extension objects..

    结构

    参与者

    Subject

    • 定义抽象主体对象。其定义用于查询是否包含特定扩展的接口。

    Extension

    • 所有扩展类的抽象基类。可以定义负责管理扩展自身的操作。
    • Extension 知道其是谁的扩展。

    ConcreteSubject

    • 具体的主体类。实现基类定义的 GetExtension 方法并返回相应的扩展对象。

    AbstractExtension

    • 特定种类的扩展类的抽象基类。

    ConcreteExtension

    • 继承并实现 AbstractionExtension 类。实现特定的扩展功能。

    适用性

    当以下情况成立时可以使用 Extension Object 模式:

    • 当需要为已有对象额外添加全新的或无法预见的接口时。
    • 抽象的主要接口在不同的客户类中拥有不同的角色时。
    • 无法通过子类型化来扩展接口行为时。

    效果

    • 扩展对象促进了增加新扩展功能。
    • 类的主要抽象接口不会过于膨胀。
    • 接口的主要抽象在不同的子系统中可实现不同的角色。
    • 客户类变得更加复杂。
    • 需要控制对扩展对象的滥用。

    相关模式

    • Visitor 模式可以为层级的类结构增加新的行为。Visitor 模式与 Extension Object 模式拥有类似的益处。相比 Visitor 模式,Extension Object 模式不需要一个稳固的类层级结构,并且也不引入循环依赖。
    • Decorator 模式是另一个可以扩展类的行为的模式。客户类在使用 Decorator 对象时的透明性比使用 Extension Object 更好。在使用窄接口或需要增强已知接口时更适合使用 Decorator 模式。
    • Adapter 模式支持适配一个已知接口。Extension Object 模式支持附加的接口。当对象需要对扩展接口进行适配时可以同时使用 Extension Object 模式和 Adapter 模式。

    实现

    实现方式(一):使用示例结构实现 Extension Object。

     1 namespace ExtensionObjectPattern.Implementation1
     2 {
     3   public abstract class Subject
     4   {
     5     public abstract void Operation1();
     6     public abstract Extension GetExtension(string extensionType);
     7   }
     8 
     9   public abstract class Extension
    10   {
    11     protected Subject _owner;
    12 
    13     public Extension(Subject owner)
    14     {
    15       _owner = owner;
    16     }
    17 
    18     public abstract void DoSomething();
    19   }
    20 
    21   public abstract class AbstractExtension : Extension
    22   {
    23     public AbstractExtension(Subject owner)
    24       : base(owner)
    25     {
    26     }
    27   }
    28 
    29   public class ConcreteExtension : AbstractExtension
    30   {
    31     public ConcreteExtension(Subject owner)
    32       : base(owner)
    33     {
    34     }
    35 
    36     public override void DoSomething()
    37     {
    38       // do something
    39       _owner.Operation1();
    40     }
    41   }
    42 
    43   public class ConcreteSubject : Subject
    44   {
    45     private ConcreteExtension _extension;
    46 
    47     public ConcreteSubject()
    48     {
    49       _extension = new ConcreteExtension(this);
    50     }
    51 
    52     public override void Operation1()
    53     {
    54       // do something
    55     }
    56 
    57     public override Extension GetExtension(string extensionType)
    58     {
    59       if (extensionType == "some type")
    60       {
    61         return this._extension;
    62       }
    63 
    64       return null;
    65     }
    66   }
    67 
    68   public class Client
    69   {
    70     public void TestCase1()
    71     {
    72       Subject subject = new ConcreteSubject();
    73       Extension extension = subject.GetExtension("some type");
    74       extension.DoSomething();
    75     }
    76   }
    77 }

    实现方式(二):使用泛型实现 IExtensibleObject<T> 接口。

     1 namespace ExtensionObjectPattern.Implementation2
     2 {
     3   public abstract class Subject : IExtensibleObject<Subject>
     4   {
     5     public abstract void Operation1();
     6     public abstract IEnumerable<IExtension<Subject>> Extensions { get; }
     7   }
     8 
     9   public interface IExtensibleObject<T>
    10     where T : class, IExtensibleObject<T>
    11   {
    12     IEnumerable<IExtension<T>> Extensions { get; }
    13   }
    14 
    15   public interface IExtension<T>
    16     where T : class, IExtensibleObject<T>
    17   {
    18     void Attach(T owner);
    19     void Detach(T owner);
    20   }
    21 
    22   public abstract class Extension : IExtension<Subject>
    23   {
    24     protected List<Subject> _owners;
    25 
    26     public void Attach(Subject owner)
    27     {
    28       _owners.Add(owner);
    29     }
    30 
    31     public void Detach(Subject owner)
    32     {
    33       _owners.Remove(owner);
    34     }
    35 
    36     public abstract void DoSomething();
    37   }
    38 
    39   public class ConcreteExtension : Extension
    40   {
    41     public override void DoSomething()
    42     {
    43       // do something
    44       foreach (var item in _owners)
    45       {
    46         item.Operation1();
    47       }
    48     }
    49   }
    50 
    51   public class ConcreteSubject : Subject
    52   {
    53     private List<Extension> _extensions = new List<Extension>();
    54 
    55     public ConcreteSubject()
    56     {
    57       Extension extension = new ConcreteExtension();
    58       extension.Attach(this);
    59 
    60       _extensions.Add(extension);
    61     }
    62 
    63     public override void Operation1()
    64     {
    65       // do something
    66     }
    67 
    68     public override IEnumerable<IExtension<Subject>> Extensions
    69     {
    70       get
    71       {
    72         return _extensions;
    73       }
    74     }
    75   }
    76 
    77   public class Client
    78   {
    79     public void TestCase1()
    80     {
    81       Subject subject = new ConcreteSubject();
    82 
    83       foreach (var extension in subject.Extensions)
    84       {
    85         (extension as Extension).DoSomething();
    86       }
    87     }
    88   }
    89 }

    设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

  • 相关阅读:
    vue+webpack搭建项目基础架构
    vue入门学习篇——父子组件通信
    vue入门学习篇——数据双向绑定原理及简单实现
    vue入门学习篇——挂载点、实例、模版之间的关系
    毫秒转成天、小时、分钟、秒
    可执行jar包的MANIFEST.MF
    fsck系统修复
    HDFS, YARN, HBase, Hive, ZooKeeper端口说明
    解压 tar zxvf 文件名.tar.gz 压缩 tar zcvf 文件名.tar.gz 目标名
    Linux学习笔记之RedHat Enterprise Linux 6.4 使用 Centos 6 的yum源问题
  • 原文地址:https://www.cnblogs.com/gaochundong/p/design_pattern_extension_object.html
Copyright © 2020-2023  润新知