[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. Ubuntu进不入系统,一直停留在ubuntu图标画面(转)

    Ubuntu进不入系统,一直停留在ubuntu图标画面(转) 在VMware中对Ubuntu进行“关闭电源”后,再次进入,一直停留在ubuntu的图标画面,无法进入系统了!网上也有别的网友碰到这个问题 ...

  2. 【Xamarin报错】visual studio android 模拟器部署卡住

    模拟器启动成功,但是部署一直等待中,没有反应. 1>Starting deploy 5" KitKat (4.4) XXHDPI Phone ...1>Starting emul ...

  3. 使用UIKit制作卡牌游戏(三)ios游戏篇

    译者: Lao Jiang | 原文作者: Matthijs Hollemans写于2012/07/13 转自朋友Tommy 的翻译,自己只翻译了这第三篇教程. 原文地址: http://www.ra ...

  4. AC_Dream 1224 Robbers(贪心)

    题意:n个抢劫犯分别抢到的金钱是k1, k2, k3,...,一共得到的金钱是m, 但是在分钱的时候是按照x1/y, x2/y, x3/y,....的比例进行分配的!这样的话 一些抢劫犯就会觉得不公平 ...

  5. 【转载】关于 Ubuntu 的小知识分享

    转载自:http://os.51cto.com/art/201307/402197.htm 一.默认开机直接进入到Ubuntu命令行界面 安装Ubuntu后,开机会默认进入到图形界面,如果不喜欢图形界 ...

  6. WhatFontIs - 字体百科全书,没有不认识的字体

    我敢肯定,我不是唯一一个曾经特别想知道图片上使用的某个字体,然后特别无奈的到字体网站大海捞针似的的找类似的字体.如今,一个强大的软件字体识别——WhatFontIs,让我们的生活更轻松. 您可能感兴趣 ...

  7. HTML5 新特性总结

    1.使用autocomplete 自动完成必须给input 加上name. 2.SVG图形代码 复制https://developer.mozilla.org/zh-CN/docs/Web/SVG/E ...

  8. [python]decimal常用操作和需要注意的地方

    decimal模块 简介 decimal意思为十进制,这个模块提供了十进制浮点运算支持. 常用方法 1.可以传递给Decimal整型或者字符串参数,但不能是浮点数据,因为浮点数据本身就不准确. 2.要 ...

  9. UIScrollView子控件的布局

    scorllView内部子控件添加约束的注意点: 1.子控件的尺寸不能通过UIScrollView来计算 *比如可以设置固定值 (width==100 height ==100) *比如可以相对于UI ...

  10. 一次领域驱动设计(DDD)的实际应用

    笔者先前参与了一个有关汽车信息的网站开发,用于显示不同品牌的汽车的信息,包括车型,发动机型号,车身尺寸和汽车报价等信息.在建模时,我们只需要创建名为Car的实体(Entity)对象.其他的信息,比如车 ...