观察者模式

来源:互联网 发布:知乎增加关注话题 编辑:程序博客网 时间:2024/05/23 14:24

      观察者模式:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。观察者一般用于当一个对象改变时候同时需要改变其他对象,但它不知道具体改变多少个对象;

       下面就以一个例子作为此模式的简单入门:比如两个男生,一个叫李一峰,一个叫赵又挺,两位都在追求一个美女叫咪咪,两位男生都分别请求咖啡店的店员小梨子,若咪咪来到,就通知他;这个流程功能就可以简单的使用观察者模式,代码如下:

首先定义一个BOY类,类里定义一个去追咪咪的方法;

public class Boy {//男生的名字private String name;//店员private Client client;public Boy(String name,Client client){this.name =name;this.client =client;}public void update(){System.out.println("店员小梨子通知:"+client.getAction()+";"+this.name+"男屌丝开始去追了!");}}
再次定义一个店员类当做观察者

//店员类public class Client {//委托对象List<Boy> boys =new ArrayList<Boy>();private String action;public String getAction() {return action;}public void setAction(String action) {this.action = action;}//增加委托对象public void addBoy(Boy boy){boys.add(boy);}//通知男同学public void notifyBoy(){for(Boy boy:boys){boy.update();}}}
客户端代码如下:

public static void main(String[] args) {//一个叫做小梨子的店员Client xiaolizi =new Client();//追美女的两位同事Boy boy1 = new Boy("李一峰",xiaolizi);Boy boy2 = new Boy("赵一挺",xiaolizi);    //小梨子记下两位男士xiaolizi.addBoy(boy1);xiaolizi.addBoy(boy2);xiaolizi.setAction("美女咪咪来店了!");xiaolizi.notifyBoy();}
运行结果显示


以上就完成一个简单的观察者模式,但上面的方法中有个问题,就是男生对象和店员对象耦合一起,不利于后续功能的扩展;那下面对上面代码就行改造;

首先定义一个抽象的观察者类;

public abstract class BoyObserve {    //观察者名称@SuppressWarnings("unused")private String name;//通知者@SuppressWarnings("unused")private ClientObserve client;public BoyObserve(String name, ClientObserve client) {this.name = name;this.client = client;}    //观察者状态更改public abstract void update();   }
实现两个具体的观察者

public class BoyB extends BoyObserve{    ClientObserve client;public BoyB(String name, ClientObserve client) {super(name, client);this.client = client;}@Overridepublic void update() {System.out.println("接收到店员"+client.getName()+"的通知,"+this.getName()+"开始送花");}}

public class BoyA extends BoyObserve {    private ClientObserve client;public BoyA(String name, ClientObserve client) {super(name, client);this.client = client;}public void update() {System.out.println("接到店员"+client.getName()+"的通知,"+this.getName()+"开始追赶");}}

定义一个通知者接口:

public interface ClientY {public void addBoy(BoyObserve boy);public void notifyBoy();}
实现一个通知者:

public  class ClientObserve implements ClientY{//通知者名称private String name;//观察者private List<BoyObserve> boys =new ArrayList<BoyObserve>(); //消息private String actionMessage;ClientObserve(String name){this.name =name;}//添加观察者public void addBoy(BoyObserve boy){boys.add(boy);}//通知观察者public void notifyBoy(){for(BoyObserve boy:boys){boy.update();}}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getActionMessage() {return actionMessage;}public void setActionMessage(String actionMessage) {this.actionMessage = actionMessage;}}
客户端代码如下:

public static void main(String[] args) {//一个叫做小梨子的店员ClientObserve client =new ClientObserve("小玲子");BoyA li = new BoyA("李一峰", client);BoyB zh = new BoyB("赵又挺",client);client.addBoy(li);client.addBoy(zh);client.setActionMessage("咪咪来店了");client.notifyBoy();}
以上改造对观察者进行了抽象,对通知者也进行了抽象,其中类之间的关系图如下:







0 0
原创粉丝点击