行为型(一)—策略模式

1、定义

Define a family of algorithms, encapsulate each one, and make them interchangeable.

定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

2、使用场景

  1. 多个类只是在算法或行为上稍有不同
  2. 算法需要自由切换
  3. 需要屏蔽算法规则

3、UML类图


角色说明:

  1. 上下文Context: 屏蔽高层模块对策略、算法的直接访问,它持有一个Strategy类的引用
  2. 抽象策略Strategy:对策略、算法进行抽象、
  3. ConcreteStrategyA、ConcreteStrategyB:是实现抽象策略中的具体操作,具体算法。

4、示例

以图书馆售书折扣为例,存在以下三种折扣算法:

  1. 算法1:对有些图书没有折扣,即折扣值算法中折扣值为0
  2. 算法2:对有些图书的折扣值是固定值为1元
  3. 算法3:对有些图书的折扣是15%
/**
 * 抽象折扣算法
 * @author Administrator
 *
 */
public abstract class Strategy {
	private double price;
	private int number;
	
	public Strategy(double price, int number) {
		super();
		this.price = price;
		this.number = number;
	}
	
	
	public double getPrice() {
		return price;
	}


	public int getNumber() {
		return number;
	}

	// 策略算法,计算折扣额
	public abstract double calculateDiscount();
	
}
/**
 * 具体折扣类,没有折扣算法
 * @author Administrator
 *
 */
public class NoDiscountStrategy extends Strategy{

	public NoDiscountStrategy(double price, int number) {
		super(price, number);
	}

	/**
	 * 实现策略算法,0折扣算法
	 */
	@Override
	public double calculateDiscount() {
		return 0;
	}
}
/**
 * 具体折扣类,固定折扣值为1的算法
 * @author Administrator
 *
 */
public class FixDiscountStrategy extends Strategy{

	public FixDiscountStrategy(double price, int number) {
		super(price, number);
	}

	/**
	 * 实现策略算法,固定的折扣额
	 */
	@Override
	public double calculateDiscount() {
		return getNumber() * 2;
	}
}
/**
 * 具体的折扣,按照15%的折扣算法
 * @author Administrator
 *
 */
public class PercentageDiscountStrategy extends Strategy{

	public PercentageDiscountStrategy(double price, int number) {
		super(price, number);
	}

	/**
	 * 具体策略算法,15%的折扣额
	 */
	@Override
	public double calculateDiscount() {
		return getNumber() * getPrice() * 0.15;
	}
}
/**
 * 上下文文Context的实现
 * @author Administrator
 *
 */
public class ContextClient {
	private Strategy strategy;
	
	public ContextClient(Strategy strategy) {
		super();
		this.strategy = strategy;
	}
	
	/**
	 * 调用策略算法,计算折扣值
	 * @return
	 */
	public double calDiscount() {
		return strategy.calculateDiscount();
	}
	
	public static void main(String[] args) {
		ContextClient client0 = new ContextClient(new NoDiscountStrategy(48.5, 20));
		System.out.println("0折扣:" + client0.calDiscount());
		
		ContextClient clientFix = new ContextClient(new FixDiscountStrategy(48.5, 20));
		System.out.println("固定折扣:" + clientFix.calDiscount());
		
		ContextClient clientPer = new ContextClient(new PercentageDiscountStrategy(48.5, 20));
		System.out.println("15%折扣:" + clientPer.calDiscount());
	}

}

输出结果如下:

0折扣:0.0
固定折扣:40.0
15%折扣:145.5

5、总结

优点:

  1. 定义了一个算法和行为族,恰当的使用继承将公共的代码移到父类中,避免代码重复。
  2. 避免使用多重条件判断。

缺点:

  1. 客户端必须知道所有的策略类,并自行决定使用哪个策略类。
  2. 随着策略的增加,子类也会变得繁多。



猜你喜欢

转载自blog.csdn.net/zcjxaiofeizhu/article/details/80716628