策略模式


策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。


       策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。


  这个模式涉及到三个角色:

  ●  环境(Context)角色:持有一个Strategy的引用。

  ●  抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  ●  具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

  Context:

public class CashContext {

	private Strategy cs;
	
	public CashContext(Strategy cssuper){
		this.cs = cssuper;
	}
	
	public double getResult(double money){
		return cs.algorInterface(money);
	}
}

Strategy:

public abstract class Strategy {
   
	double money;
	
	public Strategy(double m){
		this.money = m;
	}
	
	public double getMoney(){
		return this.money;
	}
	public void setMoney(double m){
		this.money = m;
	}
	public abstract double algorInterface(double m);
}
ConcreteStrategy:

//正常收费

public class CashNormal extends Strategy {

	public CashNormal(double m){
		super(m);
	}
	
	public double algorInterface(double m){
		return m;
	}
}

//打折

public class CashRebate extends Strategy {

	private double rebate = 0;
	
	public CashRebate(double m,double r){
		super(m);
		rebate = r;
	}
	
	public double algorInterface(double m){
		return m*rebate;
	}
}

//满X返Y

public class CashReturn extends Strategy {

	private double _return = 0;  //满五百反一百, 100
	private double _condition = 0; //500
	
	public CashReturn(double m,double c,double r){
		super(m);
		_return = r;
		_condition = c;
	}
	
	public double algorInterface(double m){
		double result = m;
		if(m > _condition){
			result = m - ((int)(m / _condition))*_return;
		}
		return result;
	}
	
}

客户端

import java.util.ArrayList;
import java.util.List;

public class CashClient {

	public static void main(String[] args) {
		List<String> str = new ArrayList<String>();
        str.add("正常收费");
        str.add("打8折");
        str.add("满300减100");
		CashContext cashContext = null;
		for(String ss : str){
			switch(ss){
			case "正常收费" :
				cashContext = new CashContext(new CashNormal(500));
			    break;
			case "打8折" :
				cashContext = new CashContext(new CashRebate(500, 0.8));
				break;
			case "满300减100" :
				cashContext = new CashContext(new CashReturn(500, 300,100));
				break;
			default :
				System.out.println("打烊了.");
			}
			double re =  cashContext.getResult(500);
			System.out.println(re);
		}   
        
	}

}

结果:

500.0
400.0
400.0


总结:

      策略模式主要体现为封装变化点,这种设计思想很重要,看到题目是超市收费,给出的几种收费方式的时候,要想到如何涵盖这些收费方式也就是算法,如何利于后续的扩展,同时如何降低模块之间的耦合度。

策略模式和简单工程模式比较:

简单工厂模式:客户端传一个条件进工厂类,工厂类根据条件创建相应的产品类对象,并return给客户端,供客户端使用。即客户端使用的是工厂类生产的产品对象。

策略模式:客户端创建一个Context类对象a(可以看作是工厂模式中工厂类),创建一个策略对象并传参给对象a,然后客户端使用a对象的某些方法来使用前面传参进来的策略,即客户端是通过a对象使用策略的。

简单的说,

1、工厂模式根据条件生产出产品给客户端用。而策略模式是客户端使用传参给Context的策略(你也可以理成产品),传入策略的不同,调用同样方法得到的结果也不同。

2、工厂模式:客户端是使用工厂类生产的对象进行操作,策略模式:客户端使用自己传给Context的策略的对象进行操作。



参考文章:

http://blog.youkuaiyun.com/zhangliangzi/article/details/52161211

https://www.cnblogs.com/langtianya/archive/2013/03/08/2950934.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值