设计模式是软件设计中常见问题的典型解决方案。它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。
设计模式与方法或库的使用方式不同,你很难直接在自己的程序中套用某个设计模式。模式并不是一段特定的代码,而是解决特定问题的一般性概念。你可以根据模式来实现符合自己程序实际所需的解决方案。
模式像是蓝图,你可以看到最终的结果和模式的功能,但需要自己确定实现步骤。
在了解什么是观察者模式之前,首先要明白接口和抽象类之间的区别,设计模式当中大量使用了它们来抽象现实中的事物,我认为计算机编程就是一个抽象化的过程。
问题:人属于一种抽象的集合,那就可以把人给变成抽象类,至于具体到哪一个人就extend抽象类。人都有公共的动作,比如吃饭、睡觉等,但是不同的人有不一样的能力,比如小明会制作工艺品,小红会绘画。那这些特定的方法写在抽象类就不合适了,因为一旦extend了抽象类,所有人就都具备了这些特定的能力,显然是不合适的。因此,需要单独把这些特定的方法给抽取到interface中。小明会制作工艺品就implements即可。
public abstract class Human {
private String name;
private int age;
public abstract void eat();
public abstract void sleep();
}
public interface Draw {
void paint();
}
public interface Make {
void makeFlower();
}
public class XiaoHong extends Human implements Make {
@Override
public void eat() {
System.out.println("eat");
}
@Override
public void sleep() {
System.out.println("sleep");
}
@Override
public void makeFlower() {
System.out.println("make flower");
}
}
public class XiaoMing extends Human implements Draw{
@Override
public void eat() {
System.out.println("eat");
}
@Override
public void sleep() {
System.out.println("sleep");
}
@Override
public void paint() {
System.out.println("paint");
}
}
我们利用微信公众号的现实例子来实现观察者模式,首先订阅者要先订阅公众号,如果公众号要对每一个订阅者群发消息,就需要挨个挨个地发送给他们。问题来了,订阅者如何订阅公众号,公众号如何对每一个订阅者群发消息?在代码层面上考虑就是,在公众号中创建一个集合来存储每一个订阅者对象,然后遍历循环集合并调用订阅者的update方法。订阅者在创建之初,可以使用构造器来添加公众号对象进去,就实现了订阅者监听公众号是否有群发消息,如果群发了,不仅我能收到,其他人也能收到。
现在需要两个对象,一个是Observer抽象类,另一个是Subject类(理解为公众号),其他具体观察者就继承Observer抽象类。
Subject内存储每一个Observer,在notifyAllObserver方法内部循环集合并调用Observer的update方法来群发消息。观察者执行update方法获取群发消息。
public class Subject {
// 公众号存储所有订阅者
public List<Observer> observers = new ArrayList<>();
// 公众号的名称
private String name;
// 公众号的消息
private String content;
// 添加订阅
public void attach(Observer observer) {
if (observer != null) observers.add(observer);
}
// 删除订阅
public void detach(Observer observer) {
if (observers.indexOf(observer) > 0) observers.remove(observer);
}
// 对每一个订阅者群发消息
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setName(String name) {
this.name = name;
}
public void setContent(String content) {
this.content = content;
}
public String getName() {
return name;
}
public String getContent() {
return content;
}
}
public abstract class Observer {
// 公众号对象
protected Subject subject;
// 更新消息
public abstract void update();
}
public class SubscribeObserver extends Observer {
// 观察公众号
public SubscribeObserver(Subject subject) {
this.subject = subject;
subject.attach(this);
}
@Override
public void update() {
System.out.println("[ " + subject.getName() + " ] 群发了一条消息:" + subject.getContent());
}
}
public class Test {
public static void main(String[] args) {
Subject subject = new Subject();
subject.setContent("恭喜kongsam用户中了一等奖!");
subject.setName("XX公众号");
subject.notifyAllObservers();
SubscribeObserver xiaoming = new SubscribeObserver(subject);
xiaoming.update();
SubscribeObserver xiaohong = new SubscribeObserver(subject);
xiaohong.update();
SubscribeObserver xiaowang = new SubscribeObserver(subject);
xiaowang.update();
}
}
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!
参考文献:
【2】Design Patterns - Observer Pattern
原文:https://www.cnblogs.com/kongsam/p/14426757.html