版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112
目录
导航
设计模式之六大设计原则
设计模式(一)单例模式
设计模式(二)工厂模式
设计模式(三)策略模式
设计模式(四)适配器模式
设计模式(五)享元模式
设计模式(六)建造者模式
设计模式(七)原型模式
设计模式(八)桥接模式
设计模式(九)外观模式
设计模式(十)组合模式
设计模式(十一)装饰器模式
设计模式(十二)代理模式
设计模式(十三)迭代器模式
设计模式(十四)观察者模式
设计模式(十五)中介者模式
设计模式(十六)命令模式
设计模式(十七)状态模式
设计模式(十八)访问者模式
设计模式(十九)责任链模式
设计模式(二十)解释器模式
设计模式(二十一)备忘录模式
设计模式(二十二)模板模式
设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)
前言
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
其实用通俗的话讲就是订阅,发布这样的流程。
例子
我们经常会去银行办理业务,然后当人多的时候,我们就需要拿号来等待银行叫号。当银行叫到你的时候,才轮到你办理业务。万恶的某行,居然有Vip插队业务,太恶心了,这个例子中,不包含这恶心的插队逻辑。
所以LZ需要建4个类,其中2个是观察者接口,和被观察者接口,另外2个是实现类,一个银行呼叫中心和取了号的客户。
UML类图
/***
*
*@Author ChenjunWang
*@Description:被观察者接口
*@Date: Created in 16:11 2018/4/11
*@Modified By:
*
*/
public interface Subject {
//注册观察者
void registerObserver(Observer observer);
//移除观察者
void removeObserver(Observer observer);
//提醒观察者
void notifyObserver(String msg);
}
/***
*
*@Author ChenjunWang
*@Description: 观察者接口
*@Date: Created in 16:10 2018/4/11
*@Modified By:
*
*/
public interface Observer {
void update(String msg);
}
/***
*
*@Author ChenjunWang
*@Description: 银行叫号中心
*@Date: Created in 17:06 2018/4/11
*@Modified By:
*
*/
public class BankCallCenter implements Subject {
List<Observer> list = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notifyObserver(String msg) {
for (Observer item : list)
item.update(msg);
}
}
/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 17:09 2018/4/11
*@Modified By:
*
*/
public class Client implements Observer {
String callNo;
public Client(String callNo) {
this.callNo = callNo;
}
@Override
public void update(String msg) {
if (msg.equals(this.callNo)){
System.out.println("我是" + callNo + "号客户,现在到我了!");
} else {
System.out.println("我是" + callNo + "号客户,现在还没到我了!");
}
}
}
/***
*
*@Author ChenjunWang
*@Description:测试类
*@Date: Created in 17:12 2018/4/11
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
BankCallCenter bankCallCenter = new BankCallCenter();
Client client = new Client("1");
bankCallCenter.registerObserver(client);
Client client2 = new Client("2");
bankCallCenter.registerObserver(client2);
Client client3 = new Client("3");
bankCallCenter.registerObserver(client3);
System.out.println("----------中心叫一号去办理业务------------");
bankCallCenter.notifyObserver("1");
System.out.println("----------从观察者列表中移除一号------------");
bankCallCenter.removeObserver(client);
System.out.println("-----------中心叫二号去办理业务-------------");
bankCallCenter.notifyObserver("2");
System.out.println("------------从观察者列表中移除二号-----------");
}
}
运行结果如下
--------------------------------------
/***
*
*@Author ChenjunWang
*@Description:测试类
*@Date: Created in 17:12 2018/4/11
*@Modified By:
*
*/
public class Test {
public static void main(String[] args) {
BankCallCenter bankCallCenter = new BankCallCenter();
Client client = new Client("1");
bankCallCenter.registerObserver(client);
Client client2 = new Client("2");
bankCallCenter.registerObserver(client2);
Client client3 = new Client("3");
bankCallCenter.registerObserver(client3);
System.out.println("----------中心叫一号去办理业务------------");
bankCallCenter.notifyObserver("1");
System.out.println("----------从观察者列表中移除一号------------");
bankCallCenter.removeObserver(client);
System.out.println("-----------中心叫二号去办理业务-------------");
bankCallCenter.notifyObserver("2");
System.out.println("------------从观察者列表中移除二号-----------");
}
}
被观察者利用notifyObserver群发消息,LZ在update方法中对接受到的消息进行了处理,若收到有用的消息则进行操作。
观察者模式适合一个软件系统要求在某一个对象状态发生变化的时候,某些其他的对象作出相应的改变。观察者模式减少对象之间的耦合有利于系统的复用。
总结
优点
(1)Subject和Observer之间是松耦合的,分别可以各自独立改变。
(2)Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
(3)符合开闭原则
缺点
(1)如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。
(2)使得代码关系变得复杂。
Git地址
本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/observer
有什么不懂或者不对的地方,欢迎留言。
喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!