java 设计模式之观察者模式①⑥
二十岁之后就不应该与人争论,人对自己的观念都非常固执,不要企图能说服别人。
设计模式学习,近期我会把23中设计模式都写成博客,敬请期待~
—2021/1/21
定义
观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
项目需求分析
假设我现在想喝牛奶,或者红牛,我就得去商店购买
在这里,商店就是’被观察者’,购买的商品就是’观察者’
在商店中你可以选择购买,也可以选择不够买,最终确定之后输出选择的商品,
无论最后选择多少商品,都是在同一家超市’结账’(输出).
在代码中也是一样的,你可以订阅多个观察者,但是观察者只能有一个.
在这个例子中表示你可以选各种商品,但必须在这家商店中结账.
代码来源于生活
角色分析
UML类图分析(1.1):
- Subject: 抽象主题(被观察者) :抽象主题提供一个接口,可以增加和删除观察者对象。
- SubjectImpl: 抽象主题实现(被观察者实现) :将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
- Observer:抽象观察者 :为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
- MilkObserverImpl / RedBullObserver :抽象观察者实现 : 实现抽象观察者角色所要求的更新接口
代码实现
Subject被观察者 这里指商店(用来添加 / 移除 / 输出 商品):
public interface Subject {
/**
* 移除观察者
*/
public void removeObserver(Observer observer);
/**
* 注册观察者
*/
public void registerObserver(Observer observer);
/**
* 刷新观察者
*/
public void notfiyObservers();
}
Observer观察者(具体商品规范):
public interface Observer {
public void update();
}
MilkObserverImpl 牛奶商品实现:
public class MilkObserverImpl implements Observer{
String food;
public MilkObserverImpl(String food) {
this.food = food;
}
@Override
public void update() {
Log.i("观察者模式","饮料为: "+food);
}
}
RedBullObserverImpl 红牛商品实现:
public class RedBullObserverImpl implements Observer{
String food;
public RedBullObserverImpl(String food) {
this.food = food;
}
@Override
public void update() {
Log.i("观察者模式","饮料为: "+food);
}
}
SubjectImpl 添加 / 移除 / 输出最终商品:
public class SubjectImpl implements Subject{
List<Observer> list = new ArrayList<>();
@Override
public void removeObserver(Observer observer) {
//判断是否有当前状态
if (list.contains(observer)) {
list.remove(observer);
}
}
@Override
public void registerObserver(Observer observer) {
list.add(observer);
}
@Override
public void notfiyObservers() {
for (int i = 0; i < list.size(); i++) {
list.get(i).update();
}
}
}
测试代码(客户端):
//观察者
SubjectImpl subject = new SubjectImpl();
//被观察者
MilkObserverImpl milkObserver = new MilkObserverImpl("牛奶");
RedBullObserverImpl redBullObserver = new RedBullObserverImpl("红牛");
//注册牛奶观察者
subject.registerObserver(milkObserver);
//注册红牛观察者
subject.registerObserver(redBullObserver);
//刷新 (输出结果)
subject.notfiyObservers();
Log图(2.1):
移除商品代码:
//观察者
SubjectImpl subject = new SubjectImpl();
//被观察者
MilkObserverImpl milkObserver = new MilkObserverImpl("牛奶");
RedBullObserverImpl redBullObserver = new RedBullObserverImpl("红牛");
//注册牛奶观察者
subject.registerObserver(milkObserver);
//注册红牛观察者
subject.registerObserver(redBullObserver);
//刷新 (输出结果)
subject.notfiyObservers();
Log.i("观察者模式"," ======= 移除商品,重新输出 ============");
//移除红牛观察者
subject.removeObserver(redBullObserver);
//刷新 (输出结果)
subject.notfiyObservers();
Log图(2.2):
如何扩展商品
CocaColaObserverImpl 新扩展可口可乐商品:
public class CocaColaObserverImpl implements Observer{
String food;
public CocaColaObserverImpl(String food) {
this.food = food;
}
@Override
public void update() {
Log.i("观察者模式","饮料为: "+food);
}
}
测试代码:
....
CocaColaObserverImpl colaObserver = new CocaColaObserverImpl("可口可乐");
.....
Log.i("观察者模式"," ======= 新商品,重新输出 ============");
subject.registerObserver(colaObserver);
subject.notfiyObservers();
Log图(2.3):
原创不易,您的点赞就是对我最大的支持~