设计模式-观察者模式,在各种对象之间划分清晰的界限
来源:互联网 发布:mysql 大于小于转义 编辑:程序博客网 时间:2024/05/29 12:51
一个现实的例子
千橡的开放办公区里坐着很多女孩儿,多到超出了我对计算机、互联网企业中女孩应有数量的想象和认知。而程序员大多是单身的情商较低的脑力劳动者,他们虽然工资理想,但是除了代码和书籍,他们只能一个人过夜。而千橡的办公环境似乎在为程序员们创造机会,我甚至认为这是管理层故意而为之。这样的状况产生了一个有意思的现象,很多程序员同学都在默默地关注着一个或多个自己心仪的女孩儿,如果哪个被关注的女孩儿有什么样的举动,他们会随风而动,要么装作一起出门去吃饭要么在饮水机旁来一次”偶遇“。要是一个不曾是单身的女孩失恋了,我想那些默默关注她的程序员们会有所行动吧。这就是一个典型的观察者模式。
观察者模式
对于观察者模式的定义,网上有很多不同的定义,我在这里引用书中的一段话:
Observer- define a one-to-many dependncy between objects so that when one object changes state, all its dependents are notified and updated automatically.
普遍认同的,面向对象的编程思想是对不同概念(算法,定义,操作)的逻辑抽象与抽离,使用这一思想开发的一个主导原则是,在给定的应用程序中正确地分配任务。 系统中的每个对象应该将重点放在它所在问题域中的离散抽象上,而不是放在任何其它方面。 简而言之,一个对象只应做一件事,而且要将它做好。
而设计的意义就在于确保在对象之间划定清晰的界限,因而可提供更高的重用性和系统可维护性。观察者模式就是这样的普遍存在的设计模式。
最显而易见的案例就是表现层与逻辑层的分离,在几乎所有的(我们甚至可以讲”几乎“去掉)GUI技术中,观察者模式都发挥着作用,比如.net中的“委托/事件机制”,或swing中JButton的实现都是很好的例子。
在技术不断发展的今天,观察者模式演化出了很多与其类似的设计模式,较著名的如.net的事件模式,Qt中Signal/Slot概念等。但是他们所表达的意义却没有变,就是将各种对象之间划分出清晰的界限,同时又保持紧密的关联。
角色
尽管观察者模式有很多变体,但该模式的基本前提包含两个角色:观察者和主体(熟悉 Smalltalk MVC 的人将这些术语分别称为视图和模型)。 在用户界面的环境中,观察者是负责向用户显示数据的对象。 另一方面,主体表示从问题域中模拟的业务抽象。 正如图 1 中所描述的一样, 在观察者和主体之间存在逻辑关联。 当主体对象中发生更改时,(例如,修改实例变量),观察者就会观察 这种更改,并相应地更新其显示。如同上文中提到的现实的例子一样,女孩们是主体,而程序员们则是观察者。
但是观察者模式的现实意义在于,角色的定义并非如此的简单,我们必须要明白观察者或主体并非是简单的一个种类。还以刚才的例子分析,女孩儿们,作为主体,会有不同的种类,比如有的女孩比较内敛,及时是单身也不会将这一现实显现出来。而有的女孩儿则不同,她们也许会估计将一枚戒指戴在小拇指上。而那孩儿们的分类则明了得多,比如有一些男孩儿会马上吐露心扉,有的则选择曲线救国的路线,还有的可能会比较沉得住气,过一段时间才张开攻势。无论怎样, 我们要知道,角色不是单一形式存在的。也许我们应该重新强调一下这两个角色:不同种类的观察者和不同种类的主体。
角色之间的关系
我们现在知道观察者模式在逻辑上规定了观察者观察主体,但这种模式时,这实际上是一个名称误用。 更准确地说,观察者注册主体,表明它对观察的意向。 在某种状态发生变化时,主体向观察者通知这种变化情况。 当观察者不再希望观察主体时,观察者从主体中撤消注册。 这些步骤分别称为观察者注册、通知和撤消注册。还以上文的例子来说,我们假设每个女孩都有一个追求者名单(虽然有些不现实),当一个男孩儿喜欢一个女孩的话, 他在该名女孩的名单中注册,如果他移情别恋的时候他从这个名单中撤销。而女孩呢,只需在单身时发出广播,逐个通知名单上的每个候选者。
所以现在,我们可以确定几个必要的动作,注册,通知和撤销注册。
代码
It's time to make your hands dirty!在Java中,描述一个实体是异常简单的事情,比如一个男孩类或一个女孩类。但是考虑到给种男孩儿在面对不同女孩是表现的方法各不相同,所以要使用接口将showLove的动作抽离出来,同时为了方便女孩通知男孩儿,我们也要加入一个通知方法qualified。另一方面,对于女孩儿,要给与她们作为女性更大的权限,例如所有的对那份列表的操作以及发出通知的权利。
一个爱慕者的接口
public interface Admirer {
public void qualifiedTo(Girl thisGirl);
public void showLove();
}
一个女孩儿的类型
public abstract class Girl {
private Vector<Admirer> admirerList;
private String name;
private int age;
public Girl(String name, int age) {
setAge(age);
setName(name);
}
public void registerAdmirer(Admirer admirer) {
this.admirerList.add(admirer);
}
public void removeAdmirer(Admirer admirer) {
this.admirerList.remove(admirer);
}
public void notifyAdmirer() {
for (Admirer admirer : admirerList)
admirer.qualifiedTo(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setStatus(boolean isSingle, int age) {
this.setAge(age);
this.setSingle(isSingle);
if(isSingle)
notifyAdmirer();
}
}
我们可以看到,当一个女孩儿成为单身状态后,会主动的向全部的潜在爱慕者广播自己单身了的消息,而不同的爱慕者对于此消息的反应则不尽相同。
我在这里设计集中不同类型的爱慕者,他们分别是现实的男孩,情圣,害羞男孩还有专一的男孩。 他们各自对于心中爱慕的人有着不同的反应。现实的男孩关心年龄,大于心里承受年龄的人不予以接受。情圣则是来着不惧,害羞的男孩则会等上一段时间才会表白。而专一的男孩儿则只会对心中的女生采取行动。
public class RealityBoy implements Admirer {
public final int ageExcepted;
public RealityBoy(Girl girl, int ageExcepted) {
this.ageExcepted = ageExcepted;
if (girl.getAge() < ageExcepted) {
girl.registerAdmirer(this);
}
}
@Override
public void qualifiedTo(Girl thisGirl) {
if (thisGirl.getAge() > this.ageExcepted) {
return;
}
showLove();
}
@Override
public void showLove() {
System.out.println("Hi, I am the reality boy, since you are single and I love girls in your age. How about we hang out for a while?");
}
}
public class LoverBoy implements Admirer {
private Girl anyGirl;
private final List<Girl> girls;
public LoverBoy(Girl girl) {
this.anyGirl= girl;
this.girls = new ArrayList<Girl>();
girl.registerAdmirer(this);
}
@Override
public void qualifiedTo(Girl thisGirl) {
this.anyGirl = thisGirl;
showLove();
}
@Override
public void showLove() {
System.out .println("Hello there" +this.anyGirl.getName() + " I am romantic boy , wanna to have a cup of coffee before going to a movie.");
}
public void likeThisGirl(Girl oneGirl) {
this.girls.add(oneGirl);
}
}
public class ShyBoy implements Admirer ,Runnable{
public long dormantPeriod;
private Thread t;
public ShyBoy(Girl girl, long time) {
this.dormantPeriod = time;
girl.registerAdmirer(this);
}
@Override
public void qualifiedTo(Girl thisGirl) {
t = new Thread(this);
t.start();
}
@Override
public void showLove() {
System.out
.println("Hi, I am the shy boy, I wait for "
+ dormantPeriod/ 1000
+ " seconds to get enough guts to tell you that I love you since the moment I known you were single again");
}
@Override
public void run() {
try {
t.sleep(dormantPeriod);
showLove();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class LoyalBoy implements Admirer {
private Girl dreamGirl;
public LoyalBoy(Girl goddress) {
setDreamGirl(goddress);
goddress.registerAdmirer(this);
}
@Override
public void qualifiedTo(Girl thisGirl) {
if (thisGirl == this.dreamGirl) {
showLove();
}
}
@Override
public void showLove() {
System.out.println("Hi, I am the persitent boy, and you are my dream girl for long time. I love you.");
}
public Girl getDreamGirl() {
return dreamGirl;
}
public void setDreamGirl(Girl dreamGirl) {
this.dreamGirl = dreamGirl;
}
}
最后,让我们一起创建一个丘比特
public class Cupid {
public static void main(String[] args) {
Girl pretty = new Girl("pretty", 24, false);
Girl amii = new Girl("amii", 21, false);
Girl vendy = new Girl("vendy", 32, false);
Girl clementina = new Girl("clementina", 25, false);
ShyBoy shy = new ShyBoy(pretty, 10000);
LoverBoy roman = new LoverBoy(pretty);
roman.likeThisGirl(amii);
roman.likeThisGirl(vendy);
roman.likeThisGirl(clementina);
RealityBoy real = new RealityBoy(clementina, 27);
LoyalBoy loyal = new LoyalBoy(amii) ;
System.out.println("{I am Cupid, now Pretty is single}");
pretty.setStatus(true, 25);
System.out.println("{I am Cupid, now Amii is single}");
amii.setStatus(true, 22);
System.out.println("{I am Cupid, now Pretty is single}");
vendy.setStatus(true, 25);
System.out.println("{I am Cupid, now Pretty is single}");
clementina.setStatus(true, 26);
}
}
- 设计模式-观察者模式,在各种对象之间划分清晰的界限
- [设计模式]_[观察者模式在窗口之间消息传递的使用例子]
- 面向对象的设计模式(七),观察者模式
- 浅谈面向对象设计模式:观察者模式
- 模式设计:观察者模式
- 设计模式-----观察者模式
- 设计模式-观察者模式
- 设计模式--观察者模式
- 设计模式:观察者模式
- 设计模式-----观察者模式
- 设计模式:观察者模式
- 设计模式-观察者模式
- 设计模式 观察者模式
- 设计模式-观察者模式
- 设计模式-【观察者模式】
- 设计模式-观察者模式
- 设计模式 -- 观察者模式
- 设计模式-观察者模式
- 一步一步教你在Ubuntu12.04搭建gstreamer开发环境
- 博客开通了
- 微软:经调查88%的用户表示喜欢WP手机
- Ubuntu root
- C/C++:构建你自己的插件框架
- 设计模式-观察者模式,在各种对象之间划分清晰的界限
- Win32中的字符串(位,字符,字节,编码)
- convert 'std::vector<>::iterator {aka __gnu_cxx::__normal_iterator<*, std::vector<> >}' to '*' in in
- Picking the Right NoSQL Database Tool
- ARM Linux内核驱动异常定位方法分析--反汇编方式
- ASP连接MYSQL并读取数据
- ORACLE IS 和 AS 用法
- 使用FileZilla Server建立FTP服务
- linux 内核的链表操作(好文不得不转)