设计模式之美: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 }
复制代码









目录
相关文章
|
7天前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性本文旨在探讨PHP中常见的设计模式及其应用,帮助开发者编写出更加灵活、可维护和易于扩展的代码。通过深入浅出的解释和实例演示,我们将了解如何使用设计模式解决实际开发中的问题,并提升代码质量。
在软件开发过程中,设计模式是一套经过验证的解决方案模板,用于处理常见的软件设计问题。PHP作为流行的服务器端脚本语言,也有其特定的设计模式应用。本文将重点介绍几种PHP中常用的设计模式,包括单例模式、工厂模式和策略模式,并通过实际代码示例展示它们的具体用法。同时,我们还将讨论如何在实际项目中合理选择和应用这些设计模式,以提升代码的可维护性和扩展性。
|
4月前
|
设计模式
**工厂模式与抽象工厂模式**都是创建型设计模式,用于封装对象创建,减少耦合
【6月更文挑战第23天】**工厂模式与抽象工厂模式**都是创建型设计模式,用于封装对象创建,减少耦合。工厂模式专注于单个对象,通过具体工厂创建具体产品,适用于简单对象创建;抽象工厂则关注一系列相关产品,提供创建一族对象的接口,适用于处理多个不兼容产品族。选择模式基于问题域的复杂性,单个产品需求时用工厂模式,多产品族时用抽象工厂模式。
29 5
|
7天前
ES6中map对象的使用,确实比Object好使哈
ES6中Map对象的使用优势,包括任意类型作为键、直接获取大小、增删查改操作等。Map的键可以是函数、对象、NaN等,支持forEach循环和for...of循环。
18 1
ES6中map对象的使用,确实比Object好使哈
|
2月前
|
数据安全/隐私保护
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
该博客文章通过示例演示了如何使用session对象的`setAttribute`和`getAttribute`方法在不同页面间传递和显示用户的用户名和密码信息,并说明了如何设置会话的有效期。
作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户
|
5天前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
2月前
|
SQL 存储 数据库
|
2月前
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
|
2月前
|
设计模式 存储 安全
18 Java反射reflect(类加载+获取类对象+通用操作+设计模式+枚举+注解)
18 Java反射reflect(类加载+获取类对象+通用操作+设计模式+枚举+注解)
72 0
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(二)详细讲解!
|
2月前
|
JavaScript
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(一)详细讲解!
网易:所有的对象最终都会继承自 Object.prototype ? ——原型链(一)详细讲解!