文档章节

设计模式随笔-用奶箱订报纸

Start-up
 Start-up
发布于 2012/05/17 17:33
字数 736
阅读 95
收藏 0

几天前给学生上课,一个学生问我用Delegate与Event实现Observer模式与不用它们实现到底有什么区别?我便讲了一个用奶箱订报纸的故事。

现 在很多人都同时在订报纸和牛奶,送报纸的和送牛奶的也会在楼门口钉上一个箱子,一来方便,二来也为自己做做广告。现在楼门口前钉的大大小小都是箱子,几乎 挤满了所有可用的地方。报箱是那种长长的,而奶箱子则有些四四方方,上面都开了可口,用来投递的。我家原来订了奶,楼门口众多的奶箱中有一个就是我家的, 可后来不打算订了,就留了个空奶箱在那里。最近又有订报纸的打算,可打量了一番门口大大小小的箱子,实在是拥挤不堪,难以放下另外一个报箱了。于是我想让 他们把报纸投到奶箱里算了,还省了不少麻烦。可偏偏碰上一家送报的对我说,我只会把报纸投到报箱中,投到奶箱中的事我不会!也难怪,他们公司没有使用 Delegate!唉。

using  System;
using  System.Collections;

public   interface  IMilkBox
{
  
void PutMilkIn(string s);
}


public   interface  INewsPaperBox
{
  
void PutNewsPaperIn(string s);
}


public   class  Subscriber : INewsPaperBox, IMilkBox  
{
  
public string name;

  
public Subscriber(string name)
  
{
    
this.name = name;
  }


  
public void PutNewsPaperIn(string s)
  
{
    Console.WriteLine(
"{0}在报箱里收到送来的{1}",name, s);
  }


  
public void PutMilkIn(string s)
  
{
    Console.WriteLine(
"{0}在奶箱里收到送来的{1}",name, s); 
  }

}


public   class  NewsPaperSender
{
  
protected ArrayList subscribers = new ArrayList();

  
public void SendNewsPaper()
  
{
    
foreach(INewsPaperBox newsPaperBox in subscribers)
      newsPaperBox.PutNewsPaperIn(
"报纸");
  }


  
public void Subscribe(INewsPaperBox newsPaperBox)
  
{ subscribers.Add(newsPaperBox); }
}


public   class  MilkSender
{
  
protected ArrayList subscribers = new ArrayList();

  
public void SendMilk()
  
{
    
foreach(IMilkBox milkBox in subscribers)
      milkBox.PutMilkIn(
"牛奶");
  }


  
public void Subscribe(IMilkBox milkBox)
  
{ subscribers.Add(milkBox); }
}


public   class  Client
{
  
public static void Main( string[] args )
  
{
    MilkSender ms 
= new MilkSender();
    NewsPaperSender nps 
= new NewsPaperSender();
    
    Subscriber s1 
= new Subscriber("张三");
    Subscriber s2 
= new Subscriber("李四");
    Subscriber s3 
= new Subscriber("王五");

    ms.Subscribe(s1);
    ms.Subscribe(s2);

    nps.Subscribe(s2);
    nps.Subscribe(s3);

    ms.SendMilk();
    Console.WriteLine(
"--------------------");
    nps.SendNewsPaper();
  }

}


后来我碰上了一家送报纸的比较灵活,只要是有口的箱子都可以送,不管是报箱还是奶箱,我的想法终于得到实现了,当然这也要归功于Delegate。

using  System;

public   delegate   void  SendableDelegate( string  s);

public   class  Subscriber
{
  
public string name;

  
public Subscriber(string name)
  
{
    
this.name = name;
  }


  
public void PutNewsPaperIn(string s)
  
{
    Console.WriteLine(
"{0}在报箱里收到送来的{1}",name, s);
  }


  
public void PutMilkIn(string s)
  
{
    Console.WriteLine(
"{0}在奶箱里收到送来的{1}",name, s); 
  }

}


public   class  NewsPaperSender
{
  
public event SendableDelegate SendNewsPaperHandler;

  
public void SendNewsPaper()
  
{
    
if(SendNewsPaperHandler != null)
      SendNewsPaperHandler(
"报纸");
  }


  
public void Subscribe(SendableDelegate sd)
  
{
    SendNewsPaperHandler 
+= sd;
  }

}


public   class  MilkSender
{
  
public event SendableDelegate SendMilkHandler;

  
public void SendMilk()
  
{
    
if(SendMilkHandler != null)
      SendMilkHandler(
"牛奶");
  }


  
public void Subscribe(SendableDelegate sd)
  
{
    SendMilkHandler 
+= sd;
  }

}


public   class  Client
{
  
public static void Main( string[] args )
  
{
    MilkSender ms 
= new MilkSender();
    NewsPaperSender nps 
= new NewsPaperSender();
    
    Subscriber s1 
= new Subscriber("张三");
    Subscriber s2 
= new Subscriber("李四");
    Subscriber s3 
= new Subscriber("哈哈!吕震宇");

    ms.Subscribe(
new SendableDelegate(s1.PutMilkIn));
    ms.Subscribe(
new SendableDelegate(s2.PutMilkIn));

    nps.Subscribe(
new SendableDelegate(s2.PutNewsPaperIn));
    nps.Subscribe(
new SendableDelegate(s3.PutMilkIn));

    ms.SendMilk();
    Console.WriteLine(
"--------------------");
    nps.SendNewsPaper();
  }

}

呵呵,不知道这回有没有搞清楚Delegate的作用?

 

© 著作权归作者所有

Start-up
粉丝 46
博文 292
码字总数 579103
作品 0
海淀
高级程序员
私信 提问
观察者模式和发布订阅模式真的不一样?

背景 设计模式的定义: 在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。 设计模式并不能直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案,它不...

Clearlover
08/28
0
0
从观察者模式到手写EventEmitter源码

观察者模式 观察者模式(observer)广泛的应用于javascript语言中,浏览器事件(如鼠标单击click,键盘事件keyDown)都是该模式的例子。设计这种模式背后的主要原因是促进形成低耦合,在这种...

恍然小悟
2018/09/12
0
0
【非凡程序员】 OC第十五节课 (观察者模式和KVO进行对比)

今天主要学了观察者模式,以及回顾复习了KVO,两者进行对比 什么是观察者模式? 我们先打个比方,这就像你订报纸。比如你想知道美国最近放生了些新闻,你可能会订阅一份美国周刊,然后一旦美...

七月流火zsp
2015/06/05
101
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot2.0 maven打包分离lib,resources

springboot将工程打包成jar包后,会出现获取classpath下的文件出现测试环境正常而生产环境文件找不到的问题,这是因为 1、在调试过程中,文件是真实存在于磁盘的某个目录。此时通过获取文件路...

陈俊凯
今天
6
0
BootStrap

一、BootStrap 简洁、直观、强悍的前端开发框架,让web开发更加迅速、简单 中文镜像网站:http://www.bootcss.com 用于开发响应式布局、移动设备优先的WEB项目 1、使用boot 创建文件夹,在文...

wytao1995
今天
10
0
小知识:讲述Linux命令别名与资源文件的区别

别名 别名是命令的快捷方式。为那些需要经常执行,但需要很长时间输入的长命令创建快捷方式很有用。语法是: alias ppp='ping www.baidu.com' 它们并不总是用来缩短长命令。重要的是,你将它...

老孟的Linux私房菜
今天
8
0
《JAVA核心知识》学习笔记(6. Spring 原理)-5

它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是 Spring 仍然可以和其他的框架无缝整合。 6.1.1. Spring 特点 6.1.1.1. 轻量级 6.1.1.2. 控制反转 6.1.1....

Shingfi
今天
8
0
Excel导入数据库数据+Excel导入网页数据【实时追踪】

1.Excel导入数据库数据:数据选项卡------>导入数据 2.Excel导入网页数据【实时追踪】:

东方墨天
今天
11
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部