设计模式之观察者模式

Posted by ShiYu on 2018-04-18

最近一段时间一直在和刚毕业时写的代码打交道,现在的自己看着以前写下的代码,简直是“目不忍视”了,很多代码糅合在一起,只考虑功能,丝毫没有考虑代码的美感。有以下场景:

系统中存在“资源”、“实体”、“字段”等几个概念,资源后面的几个对象都依赖资源的存在,如果资源被删除,就应该删除该资源下对应的实体、字段等

我之前的代码是在删除资源的方法里面写上删除字段、实体,然后用事务包装起来,这样写功能是没有问题的,但是当系统突然又增加了很多的概念,比如血缘、扩展属性等,这些对象在删除资源时应该也被对应删除,如果还是按照之前的代码,就需要修改删除资源的方法,在里面再加上删除血缘的的方法,更要命的是如果维护血缘的人不是自己,别人就要找到我之前写的删除资源方法并修改,这种方式让代码的维护变得很困难,本篇博客介绍的观察者模式就可以很好的解决上述问题。

观察者模式

观察者模式,简单的理解就是观察者订阅被观察者的状态,当观察者状态改变时,所有依赖于它的对象都得到通知并自动更改。主要用来解决一个对象状态的改变给其它对象通知问题,并保证易用和低耦合。

用观察者模式解决文章开篇提到的问题:

  1. 定义观察者抽象类
1
2
3
4
5
6
7
8
9
package net.syhong.Observer;

/**
* 观察者抽象类
* Created by ShiYu on 2018/4/18.
*/
public abstract class Observer {
public abstract void update(String msg);
}
  1. 定义具体观察者

实体观察者:

1
2
3
4
5
6
7
8
9
10
11
12
package net.syhong.Observer;

/**
* 实体观察者
* Created by ShiYu on 2018/4/18.
*/
public class EntityObserver extends Observer{

public void update(String msg) {
System.out.println("删除"+msg+"下实体");
}
}

字段观察者:

1
2
3
4
5
6
7
8
9
10
11
package net.syhong.Observer;

/**
* 字段观察者
* Created by ShiYu on 2018/4/18.
*/
public class FieldObserver extends Observer {
public void update(String msg) {
System.out.println("删除"+msg+"下对应字段");
}
}
  1. 定义被观察者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package net.syhong.Observer;

import java.util.ArrayList;
import java.util.List;

/**
* 资源类,被观察者
* Created by ShiYu on 2018/4/18.
*/
public class Resource {

//观察者
private List<Observer> observers=new ArrayList<Observer>();

//改变资源状态
public void delete(){
notifyAll("资源ID");
}

//注册观察者,可以理解成观察者订阅资源的状态
public void attach(Observer observer){
observers.add(observer);
}

//通知所有订阅的观察者
private void notifyAll(String msg){
//涉及数据库操作的话此处可加事务
for(Observer observer:observers){
observer.update(msg);
}
}

}
  1. 使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package net.syhong.Observer;

/**
* Created by ShiYu on 2018/4/18.
*
* 系统中存在资源、实体、字段3个概念,当删除资源时,要删除该资源对应的字段、实体等信息,
* 由于随着业务发展,还可能会删除更多的东西,比如血缘、扩展属性等,采用观察者模式可以实现松耦合
*/
public class Demo {
public static void main(String[] args) {
//被观察者:资源
Resource resource=new Resource();
//观察者:字段
Observer fieldObserver=new FieldObserver();
//观察者:实体
Observer entityObserver=new EntityObserver();

//注册观察者
resource.attach(entityObserver);
resource.attach(fieldObserver);

//改变被观察者状态,从而通知字段和实体资源被删除了,请删除该资源下对应的相关信息
resource.delete();
}
}

/*运行结果:
删除资源ID下实体
删除资源ID下对应字段
*/