An open API service indexing awesome lists of open source software.

https://github.com/louloulin/zed

设计模式
https://github.com/louloulin/zed

java

Last synced: 10 months ago
JSON representation

设计模式

Awesome Lists containing this project

README

          

# 设计模式

### 观察者模式

观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,从而触发观察者的动作。

观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。
#### 观察者模式主要构成
* 观察者
* 目标对象

#### 观察者模式的例子
就以警察监控罪犯的例子来说明观察者模式的,代码如下:

1. 观察者接口:Observer

package com.listener;
/**
* 观察者模式接口
* @author lin
* @date 2018-01-16
*/
public interface Observer {
/**
* 观察动作
* @param message
* @param name
*/
void update(String message,String name);
}
2. 定义两名便衣观察者:Policeman1,Policeman2

import com.listener.Observer;
/**
* 便衣警察邹宇
*/
public class Policeman1 implements Observer {
/**
* 警察名称
*/
private String bname = "邹宇";

@Override
public void update(String message, String name) {
System.out.println(bname + ":" + name + "那里有新情况:" + message);
}
}


import com.listener.Observer;
/**
* 便衣警察
*/
public class Policeman2 implements Observer {
/**
* 警察名称
*/
private String bname = "周童";

@Override
public void update(String message, String name) {
System.out.println(bname + ":" + name + "那里有新情况:" + message);
}
}
3. 监控对象接口

/**
* 目标接口
* @author lin
* @date 2018-01-16
*/
public interface Badass {
/**
* 添加便衣观察者
* @param observer
*/
void addObserver(Observer observer);
/**
* 移除便衣观察者
* @param observer
*/
void removeObserver(Observer observer);

/**
* 通知观察者
* @param message
*/
void notice(String message);
}
4. 目标对象的的实现,定义2个罪犯

/**
* 嫌犯大熊
*/
public class XianFan1 implements Badass {
/**
* 别称
*/
private String name = "大熊";
/**
* 定义观察者集合
*/
private List observerList = new ArrayList();

/**
* 增加观察者
*
* @param observer
*/
@Override
public void addObserver(Observer observer) {
if (!observerList.contains(observer)) {
observerList.add(observer);
}
}

/**
* 移除观察者
*
* @param observer
*/
@Override
public void removeObserver(Observer observer) {
if (observerList.contains(observer)) {
observerList.remove(observer);
}
}

/**
* 通知观察者
*
* @param message
*/
@Override
public void notice(String message) {
for (Observer observer : observerList) {
observer.update(message, name);
}
}
}


/**
* 嫌犯大熊
*/
public class XianFan2 implements Badass {
/**
* 别称
*/
private String name = "小熊";
/**
* 定义观察者集合
*/
private List observerList = new ArrayList();

/**
* 增加观察者
*
* @param observer
*/
@Override
public void addObserver(Observer observer) {
if (!observerList.contains(observer)) {
observerList.add(observer);
}
}

/**
* 移除观察者
*
* @param observer
*/
@Override
public void removeObserver(Observer observer) {
if (observerList.contains(observer)) {
observerList.remove(observer);
}
}

/**
* 通知观察者
*
* @param message
*/
@Override
public void notice(String message) {
for (Observer observer : observerList) {
observer.update(message, name);
}
}
}
5. 测试类:Main

/**
* 类名称: Main

* 类描述:

*
* @author: lin
* @date: // 上午:
* @company: Demical
*/
public class Main {
public static void main(String[] args) {
//定义两个嫌犯
Badass xf1 = new XianFan1();
Badass xf2 = new XianFan2();
//定义三个观察便衣警察
Observer o1 = new Policeman1();
Observer o2 = new Policeman2();
//为嫌犯增加观察便衣
xf1.addObserver(o1);
xf1.addObserver(o2);
xf2.addObserver(o1);
xf2.addObserver(o2);
//定义嫌犯的情况
String message1 = "光头强的面包到了";
String message2 = "光头强要来砍树了";
xf1.notice(message1);
xf2.notice(message2);
}
}
6. 测试结果

邹宇:大熊那里有新情况:光头强的面包到了
周童:大熊那里有新情况:光头强的面包到了
邹宇:小熊那里有新情况:光头强要来砍树了
周童:小熊那里有新情况:光头强要来砍树了
### 观察者模式总结

* 针对观察者与被观察者分别定义接口,有利于分别进行扩展
* 重点就在被观察者的实现中:
1. 定义观察者集合,并定义针对集合的添加、删除操作,用于增加、 删除订阅者(观察者)
2. 定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3. 观察者中需要有个接收被观察者通知的方法。

* 观察者模式定义的是一对多的依赖关系,一个被观察者可以拥有多个观察者,并且通过接口对观察者与被观察者进行逻辑解耦,降低二者的直接耦合。
* 如此这般,想了一番之后,突然发现这种模式与桥接模式有点类似的感觉。桥接模式也是拥有双方,同样是使用接口(抽象类)的方式进行解耦,使双方能够无限扩展而互不影响,其实二者还是有者明显的区别:
1. 主要就是使用场景不同,桥接模式主要用于实现抽象与实现的解耦,主要目的也正是如此,为了双方的自由扩展而进行解耦,这是一种多对多的场景。观察者模式侧重于另一方面的解耦,侧重于监听方面,侧重于一对多的情况,侧重于一方发生情况,多方能获得这个情况的场景。

2. 另一方面就是编码方面的不同,在观察者模式中存在许多独有的内容,如观察者集合的操作,通知的发送与接收,而在桥接模式中只是简单的接口引用。

下期说说桥接模式,哈哈。