策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
抽象策略角色:通常用一个抽象类或者接口来实现,主要是定义这个算法所完成的功能
具体策略角色:包装了相关算法和行为
环境角色:持有策略类的引用
使用场景:
1) 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态的让一个对象在许多行为中选择一种行为。
2) 如果系统需要动态地在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多态性原则。客户端可以选择使用任何一个具体算法类,并只持有一个数据类型是抽象算法类的对象。
3) 一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复发的和只与算法有关的数据。
4) 假设这样一个案例:假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。如果要计算购物车的货品的价格,一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。
策略模式的缺点:
1) 客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2)策略模式造成许多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
package com.qinsoft.design; public class Strategy { public static void main(String[] args) { StrategyInter stgA = new ConcreteStrategyA(); StrategyContext ct = new StrategyContext(stgA); ct.DoAction(); } } /** * 环境角色:操作不同的策略 */ class StrategyContext { private StrategyInter stg; public StrategyContext(StrategyInter theStg) { this.stg = theStg; } public void DoAction() { this.stg.AlgrithmInterface(); } } /** * 抽象策略角色:定义一个策略接口 */ interface StrategyInter { void AlgrithmInterface(); } /** * 具体策略角色:策略A */ class ConcreteStrategyA implements StrategyInter { public void AlgrithmInterface() { System.out.println("策略A被执行。。。。。。。。"); } } /** * 具体策略角色:策略B */ class ConcreteStrategyB implements StrategyInter { public void AlgrithmInterface() { System.out.println("策略B被执行。。。。。。。。"); } }