观察者模式:定义了对象之间的一对多依赖,让多个观察者对象同 时监听一个主体对象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通 知并更新,属于行为型模式。观察者模式有时也叫做发布订阅模式。观察者模式主要用 于在关联行为之间建立一套触发机制的场景。观察者模式在现实生活应用也非常广泛, 比如:微信朋友圈动态通知、邮件通知、广播通知、桌面程序的事件响应等
设计原则 | 简称 | 解释说明 | 备注 |
开闭原则 | (OCP)Open-Closed Principle, | 对扩展开放,对修改关闭。 | |
依赖倒置原则 | (DIP)Dependence Inversion Principle | 高层模块不应该依赖底层模块,二者都应该依赖其抽象。也就是说针对接口编程,不要针对实现编程,针对接口编程包括使用接口或抽象类,这样可以使得各个模块彼此独立,降低模块间的耦合性。而且在实现类中尽量不发生直接的依赖关系,依赖关系通过接口或抽象类产生。 | |
单一职责原则 | (SRP)Single Responsibility Principle | 一个类、接口、方法只做一件事。 | |
接口隔离原则 | (ISP)Interface Segregation Principle, | 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口。胖接口会导致他们的客户程序之间产生不正常的并且有害的耦合关系.当一个客户程序要求该胖接口进行一个改动时,会影响到所有其他的客户程序.因此客户程序应该仅仅依赖他们实际需要调用的方法. | |
迪米特法则 | (LoD)Law of Demeter 又叫做最少知识原则(LKP)Least Knowledge Principle, | 又叫最少知道原则,一个类对其所依赖的类知道得越少越好。就是说,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中的一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。 | |
里氏替换原则 | (LSP)Liskov Substitution Principle, | 子类可以扩展父类的功能但不能改变父类原有的功能。一般而言,如果有两个具体类A,B有继承关系,那么一个最简单的修改方案是建立一个抽象类C,然后让类A和B成为抽象类C的子类. | |
合成复用原则 | (CARP)Composite/Aggregate Reuse Principle, | 尽量使用对象组合、聚合,而不使用继承关系达到代码复用的目的。 |
上代码:
package Observ;
public class Question {
private String name;
private String content;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
package Observ;
import java.util.Observable;
public class Csdn extends Observable {
private String name = "CSDN部落";
private static Csdn csdn;
public Csdn() {
}
public String getName() {
return name;
}
public static Csdn getInstance(){
if(null == csdn){
csdn = new Csdn();
}
return csdn;
}
public void publishQuestion(Question question){
System.out.println(question.getName()+"在"+this.name+"上提交了一个问题。");
setChanged();
notifyObservers(question);
}
}
package Observ;
import java.util.Observable;
import java.util.Observer;
public class CsdnFriend implements Observer {
private String name;
public CsdnFriend(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
Csdn csdn = (Csdn) o;
Question question = (Question) arg;
System.out.println("*******************************");
System.out.println("hello,小伙伴:"+name+"\n"+",你收到了一个来自"+csdn.getName()+"的提问,希望你能回答。"+"\n"+"问题如下:"+"\n"+question.getContent()+"\n"+"提问者:"+csdn.getName());
}
}
package Observ;
public class Test {
public static void main(String[] args) {
Csdn csdn = Csdn.getInstance();
CsdnFriend xiaoMing = new CsdnFriend("xiaoMing");
CsdnFriend wangCai = new CsdnFriend("wangCai");
csdn.addObserver(xiaoMing);
csdn.addObserver(wangCai);
Question question = new Question();
question.setName("侠客行");
question.setContent("问道,问剑,问天下,你可愿入伍?");
csdn.publishQuestion(question);
}
}
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/aafc02c603cf314d3ef0b9114eea4557.png)
观察者模式的优缺点
优点:
1、观察者和被观察者之间建立了一个抽象的耦合。
2、观察者模式支持广播通信。
缺点:
1、观察者之间有过多的细节依赖、提高时间消耗及程序的复杂度。
2、使用要得当,要避免循环调用。