设计模式之观察者模式

一情景

   今天来聊聊我对观察者模式的理解。完全是个人理解,本篇文章也只是简单的说一下。

   在商场里面有普通员工A和B和C,还有经理D,A和B是普通售货员,C是保安人员,每次经理D外出,A和B就经常偷懒,但是经理回来他们需要第一时间知道这个信息,于是他们跟C搞好关系,只要D一回来就打电话通知A和B。A和B就立马好好工作,我们把A叫做观察者,C叫做通知者

首先是A代码实现:A有姓名和经理的状态两个属性,经理的状态要么是回来,要么就是出去,还有一个行为就是工作,A类如下:

public      class  A  {

public String  name;// 

        public C  c//

public String state;//经理的状态


public A(String name,C c){

this.name=name;

this.c=c

}

public void work(){

      this.state=c.state//保安获得的经理状态同步给A

System.out.println("工作");
}

}

C也有姓名和经理的状态,当然还有通知A的行为,经理回来就立刻通知告诉A:

public      class  C  {
public A a;//观察者
public String  name;//
public String state;//得到经理的状态
public C(A a){
this.a=a;
}

public void notice(){

System.out.println("经理D回来了,赶紧工作");
a.work();
}

}

但是发现一个问题,如果这么写的话,只能通知A一个人,不能通知员工B了,或许还要通知另外的员工E该帮经理泡茶。如果要通知其他人岂不是要把A类改一下?依据封闭原则这样不好!只能想其他的办法。

二解耦一

     既然C要通知两个,那么就在C类里面定义需要被通知的的同事的列表,被通知的同事叫做观察者,通知别人的保安叫做通知者,还要有一个往列表添加这些观察者的方法,如果这个观察者跟C闹毛了,C就不在通知他了,就要有把他移除的方法。这样解决通知观察者的问题,但是还有一个问题,既然是观察者列表肯定是既能放A也能放B也能放E或者观察者,依据依赖倒转原则,我们可以让这些被通知者都依赖于抽象。

C类如下:

public      class  C  {
public List<Observe> ob= new LinkedList<Observe>(); //通知列表
public String  name;//
public String state;//经理的状态


public void add(Observe o){//添加需要通知的员工
 synchronized (o) {
ob.add(o);
}

}
public void notice(){//通知所有列表的员工

for(int i=0;i>=0 ;i=ob.size()-1){
Observe o2=ob.remove(0);
o2.work();//通知,该泡茶的泡茶,改上班的上班
}

}

}

该上班的A如下

public      class  A  extends Observe{

public String  name;//
public String state;//经理的状态
public C c;
public A(String name ,C c){
this.name=name;
this.c=c;
}
public void work(){
this.state=c.state;//保安c获得的经理回来的状态,同步给A
System.out.println("员工"+name+"得到的经理的状态--"+state);
System.out.println("工作");
}

}

B就省略了,写一下员工E的代码

public      class  E  extends Observe{

public String  name;//
public String state;//经理的状态
public C c;
public E(String name ,C c){
this.name=name;
this.c=c;
}

public void work(){

         this.state=c.state;//保安c获得的经理回来的状态,同步给e

System.out.println("员工"+name+"得到的经理的状态--"+state);
System.out.println("泡茶");
}

}

这样做是不是让ABE都依赖与抽象Observe了,这样就就解决通知很多观察者的问题,但是这里面C是一个具体的类,但是具体的实现可能是C可能是D,为什么?

三解耦二

     这里大家有没有发现虽然观察者ABE实现了都被通知的情况,通知他的人都是保安C,但是假设有一天员工B跟保安C闹了矛盾,那么C就把E从列表移除了,经理回来了C就不会通知E,如果E上班睡觉就被经理抓住了,这个时候e被抓住了换一种说话就是E是被经理D通知的,经理D也成了通知者,这个时候有了两个通知者C和D,我们又只能把这两个共同的部分抽象出来让具体的通知者去实现抽象类,这个时候定义一个抽象的父类Subject,让具体的C或D去

Subject


public abstract     class  Subject  {
public List<Observe> ob= new LinkedList<Observe>(); //通知列表
//增加
public void add(Observe o){//来跟包含打招呼我就把这个员工放进去要通知的列表
 synchronized (o) {
ob.add(o);
}
}
//减少
 public void remove(Observe o){
 ob.remove(o);
 
 }  
public void notice(){//通知所有的打过招呼的人

for(int i=0;i>=0 ;i=ob.size()-1){
Observe o2=ob.remove(0);
o2.work();//通知,该泡茶的泡茶,改上班的上班
}

}
}

具体的通知者C

public      class  C extends  Subject {
public String  name;
public String state;//得到的经理的状态

}

观察者A

public      class  A  extends Observe{

public String  name;//
public String state;//工作状态
public C c;//由于这里是被C通知的 ,所以这里直接定义C
public A(String name ,C c){
this.name=name;
this.c=c;
}
public void work(){
this.state=c.state;//告诉我经理回来了,我得到的经理状态和c通知的状态一样
System.out.println("员工"+name+"得到的经理的状态--"+state);
System.out.println("工作");
}

}


客户端代码:

   
C c=new C();//创建一个具体的通知者
A a=new A("小王",c);//创建具体的观察者
c.add(a);//通知B
 
E e=new E("小李",c);
c.add(e);//通知B
 
c.state="经理回来了!!!";//保安C得到经理回来的状态
c.notice();//进行通知

B和E就略了,如果通知者变成经理D,我们只需要创建一个经理D实现通知类Subject。

这里用到的Observe就是对观察者抽象的类

代码的结构图如下:


观察者模式完美的体现了依赖置换原则的最佳体现,观察者让所有的工作其实就是解耦,让耦合的双方都依赖与抽象。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值