23种设计模式——策略模式(Strategy)

爱⌒轻易说出口 提交于 2019-12-17 18:56:31

一、策略模式
策略模式(Strategy),定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。比如出行方式,可以选择骑自行车、坐公交车、打车、开车等等,每种出行方式都是一个策略。
在这里插入图片描述
二、策略模式的应用
1.使用场景
针对同一类型的问题,有多种处理方式,每一种都能独立解决问题且区分它们的只是它们直接的行为。算法需要自由切换的场景。需要屏蔽算法规则的场景。
2.使用方式
strategy类,定义所有支持的算法的公共接口。
concreteStrategy,封装具体的方法或行为,继承strategy类。
context,用一个concreteStrategy来配置,维护一个对strategy的引用。
简单工厂或枚举类生成Context对象。
3.主要解决
有多种算法相似的情况下,大量使用if else为程序带啦的负责性和臃肿性。
4.优点
算法的多样性,且具备自由切换场景。有效避免多重条件判断,增强了封装性,简化的操作,降低出错概率。扩展性良好,策略类遵循里氏替换原则,可以很方便的进行策略扩展。
5.缺点
策略类数量增多,每个策略都是一个类,复用的可能性很小。所有策略类必须对外暴露,以便客户端能够选择。
6.注意事项
如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略膨胀的问题。
三、策略模式的实现
1.strategy

public abstract class Strategy {
	public abstract void AlgorithmInterface();
}

2.concreteStrategy

public class ConcreteStrategyA extends Strategy {
	@Override
	public void AlgorithmInterface() {
		System.err.println("ConcreteStrategyA的实现");
	}
}
public class ConcreteStrategyB extends Strategy {
	@Override
	public void AlgorithmInterface() {
		System.err.println("ConcreteStrategyB的实现");
	}
}
public class ConcreteStrategyC extends Strategy {
	@Override
	public void AlgorithmInterface() {
		System.err.println("ConcreteStrategyC的实现");
	}
}

3.context

public class Context {
	
	private Strategy strategy;
	
	Context(Strategy strategy){
		this.strategy = strategy;
	}
	
	public void contextInterface(){
		strategy.AlgorithmInterface();
	}
}

4.StrategyFactory

public class StrategyFactory {
	public static Context create(Integer type){
		Context context = null;
		switch (type) {
		case 1:
			context = new Context(new ConcreteStrategyA());
			break;
		case 2:
			context = new Context(new ConcreteStrategyB());
			break;
		case 3:
			context = new Context(new ConcreteStrategyC());
			break;
		}
		return context;
	}
}
public enum StrategyEnum {
	
	ConcreteStrategyA {
        @Override
        public Context create() {
            return new Context(new ConcreteStrategyA());
        }
    },
    ConcreteStrategyB {
        @Override
        public Context create() {
        	return new Context(new ConcreteStrategyA());
        }
    },
    ConcreteStrategyC {
        @Override
        public Context create() {
        	return new Context(new ConcreteStrategyA());
        }
    };

    public abstract Context create();
}

5.StrategyClient

public class StrategyClient {

	public static void main(String[] args) {
		Context context;
		//策略模式 中的上下文环境(Context),其职责本来是隔离客户端与策略类的耦合,
		//让客户端完全与上下文环境沟通,无需关系具体策略
		/**
		 * 传统方式
		 * 客户端内部直接自己指定要哪种策略(new Context(new ConcreteStrategyA())),
		 * 客户端与具体策略类耦合了,
		 * 而上下文环境在这里起的作用只是负责调度执行,获取结果,并没有完全起到隔离客户端与策略类的作用。
		 */
		context = new Context(new ConcreteStrategyA());
		context.contextInterface();
		context = new Context(new ConcreteStrategyB());
		context.contextInterface();
		context = new Context(new ConcreteStrategyC());
		context.contextInterface();
		/**
		 * 简单工厂
		 * 可以通过简单工厂模式将具体策略的创建与客户端进行隔离
		 */
		context = StrategyFactory.create(1);
		context.contextInterface();
		context = StrategyFactory.create(2);
		context.contextInterface();
		context = StrategyFactory.create(3);
		context.contextInterface();
		/**
		 * 枚举
		 * 通过策略枚举将上下文环境与具体策略类融合在一起,简化代码。
		 * 当具体策略相对稳定时,推荐使用策略枚举。
		 */
		context = StrategyEnum.ConcreteStrategyA.create();
		context.contextInterface();
		context = StrategyEnum.ConcreteStrategyB.create();
		context.contextInterface();
		context = StrategyEnum.ConcreteStrategyC.create();
		context.contextInterface();
	}

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!