设计模式简介
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
实例
以热水器烧水为例,再水开了以后通知所有注册为观察者的人。
先新建一个烧水器的类
public class Boiler {
List<Person> list = new ArrayList<>();
public void waterStatus(boolean waterStatus) {
if(waterStatus) {
notifyPerson();
}
}
public void register(Person person) {
list.add(person);
}
public void notifyPerson() {
for (Person person : list) {
person.receive();
}
}
}
新建接口,每个需要注册为观察者的人都实现这个接口
/**
* 等着烧开水的人的抽象类
* @author Administrator
*
*/
public abstract class Person {
public abstract void receive();
}
public class Person001 extends Person{
public Person001(Boiler boiler) {
boiler.register(this);
}
@Override
public void receive() {
System.out.println("001已经收到水开了的信息");
}
}
public class Person002 extends Person{
public Person002(Boiler boiler) {
boiler.register(this);
}
@Override
public void receive() {
System.out.println("002已经收到水开了的信息");
}
}
运行
public static void main(String[] args) {
Boiler boiler = new Boiler();
new Person001(boiler);
new Person002(boiler);
boiler.waterStatus(false);//水还没有开 不用通知
System.out.println("=============");
boiler.waterStatus(true);//水已经开了,通知所有人
}
结果
=============
001已经收到水开了的信息
002已经收到水开了的信息