设计模式—行为型—策略模式
0.概述
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
策略模式把一个系列的算法封装到一个系列的具体策略类里面,作为一个抽象策略类的子类或策略接口的实现类。简单地说:准备一组算法,并将每一个算法封装起来,使它们可以互换。——《Java与模式》
1.图解
三个角色:
Context:环境,代表策略执行的环境,也可以理解为业务场景,以及运用策略应对不同的问题;
Strategy:抽象策略,衍生出多种不同具体策略
ConcreteStrategy:具体策略
2.应用场景
场景描述:
一个图片加载的场景,假设我们项目内有100处调用图片加载的地方,并且,图片加载的方式可能更改,比如某些图我想用fresco加载,又或者突然有一天fresco这个库突然用不了了我想切成Glide。
这种情况下,用策略模式可以用小成本的工作量对这类需求进行更改。
3.代码练习
Context
package com.zj.dp.策略模式;
/**
* Context 环境类 具体业务实现
*/
public class ImageContext {
public static final String GLID = "GLID";
public static final String FRESCO = "FRESCO";
private Strategy mImgStrategy;
/**
* 具体业务方法
* @param loadType
*/
public void loadImage(final String loadType){
switch (loadType){
case GLID:
mImgStrategy = new GlideStrategy();
break;
case FRESCO:
mImgStrategy = new FrescoStrategy();
break;
}
mImgStrategy.imgLoad();
}
}
Strategy
package com.zj.dp.策略模式;
/**
* 抽象策略类
*/
public abstract class Strategy {
abstract void imgLoad();
}
ConcretStrategy
package com.zj.dp.策略模式;
/**
* 具体策略 concrete Strategy
*/
public class GlideStrategy extends Strategy{
@Override
void imgLoad() {
System.out.println("imgLoad with GlideStrategy。");
}
}
ConcretStrategy
package com.zj.dp.策略模式;
/**
* 具体策略 concrete Strategy
*/
public class FrescoStrategy extends Strategy{
@Override
void imgLoad() {
System.out.println("imgLoad with FrescoStrategy。");
}
}
Client
package com.zj.dp.策略模式;
/**
* CLIENT
*/
public class Client {
public static void main(String[] args) {
ImageContext mImageContext = new ImageContext();
mImageContext.loadImage(ImageContext.GLID);
mImageContext.loadImage(ImageContext.FRESCO);
}
}
输出结果:
imgLoad with GlideStrategy。
imgLoad with FrescoStrategy。
4.总结
本文学习了策略模式,它是属于行为型模式,其中包含4种角色,Client客户端,Context业务环境,Stategy抽象策略,ConcreteStatgy具体策略。
策略模式优点:
1 通过策略类的等级结构来管理算法族。
2 避免使用将采用哪个算法的选择与算法本身的实现混合在一起的多重条件(if-else if-else)语句。
策略模式缺点:
1 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2 由于策略模式把每个算法的具体实现都单独封装成类,针对不同的情况生成的对象就会变得很多。