[Design Pattern] Substitute Interface

目的

将对象的成员建立为替身接口的成员,用来解耦对象之间的循环相依。

情景

假设开发人员接手一个系统,在系统里有订单对象、送货物件,其中订单对象使用送货物件所提供的送货方法。

当系统继续设计下去,会发现送货方法需要订单对象的相关信息才能决定如何送货。例如说:送货方法需要商品数量,来决定要派卡车送货还是要派机车送货;送货方法需要商品价格来决定要用盒子包还是要用纸袋包。当送货方法的逻辑越来越复杂的时候,最终就会发现送货方法需要订单对象的所有成员才能满足送货方法的运算需求。

送货方法需要订单对象的所有成员,很直觉的设计就是将订单对象作为送货方法的参数,用以提供订单对象的所有成员来满足送货方法的运算需求。系统设计到了这个阶段,就会发现订单对象使用送货物件、而送货物件也使用了订单对象,这也就是产生了对象之间循环相依的问题。(在.NET中,对象之间的循环相依是能够通过编译、并且执行的设计)

为了解决对象之间循环相依的问题,回过头思考订单对象、送货物件之间的关系。会发现在送货物件的送货方法中,其实需要的是订单对象的「所有成员」,而不是真的需要一个订单对象。

这时开发人员可以将订单对象的所有成员,建立为一个「替身接口」并且让订单对象来继承这个接口,用来透过替身接口来提供订单对象的所有成员。接着送货物件中的送货方法,改为使用这个替身接口做为参数,这样就可以取得订单对象的所有成员,而不需要将订单对象作为送货方法的参数。也就是说经由这样的设计,让订单对象、送货物件都改为相依于替身接口,进而就解除了订单对象、送货物件之间循环相依的问题。

结构

参与者

Substitute

  • 提供Primary对象的所有成员。

Primary

  • 实作Substitute界面。
  • 持有Secondary对象的参考。
  • 将本身视为Substitute接口来做为Secondary对象的函式参数,用以提供所有成员。

Secondary

  • 使用Substitute接口做为函式参数,来取得Primary对象的所有成员。

合作方式

实作

  • 类别图

  • IOrder

    public interface IOrder
    {
    // Properties
    int Quantity { get; set; } int Amount { get; set; } // Methods
    void Deliver();
    }
  • Order

    public class Order : IOrder
    {
    // Fields
    private readonly Deliverer _deliverer = new Deliverer(); // Properties
    public int Quantity{get; set;} public int Amount { get; set; } // Methods
    public void Deliver()
    {
    _deliverer.Deliver(this);
    }
    }
  • Deliverer

    public class Deliverer
    {
    // Methods
    public void Deliver(IOrder order)
    {
    // Print
    Console.WriteLine(order.Quantity);
    Console.WriteLine(order.Amount);
    }
    }
  • Program

    class Program
    {
    static void Main(string[] args)
    {
    // Test
    var order = new Order();
    order.Quantity = 12345;
    order.Amount = 67890;
    order.Deliver(); // End
    Console.WriteLine("End...");
    Console.ReadLine();
    }
    }
  • 执行结果

下载

范例程序代码:点此下载

[Design Pattern] Substitute Interface的更多相关文章

  1. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  2. [转]Design Pattern Interview Questions - Part 2

    Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...

  3. [转]Design Pattern Interview Questions - Part 3

    State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...

  4. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  5. 为什么要提倡“Design Pattern呢

    为什么要提倡“Design Pattern呢?根本原因是为了代码复用,增加可维护性. 那么怎么才能实现代码复用呢?面向对象有几个原则:开闭原则(Open Closed Principle,OCP).里 ...

  6. design pattern及其使用

    什么是设计模式? design pattern是一个通用的,可以被重用的关于一个常见的问题的解决方案. 为什么要用设计模式? 引入设计模式的理论基础非常简单.我们每天都会碰到问题.我们可能碰到决定使用 ...

  7. Asp.Net Design Pattern Studynotes -- Part1

    Asp.Net Design Pattern Studynotes -- Part1 let's start with an exampleto entry amazing OO world ! le ...

  8. [Design Pattern] Service Locator Pattern 简单案例

    Service Locator Pattern,即服务定位模式,用于定位不同的服务.考虑到 InitialContext::lookup 的成本比较高,提供了 Cache 类缓存以定位到的服务. 代码 ...

  9. [Design Pattern] Factory Pattern 简单案例

    Factory Pattern , 即工厂模式,用于创建对象的场景,属于创建类的设计模式 . 下面是一个工厂模式案例. Shape 作为接口, Circle, Square, Rectangle 作为 ...

随机推荐

  1. 解决Visual Studio 2010新建工程时出现『1>LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt』错误

    VS2010在经历一些更新后,建立Win32 Console Project时会出"error LNK1123" 错误.   解决方案为: 第一步:将:项目|项目属性|配置属性|清 ...

  2. 使用Flask-Migrate进行管理数据库升级

    我们在升级系统的时候,经常碰到需要更新服务器端数据结构等操作,之前的方式是通过手工编写alter sql脚本处理,经常会发现遗漏,导致程序发布到服务器上后无法正常使用. 现在我们可以使用Flask-M ...

  3. UML2

    UML中有3种构造块:事物.关系和图,事物是对模型中最具有代表性的成分的抽象:关系是把事物结合在一起:图聚集了相关的的事物.具体关系图标如下 说明:构件事物是名词,是模型的静态部分.行为事物是动态部分 ...

  4. 关于fork的一道经典面试题

    这是一道面试题,问程序最终输出几个“-”: #include<stdio.h> #include<sys/types.h> #include<unistd.h> i ...

  5. PowerPoint 打开文档发现.pptx中胡内容有问题

    一.问题的提出 有一个文件,在window 7操作系统中通过邮箱地址保存到本地,结果打开的时候出现[PowerPoint 打开文档发现 文件.pptx中胡内容有问题] 然后提示[如果您信任此演示文稿的 ...

  6. ISO给UIImageView增加点击事件

    自己做了一个九宫格,里面的图标都是由多张图片重叠构成,然后包装成一个button来使用: 遇到的问题是如何给这个“button”增加点击事件? 解决思路1:网友提示在该“button”上增加一个真正的 ...

  7. VS2012未找到与约束ContractName...匹配的导出

    用VS2012创建ARCGIS插件项目时,提示“未找到与约束ContractName...匹配的导出”,此前一直都是正常的额 经查,发现是近期系统相关更新导致,解决办法有两种途径: 一是删除近期更新的 ...

  8. smartjs - DataManager API

    dataServices 数据服务的管理器:首先看下具体的代码 //数据服务 dataServices = st.factory({ name: "dataServices", p ...

  9. php中关于js保存文件至本地的问题

    最近在搞一个livezilla的在线客服聊天的东东,客户界面要求添加一个下载聊天记录的功能.于是我就是翻看了下网上的各种关于”js保存文件至本地“的资料,发现只能在IE下通过execCommand实现 ...

  10. [Python] Interpreter setting in Pycharm

    From: http://blog.csdn.net/u013088062/article/details/50135135 From: http://blog.csdn.net/u013088062 ...