行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
一、策略模式
记得在中学时代,每次考完老师评讲试卷,都会说这道题有多少种解法,然后在黑板上板书第一种、第二种解法。其实这个情况就类似于今天的情况,也就是策略模式。他表示的是在遇到一种问题有多种解法的时候,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。
/**
* 旅行策略的抽象接口
*/
public interface TravelStrategy {
public void choose();
}
public class TrainStrategy implements TravelStrategy {
public void choose() {
System.out.println("火车出游");
}
}
public class BusStrategy implements TravelStrategy {
public void choose() {
System.out.println("大巴出游");
}
}
/**
* 环境
*/
public class ContextChoose {
private TravelStrategy mTravelStrategy;
public ContextChoose(TravelStrategy travelStrategy) {
mTravelStrategy = travelStrategy;
}
public void travel() {
mTravelStrategy.choose();
}
}
public static void main(String[] args) {
TravelStrategy strategy = new TrainStrategy();
// TravelStrategy strategy = new BusStrategy();
ContextChoose context = new ContextChoose(strategy);
context.travel();
}
优点:
(1)我们之前在选择出行方式的时候,往往会使用if-else语句,也就是用户不选择A那么就选择B这样的一种情况。这种情况耦合性太高了,而且代码臃肿,有了策略模式我们就可以避免这种现象。
(2)策略模式遵循开闭原则,实现代码的解耦合。扩展新的方法时也比较方便,只需要继承策略接口就好了。
缺点:
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
(2)策略模式会出现很多的策略类。
二、观察者模式
观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),定义对象间一种一对多的依赖关系,使得被观察者状态发生改变时,会通知所有的观察者。
例子:小说(被观察者),小说爱好者(观察者),小说爱好者订阅了小说,当小说有更新的时候,会推送给小说爱好者。
/**
* 被观察者-小说
*/
public interface Novel {
void subscribe(Reader reader); // 订阅
void notify(String content); // 小说更新
}
/**
* 小说的实现类,武侠小说
*/
public class WuXiaNovel implements Novel {
private List<Reader> mReaderList = new ArrayList<Reader>();
// 订阅
public void subscribe(Reader reader) {
if (!mReaderList.contains(reader)) {
mReaderList.add(reader);
}
}
// 内容更新
public void notify(String content) {
for (Reader reader : mReaderList) {
reader.update(content);
}
}
}
/**
* 观察者-读者
*/
public interface Reader {
void update(String content);
}
// A读者
public class ReaderA implements Reader {
public void update(String content) {
System.out.println("读者A的内容更新了:" + content);
}
}
// B读者
public class ReaderB implements Reader {
public void update(String content) {
System.out.println("读者B的内容更新了:" + content);
}
}
public static void main(String[] args) {
// 创建一本小说
Novel novel = new WuXiaNovel();
// 读者A订阅了小说
novel.subscribe(new ReaderA());
// 读者B订阅了小说
novel.subscribe(new ReaderB());
// 小说更新内容了
novel.notify("ABCDEF");
}
优点:
观察者模式的主要优点在于可以实现表示层和数据逻辑层的分离,并在观察目标和观察者之间建立一个抽象的耦合。
缺点:
在于如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,而且如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
三、责任链模式
责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。
例子:OKHttp的拦截器就是基于责任链模式来实现的
/**
* 抽象的Logger类
*/
public abstract class AbsLogger {
// 保存下一个执行对象
protected AbsLogger mNextLogger;
public void setNextLogger(AbsLogger nextLogger) {
mNextLogger = nextLogger;
}
public void showLog(String log) {
writeLog(log);
// 核心在这
if (mNextLogger != null) {
mNextLogger.showLog(log);
}
}
protected abstract void writeLog(String log);
}
/**
* AbsLogger实现类
*/
public class InfoLogger extends AbsLogger {
@Override
protected void writeLog(String log) {
System.out.println("==InfoLogger==" + log);
}
}
/**
* AbsLogger实现类
*/
public class DebugLogger extends AbsLogger {
@Override
protected void writeLog(String log) {
System.out.println("==DebugLogger==" + log);
}
}
/**
* AbsLogger实现类
*/
public class ErrorLogger extends AbsLogger {
@Override
protected void writeLog(String log) {
System.out.println("==ErrorLogger==" + log);
}
}
public static void main(String[] args) {
AbsLogger infoLogger = new InfoLogger();
AbsLogger debugLogger = new DebugLogger();
AbsLogger errorLogger = new ErrorLogger();
// 设置infoLogger的下一个节点是debugLogger
infoLogger.setNextLogger(debugLogger);
// 设置debugLogger的下一个节点是errorLogger
debugLogger.setNextLogger(errorLogger);
infoLogger.showLog("ABCD");
}
四、模板方法
定义一个模板结构,将具体内容延迟到子类去实现。
public abstract class BaseActivity {
// onStart方法定义了一个固定模板,
// 需要子类执行的方法就重写doOnStart,其他的公共方法按固定顺序固定内容执行
final void onStart() {
calculateStartTime();
doOnStart();
setPoint();
calculateEndTime();
}
abstract void doOnStart();
private void calculateStartTime() {
System.out.println("计算开始时间");
}
private void setPoint() {
System.out.println("埋点操作...");
}
private void calculateEndTime() {
System.out.println("计算结束时间");
}
}
/**
* BaseActivity的子类
*/
public class ActivityA extends BaseActivity {
@Override
void doOnStart() {
System.out.println("A的onStart方法执行...");
}
}
/**
* BaseActivity的子类
*/
public class ActivityB extends BaseActivity {
@Override
void doOnStart() {
System.out.println("B的onStart方法执行...");
}
}
public static void main(String[] args) {
ActivityA a = new ActivityA();
a.onStart();
ActivityB b = new ActivityB();
b.onStart();
}