观察者模式:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。观察者一般用于当一个对象改变时候同时需要改变其他对象,但它不知道具体改变多少个对象;
下面就以一个例子作为此模式的简单入门:比如两个男生,一个叫李一峰,一个叫赵又挺,两位都在追求一个美女叫咪咪,两位男生都分别请求咖啡店的店员小梨子,若咪咪来到,就通知他;这个流程功能就可以简单的使用观察者模式,代码如下:
首先定义一个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; } @Override public 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(); }
以上改造对观察者进行了抽象,对通知者也进行了抽象,其中类之间的关系图如下:
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/9390.html