您的位置:首页 > 编程语言 > Java开发

Java设计模式之——观察者模式(Observer)

2017-01-04 13:03 627 查看
年底了,手头上的项目已经处于收尾阶段,没什么新任务。这段时间争取写两三篇关于设计模式的文章,便于自己加深理解。先从观察者模式开始写起。

一、例子

公司开发讨论组,基本上每天斗图,大部分图片让人看着血脉偾张,眼睛离不开,都是漂亮的美女图,是一种不错的休息方式。

考虑一种场景,大学校园里,男生们想知道他们女神的动态,但又不可能对女神随时随地尾随不去,穷跟不舍。怎么办,买通她闺蜜(给钱,请吃饭,让她占便宜等等)。女神一有新情况,闺蜜就把相关消息透露给感兴趣的男生。暂定闺蜜只把女神在宿舍的动态往外透露,比如女神回到宿舍了,在洗澡,在和某某男生视频聊天,在看电影等等。

下面用代码实现这种场景,先定义女神的接口:

//女神的接口,定义了三个事件,回到宿舍、洗澡、看电影
public interface IGoddess {
//回到宿舍
void backToDormitory();

//洗澡
void haveAShower();

//看电影
void watchMoive();
}


接着再定义闺蜜的接口,闺蜜需要做两件事,一是收集女神的信息,二是把收集的信息透露给给了自己好处的男生。男生可能会有多个,每个男生都需要通知到,对于男生来说,女神的闺蜜就是他们的观察对象,女神不能直接观察到,只能通过观察她闺蜜,间接观察到女神的动态。这里把闺蜜收集信息和把收集的信息透露给相关男生分成两个接口:

//闺蜜的接口一,收集女神信息的接口
public interface IFemaleFriend {
//收集女神的信息
void gatherInfo(String content);
}


把收集的信息透露给相关男生的接口等一下再定义,先定义男生的接口。相对于女神的闺蜜来说,男生是她的观察者,她是一个被观察者。当闺蜜把消息放出去的时候,接收到消息的男生就会采取相应行动,这里把男生的接口名定为观察者(observer):

//男生的接口,观察者接口
public interface Observer {
//收到消息后采取相应行动
void takeAction(String content);
}


接下来再定义女神闺蜜把消息透露给男生的接口,后续可能会有更多男生需要她透露女神的消息,她需要把这些给了好处的男生加入自己的名单中,将消息一一通知给他们,也有些男生不给好处了,她就把他们从
4000
名单中删除,否则自己利益受损。这里将这个接口定义为一个被观察者接口:

//闺蜜的接口二,透露消息的接口,被观察者接口
public interface Observable {
//给了好处的男生需要加入名单
void addObserver(Observer observer);
//不再给好处的男生需要剔除
void deleteObserver(Observer observer);
//将消息透露给在名单中的男生
void notifyObservers(String content);
}


接口已经定义好,接下来实现女神一号,女神一号的闺蜜如花,希望得到女神动态的男生一号和男生二号的具体类。首先是女神的具体实现类,女神一号:

//女神实现类,名字为女神一号
public class GoddessNumOne implements IGoddess {

private IFemaleFriend femaleFriend;

public GoddessNumOne(IFemaleFriend femaleFriend){
this.femaleFriend = femaleFriend;
}

@Override
public void backToDormitory() {
System.out.println();
System.out.println("女神一号:回到宿舍了");
//身边闺蜜收集信息
femaleFriend.gatherInfo("回到宿舍");
}

@Override
public void haveAShower() {
System.out.println();
System.out.println("女神一号:在洗澡了");
//身边闺蜜收集信息
femaleFriend.gatherInfo("在洗澡");
}

@Override
public void watchMoive() {
System.out.println();
System.out.println("女神一号:在看电影了");
//身边闺蜜收集信息
femaleFriend.gatherInfo("在看电影");
}
}


接着看闺蜜如花的具体实现类:

public class RuHua implements Observable, IFemaleFriend{
private ArrayList<Observer> observersList = new ArrayList<>();

@Override
public void gatherInfo(String content) {
//一收到消息就将消息透露给,给了自己好处的男生
notifyObservers(content);
}

@Override
public void addObserver(Observer observer) {
//只要男生给了好处,都加入名单
observersList.add(observer);
}

@Override
public void deleteObserver(Observer observer) {
//不给好处就从名单中踢出
observersList.remove(observer);
}

@Override
public void notifyObservers(String content) {
//把消息通知给在名单中的男生
for (Observer observer : observersList) {
observer.takeAction(content);
}
}
}


接下来看观察者(男生)的两个具体实现类,男生一号和男生二号:

//男生一
public class CollegeBoyOne implements Observer{

@Override
public void takeAction(String content) {
if (content.equals("回到宿舍")) {
System.out.println("男生一:好,很好,非常好!");
} else if (content.equals("在洗澡")) {
System.out.println("男生一:啊!受不了了,老子要打灰机了!");
} else if (content.equals("在看电影")) {
System.out.println("男生一:不会是在看精华片吧,嘿嘿!");
}
}
}


//男生二
public class CollegeBoyTwo implements Observer{

@Override
public void takeAction(String content) {
if (content.equals("回到宿舍")) {
System.out.println("男生二:嗯嗯");
} else if (content.equals("在洗澡")) {
System.out.println("男生二:嘿嘿嘿嘿嘿嘿嘿!");
} else if (content.equals("在看电影")) {
System.out.println("男生二:看什么电影呢,改天我也看看。");
}
}
}


接下来看场景类,把所有这些联系起来:

public class Client {

public static void main(String[] args) {
//如花出场
RuHua ruHua = new RuHua();
//男生一出场
Observer collegeBoyOne = new CollegeBoyOne();
//男生二出场
Observer collegeBoyTwo = new CollegeBoyTwo();
//把男生一加入如花的名单
ruHua.addObserver(collegeBoyOne);
//把男生二加入如花的名单
ruHua.addObserver(collegeBoyTwo);
//女神出场,通过构造器把闺蜜如花传入
IGoddess goddessNumOne = new GoddessNumOne(ruHua);
//女神回到宿舍
goddessNumOne.backToDormitory();
//女神在洗澡
goddessNumOne.haveAShower();
//女神在看电影
goddessNumOne.watchMoive();
}

}


运行结果如下:

女神一号:回到宿舍了

男生一:好,很好,非常好!

男生二:嗯嗯

女神一号:在洗澡了

男生一:啊!受不了了,老子要打灰机了!

男生二:嘿嘿嘿嘿嘿嘿嘿!

女神一号:在看电影了

男生一:不会是在看精华片吧,嘿嘿!

男生二:看什么电影呢,改天我也看看。

二、观察者模式

上面就是一个观察者模式的例子。

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

观察者模式提供了一种对象设计,让被观察者(上面例子中的如花)和观察者(上面例子中的男生一号和二号)之间松耦合。

关于观察者的一切,被观察者(如花)只知道观察者(男生)实现了某个接口,被观察者(如花)不需要知道观察者(男生)的具体类是谁、做了什么或其他任何细节。只要男生给如花好处了,不管如花认不认识那个男生,如花都会给他提供女神的相关信息。

任何时候都可以给被观察者(如花)增加新的观察者(男生)。被观察者唯一依赖的东西是一个实现了Observer接口的列表。在运行时可以用新的观察者取代现有的观察者,被观察者不会受到任何影响。也可以在任何时候删除某些观察者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: