一、观察者模式
又被称为发布/订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系。
Observer(抽象被观察者): 抽象主题角色把所有观察者对象保存在一个集合里。
Subject:抽象观察者,是观察者的抽象类。QQNotice:具体观察者,以便在得到主题更改通知时更新自身的状态。QQClient:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
观察者
interface Observer{
void update(String message);
}
class QQClient implements Observer{
String clientName;
public QQClient(String clientName) {
this.clientName = clientName;
}
@Override
public void update(String message) {
System.out.println(this.clientName + "推送了消息" + message);
}
}
被观察者
interface Subject{
void attache(Observer observer);
void notify(String message);
}
class QQNotice implements Subject{
List<Observer> noticeList = new ArrayList<>();
@Override
public void attache(Observer observer) {
noticeList.add(observer);
}
@Override
public void notify(String message) {
for(Observer observer: noticeList){
observer.update(message);
}
}
}
客户端调用
QQClient qq = new QQClient("客户端1");
QQNotice qqNotice = new QQNotice();
qqNotice.attache(qq);
qqNotice.notify("新的好友消息");
二、访问者模式
概念:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。在不改变数据结构的前提下可以改变数据元素,解决了数据结构和操作耦合性的问题。原理是在被访问的类里增加一个对外提供的待访问者的接口。
主要角色的功能:Judge(抽象访问者): 定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素类个数(即抽象元素角色类的实现类的个数)是一样。
MaleJudge、FemaleJudge(具体访问者): 给出对每一个元素类访问时所产生的具体行为。
Pie(抽象元素): 定义了一个接受访问者的方法(即accept),即每个元素都要可以被访问者访问。
ApplePie、BananaPie(具体元素): 提供接受访问方法的具体实现。
PieStore(对象结构): 是一个盛放元素的容器,并且可以迭代这些元素,供访问者访问。
interface Judge{
void perfectScore(ApplePie pie);
void lowScore(BananaPie pie);
}
// 每一个裁判对不同的物品做出不同的反应
class MaleJudge implements Judge{
@Override
public void perfectScore(ApplePie pie) {
System.out.println("男人的完美评价");
}
@Override
public void lowScore(BananaPie pie) {
System.out.println("男人的很low评价");
}
}
class FemaleJudge implements Judge{
// 这里要依赖具体的类 并不能依赖模糊的接口
@Override
public void perfectScore(ApplePie pie) {
System.out.println("女人的完美评价");
}
@Override
public void lowScore(BananaPie pie) {
System.out.println("女人的很low评价");
}
}
抽象元素和具体元素实现
interface Pie{
void accept(Judge judge);
}
// 每一个被访问的都需要提供一个对外的接口
class ApplePie implements Pie {
@Override
public void accept(Judge judge) {
judge.perfectScore(this);
}
}
class BananaPie implements Pie {
@Override
public void accept(Judge judge) {
judge.lowScore(this);
}
}
class PieStore {
List<Pie> pies = new ArrayList<>();
public void addPie(Pie pie){
pies.add(pie);
}
public void startJudge(Judge judge){
for(Pie pie: pies){
pie.accept(judge);
}
}
}
客户端进行调用
PieStore store = new PieStore();
ApplePie applePie = new ApplePie();
BananaPie bananaPie = new BananaPie();
store.addPie(applePie);
store.addPie(bananaPie);
store.startJudge(new FemaleJudge());
三、迭代器模式
提供一个对象来顺序访问聚合对象中的一系列数据;优点是提供一个统一遍历的方法,隐藏了聚合内部的结构客户端无需考虑内部结构;缺点是每个聚合对象都要一个迭代器,会生成多个不好管理。
Iterator: 定义访问和遍历聚合元素的接口,通常包含hasNext()、next()等方法,这里用的是JDK自带的。
CakeIterator、PieIterator:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
PieCreater:迭代器创建类。
public class Store {
private String name;
private String desc;
public Store(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
public class CakeIterator implements Iterator<Store> {
Store[] stores;
int index = 0;
@Override
public boolean hasNext() {
return index < stores.length && stores[index] != null;
}
@Override
public Store next() {
return stores[index++];
}
public CakeIterator(Store[] storeList){
this.stores = storeList;
}
}
public class PieIterator implements Iterator<Store> {
List<Store> stores = new ArrayList<>();
int index = 0;
public PieIterator(List<Store> storeList){
this.stores = storeList;
}
@Override
public boolean hasNext() {
if(index >= stores.size() || stores.get(index) == null){
return false;
}
return true;
}
@Override
public Store next() {
return stores.get(index++);
}
}
public class PieCreater {
List<Store> stores = new ArrayList<>();
public PieIterator createPieIterator(){
return new PieIterator(stores);
}
public CakeIterator createCakeIterator(){
return new CakeIterator(stores.toArray(new Store[0]));
}
public void addStores(Store store){
stores.add(store);
}
}