设计模式 - 策略模式strategy & 委派模式deledate
策略模式:定义一组实现相同接口的类,高层模块根据场景实例化合适的对象
委派模式:委派类持有被委派类的引用,并由委派类完成任务的分发、调度
- 策略模式和委派模式的实现方式是一样的: (组合)单控制类 + 执行逻辑接口,通过创建不同的执行逻辑子类,完成解耦和复用
- 是不同侧重下的不同描述:
- 策略模式:侧重实现类之间可替换,(任务调度分派的职责交由高层模块)
- 委派模式:侧重任务调度分派,(只有一个被委派对象的情况下就无需策略了)
- 策略模式允许高层模块决定采取哪种策略,而委派模式的委派细节对于高层模块是不可见的
PS:一般而言,多执行者的情景中,委派模式 ≈ 工厂方法模式 + 策略模式
策略模式(strategy)
general
// 策略模式 - 一般应用中,策略模式的策略一般由高层模块决定(此和委派模式有细微不同,职责划分的区别)
public class Context{
private IStrategy strategy = null;
Context(IStrategy strategy){
this.strategy = strategy;
}
public void algorithm(){
strategy.algorithm();
}
}
通过工厂方法模式对策略进行管理
public class StrategyFactory {
private static HashMap<String, IStrategy> strategyContainer = null;
static{
strategyContainer = new HashMap<>();
strategyContainer.put(StrategyType.A,new StrategyA());
strategyContainer.put(StrategyType.B,new StrategyB());
}
// 现在的策略实现类存放在容器中,属于共享使用(单例)
public IStrategy getStrategy(String stratrgyName){
return strategyContainer.get(stratrgyName);
}
// 维护一份策略列表,用户根据策略常量获取对应的策略
public static final class StrategyType{
public static final String A = "A";
public static final String B = "B";
}
}
枚举策略!!!
public enum EnumStrategy {
ADD(){
@Override
public int exec(int a, int b) {
return a + b;
}
},
SUB(){
@Override
public int exec(int a, int b) {
return a - b;
}
};
private EnumStrategy(){}
public abstract int exec(int a, int b);
}
strategy Test
// Test - 策略模式语境下,策略是由高层模块决定的。
public static void main(String[] args) {
// 普通策略模式
Context contextA = new Context(new StrategyA());
contextA.algorithm();
// 策略模式与工厂模式合并使用,工厂模式负责创建策略类(工厂模式也维护了一份策略常量类)
StrategyFactory strategyFactory = new StrategyFactory();
IStrategy strategyB = strategyFactory.getStrategy(StrategyFactory.StrategyType.B);
Context contextB = new Context(strategyB);
contextB.algorithm();
// 枚举策略
int add = EnumStrategy.ADD.exec(1,2); // add = 3;
}
委派模式(deledate)
general
// 委派模式,语境中侧重委派 (根据用户输入参数,委派给不同的executor处理)
public class Delegater{
// 初始化被委派人
private Map<String, IExecutor> executors = null;
{
executors = new HashMap<>();
executors.put("A",new ExecutorA());
executors.put("B",new ExecutorB());
}
// 根据策略选择被委派者,将任务委托给被选中者执行。
public void execute(String command) {
if(executors.containsKey(command)){
executors.get(command).execute(command);
}
}
}
spring dispatcher模拟
public class DispatcherServlet extends HttpServlet {
// 初始化执行环境 - handlerMapping和ioc
private static ConcurrentHashMap<String, Method> handlerMapping = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, Object> ioc = new ConcurrentHashMap<>();
static{
try {
handlerMapping.putIfAbsent("/selectAll",MemberController.class.getMethod("selectAll"));
ioc.putIfAbsent("/selectAll",new MemberController());
} catch (NoSuchMethodException e){
e.printStackTrace();
}
}
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doDispatch(req.getRequestURI()); // 已简化
}
public void doDispatch(String uri){
try {
// method.invoke(Object,params[]) - 委派Object执行method.
Method method = handlerMapping.get(uri);
method.invoke(ioc.get(uri),null);
} catch (Exception e){
e.printStackTrace();
}
}
}
strategy Test
// 委派模式语境下,用户只知Delegater完成了对应任务(不知具体的委派流程和实现)
public class Test {
public static void main(String[] args) {
Delegater delegater = new Delegater();
delegater.execute("A");
delegater.execute("B");
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.doDispatch("/selectAll");
}
}
欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友
-- 星河有灿灿,愿与之辉