`

策略模式

 
阅读更多
抽象策略角色: 策略类,通常由一个接口或者抽象类实现。   
具体策略角色:包装了相关的算法和行为。   
环境角色:持有一个策略类的引用,最终给客户端调用。

优点:   
  1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。   
  2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。   
  3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。  
 
缺点: 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

package com.jelly.Strategy;

/**
 * 抽象算法类
 * @author Jelly QQ:136179492
 *
 */
public abstract class CashSuper {
	//算法方法
	public abstract void algorithmInterface() ;
}

/**
 * 正常支付类
 * @author Jelly
 *
 */
public class CashNormal extends CashSuper {
	public void algorithmInterface() {
		System.out.println("正常支付");
	}
}

/**
 * 打折支付
 * 
 * @author Jelly QQ:136179492
 * 
 */
public class CashRebate extends CashSuper {
	private double discount;

	public CashRebate(double discount) {
		this.discount = discount;
	}

	public void algorithmInterface() {
		//假设discount只一位小数
		System.out.println("打" + (int)(discount*10) + "折支付");
	}
}

/**
 * 活动返回支付
 * 
 * @author Jelly
 * 
 */
public class CashReturn extends CashSuper {
	public void algorithmInterface() {
		System.out.println("满100送30");
	}
}

/**
 * 上下文
 * 
 * @author Jelly QQ:136179492
 * 
 */
public class CashContext {
	private CashSuper cashSuper;

	public CashContext(CashSuper cashSuper) {
		this.cashSuper = cashSuper;
	}

	/**
	 * 上下文接口
	 */
	public void contextInterface() {
		cashSuper.algorithmInterface();
	}
}

public class Test {

	public static void main(String[] args) {
		CashContext cashContext = null;
		// 正常支付
		cashContext = new CashContext(new CashNormal());
		cashContext.contextInterface();
		// 打8折
		cashContext = new CashContext(new CashRebate(0.8));
		cashContext.contextInterface();
		// 满100送30
		cashContext = new CashContext(new CashReturn());
		cashContext.contextInterface();
	}

}




好像跟简单工厂相似,都是在客户端判断用哪一种算法。
简单工厂是一个单独的类,难道不可以和策略模式结合

在上下文类中加构造函数
    	/**
	 * 结合简单工厂
	 * @param type
	 */
	public CashContext(String type){
		if("正常收费".equals(type)){
			cashSuper = new CashNormal();
		}else if("打8折".equals(type)){
			cashSuper = new CashRebate(0.8);
		}else if("满100送30".equals(type)){
			cashSuper = new CashReturn();
		}
	}


简单工厂模式需要在客户端认识两个类 CashSuper和CashFactory,而与策略模式结合下只需要认识一个 上下文类就可以了。

策略模式是定义一系列算法的方法,从概念上来看,所有这些算法完全都是做相同的工作,只是实现不同,他可以相同的方式调用所有的算法,减少了各种算法类与使用类的之间的耦合。还有简化了单元测试。因为每个算法都有自己的类,可以通过自己的借口进行单元测试。

简单工厂模式和策略模式区别
这两种模式的作用就是拥抱变化,减少耦合。在变化来临时争取做最小的改动来适应变化。这就要求我们把那些“善变”的功能从客户端分离出来,形成一个个的功能类,然后根据多态特性,使得功能类变化的同时,客户端代码不发生变化。

简单工厂模式

简单工厂模式:有一个父类需要做一个运算(其中包含了不同种类的几种运算),将父类涉及此运算的方法都设成虚方法,然后父类派生一些子类,使得每一种不同的运算都对应一个子类。另外有一个工厂类,这个类一般只有一个方法(工厂的生成方法),这个方法的返回值是一个超类,在方法的内部,根据传入参数的不同,分别构造各个不同的子类的对象,并返回。客户端并不认识子类,客户端只认识超类和工厂类。每次客户端需要一中运算时,就把相应的参数传给工厂类,让工厂类构造出相应的子类,然后在客户端用父类接收(这里有一个多态的运用)。客户端很顺理成章地用父类的计算方法(其实这是一个虚方法,并且已经被子类特化过了,其实是调用子类的方法)计算出来结果。如果要增加功能时,你只要再从父类中派生相应功能的子类,然后修改下工厂类就OK了,对于客户端是透明的。

策略模式

策略模式:策略模式更直接了一点,没有用工厂类,而是直接把工厂类的生成方法的代码写到了客户端。客户端自己构造出了具有不同功能的子类(而且是用父类接收的,多态),省掉了工厂类。策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。这里的算法家族和简单工厂模式里的父类是同一个概念。当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为,将这些行为封装在一个个独立的策略子类中,可以在客户端中消除条件语句。

简单工厂模式+策略模式:为了将工厂方法的代码从客户端移出来,我们把这些代码搬到了父类的构造函数中,让父类在构造的时候,根据参数,自己实现工厂类的作用。这样做的好处就是,在客户端不用再认识工厂类了,客户端只要知道父类一个就OK,进一步隔离了变化,降低了耦合。

在基本的策略模式中,选择所用具体实现的职责由客户端对象成端,并转给客户端。这本身并没有减除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由父类承担,这就最大化地减轻了客户端的职责。

  • 大小: 45 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics