您的位置:首页 > 其它

每天一个设计模式之观察者模式

2017-12-05 22:17 176 查看


模式的动机

在很多情况下,对象并不是孤立存在的,如股票的变动,倘若某支股票上涨,则应该让购买该股票的股民得到通知,并为之欣喜,否则就会失望悲伤,甚至演化出种种的事故… 

从例子中我们不难可以分离出两类角色,一类我们称之为观察者,如股民,另一类就是被这些观察者观察的对象,如股票等;如果观察目标有某个动作发生。观察者就会相应,就像小时候的捉迷藏,躲着的我们在观察是否有人来抓你,有的话就会一下子四散逃跑,那个抓的人就是被观察者; 

同样的在设计模式中,与之对应的是就是观察者模型;话不多说,接下来我们看看它的模式结构到底是怎样的,见下面哦!


模式结构



观察者模式包含以下角色


1.Subject

被观察的对象,也成为目标对象 

在里面提前定义了一个List Observers集合,用来保存实现了Observer接口的各种具体的观察者,这里是能够通知到观察者的重要之点!


2.ConcreteSubject

具体的被观察的对象,继承抽象类Subject 

上面可以一个抽象类,而不是真正的被观察对象,不要混淆哦,多了个抽象类实际上是为了满足ocp和里氏代换原则(不懂这两个原则的自行百度),该具体类实现了向list中保存的各个观察者发出通知,同时也实现了目标类中定义的抽象逻辑方法(如果有的话)


3.Obsever

抽象观察者 

将具体观察者对象抽取出来形成的接口,该接口声明了响应的方法response()


4.ConcreteObserver

具体观察者类 

实现了response()方法


模式分析

这一模式中关键对象是观察目标和观察者,一个目标可以拥有多个与之依赖的观察者(其实就是将具体的观察者存入到List Observers里面),一旦目标对象状态发生变化,所有的观察者都将得到通知(也就是执行notify()方法)。作为对整个通知的响应,每个观察者做出各自的回应(也就是调用自身的response()方法),以达到与状态目标一致的状态,这种交互模式也成为发布-订阅模式(之后将模拟一个微信公众号进行验证,敬请期待),观察者模式定义了一种一对对的依赖关系,下面将举例验证该模式


举例验证

某在线股票软件需要提供如下功能:当股票购买者所购买的某支股票价格变化幅度达到5%时,系统将自动发送通知(包括新价格)给购买该股票的股民。现使用观察者模式设计该系统
//被观察者,也就是抽象目标对象

public abstract class Shares {

protected ArrayList<SharesPeople> people = new ArrayList<SharesPeople>();

public void attach(SharesPeople sharespeople){
people.add(sharespeople);
}

public void remove(SharesPeople sharespeople){
people.remove(sharespeople);
}

public abstract void notifyPeople(int num);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//具体的目标对象,具体的被观察对象
public class SharesEvent extends Shares{

@Override
public void notifyPeople(int num) {
// TODO Auto-generated method stub
if(num>=5){
for(Object obj:people){
System.out.print("***股票变化:");
((SharesPeople)obj).response();
}
}else{
System.out.print("股票变化:");
System.out.println("正常..");
}
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//观察者统一接口
public interface SharesListener {
void response();
}
1
2
3
4
5
//具体观察者
public class SharesPeople implements SharesListener{

private String name;
public SharesPeople(String name){
this.name = name;
}

@Override
public void response() {
// TODO Auto-generated method stub
System.out.println("正在发送通知股民成员:"+name+"。内容为:股票价格变化幅度达到5%..");
System.out.println("***"+name+"已收到通知");
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

客户端进行调用
public class client {

@Test
public void test(){
Shares shares = new SharesEvent();

SharesPeople people1 = new SharesPeople("郑老师");
SharesPeople people2 = new SharesPeople("刘老师");
SharesPeople people3 = new SharesPeople("徐老师");

shares.attach(people1);
shares.attach(people2);
shares.attach(people3);

shares.notifyPeople(1);
shares.notifyPeople(2);
shares.notifyPeople(5);

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

运行结果为:



作者:KD_Y 

博客:http://blog.csdn.net/weixin_36708538/article/details/78725617(转载请说明出处) 

扫码关注我微信,聊点不一样的设计模式 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式