`
zzq19860626
  • 浏览: 260978 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
B20df9e2-fb3d-3644-9f72-c1619842f682
设计模式学习笔记
浏览量:177959
87eaf24f-812a-3463-8e65-e3197d2ad8c2
java虚拟机
浏览量:26186
社区版块
存档分类
最新评论

JAVA设计模式学习17——策略模式

阅读更多

策略(Strategy)模式:又名Policy,它的用意是定义一组算法,把它们一个个封装起来,并且使他们可以相互替换。策略模式可以独立于使用他们的客户端而变化。GOF策略模式静态结构类图如下:

通过上图可以看出策略模式有以下角色构成:

1、抽象策略(Strategy)角色:抽象策略角色由抽象类或接口来承担,它给出具体策略角色需要实现的接口;

2、具体策略(ConcreteStrategy)角色:实现封装了具体的算法或行为;

3、场景(Context)角色:持有抽象策略类的引用。

策略模式重点是封装不同的算法和行为,不同的场景下可以相互替换。策略模式是开闭原则的体现,开闭原则讲的是一个软件实体应该对扩展开放对修改关闭。策略模式在新的策略增加时,不会影响其他类的修改,增加了扩展性,也就是对扩展是开放的;对于场景来说,只依赖于抽象,而不依赖于具体实现,所以对修改是关闭的。策略模式的认识可以借助《java与模式》一书中写到诸葛亮的锦囊妙计来学习,在不同的场景下赵云打开不同的锦囊,便化险为夷,锦囊便是抽象策略,具体的锦囊里面的计策便是具体的策略角色,场景就是赵云,变化的处境

选择具体策略的条件。

 

策略模式在程序设计中也很常用,在板桥(banq)的博客里有篇文章叫 “你还在用if else吗?”
http://www.jdon.com/artichect/ifelse.htm”讲的很好,策略模式不但是继承的代替方案而且能很好地解决if else问题,下面举个实例来说明,怎么使用策略模式。

需求如下:

某支付系统接入以下几种商户进行充值:易宝网易,快线网银,19pay手机支付,支付宝支付,骏网一卡通,由于每家充值系统的结算比例不一样,而且同一家商户的不同充值方式也有所不同,具体系统情况比较复杂,像支付宝既有支付宝账号支付和支付宝网银支付等这些暂时不考虑,为了讲述策略模式这里简单描述,假如分为四种,手机支付,网银支付,商户账号支付和点卡支付。因为没个支付结算比例不同,所以对手续费低的做一些优惠活动,尽可能让用户使用手续费低的支付方式来充值,这样降低渠道费用,增加收入,具体优惠政策如下:

①网银充值,8.5折;

②商户充值,9折;

③手机充值,没有优惠;

④点卡充值,收取1%的渠道费;

对于一个新手的代码如下:

package strategy;

public class Example {

	/**
	 * 
	 *作者:alaric
	 *时间:2013-8-5上午11:00:06
	 *描述:计算用户所付金额
	 */
	public Double calRecharge(Double charge ,RechargeTypeEnum type ){
		
		if(type.equals(RechargeTypeEnum.E_BANK)){
			return charge*0.85;
		}else if(type.equals(RechargeTypeEnum.BUSI_ACCOUNTS)){
			return charge*0.90;
		}else if(type.equals(RechargeTypeEnum.MOBILE)){
			return charge;
		}else if(type.equals(RechargeTypeEnum.CARD_RECHARGE)){
			return charge+charge*0.01;
		}else{
			return null;
		}

	}
	
}

 

package strategy;

public enum RechargeTypeEnum {

    E_BANK(1, "网银"),
	
    BUSI_ACCOUNTS(2, "商户账号"),
    
    MOBILE(3,"手机卡充值"),
    
    CARD_RECHARGE(4,"充值卡")
	;
    
	/**
	 * 状态值
	 */
	private int value;
	
	/**
	 * 类型描述
	 */
	private String description;
	
	
	
	private RechargeTypeEnum(int value, String description) {
		this.value = value;
		this.description = description;
	}
		
	public int value() {
		return value;
	}
	public String description() {
		return description;
	}
	

    public static RechargeTypeEnum valueOf(int value) {
        for(RechargeTypeEnum type : RechargeTypeEnum.values()) {
            if(type.value() == value) {
                return type;
            }
        }
        return null; 
    }
}

 可以看出上面四种不同的计算方式在一个方法内部,不利于扩展和维护,当然也不符合面向对象设计原则。对以上的代码利用策略模式进行修改,类图如下:

 


 实例代码如下:

 

package strategy.strategy;

import strategy.RechargeTypeEnum;

/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:03:17
 *描述:策略抽象类
 */
public interface Strategy {

	/**
	 * 
	 *作者:alaric
	 *时间:2013-8-5上午11:05:11
	 *描述:策略行为方法
	 */
	public Double calRecharge(Double charge ,RechargeTypeEnum type );
}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;
/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:14:23
 *描述:网银充值
 */
public class EBankStrategy implements Strategy{

	@Override
	public Double calRecharge(Double charge, RechargeTypeEnum type) {
		return charge*0.85;
	}

	

}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;
/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:14:08
 *描述:商户账号充值
 */
public class BusiAcctStrategy implements Strategy{

	@Override
	public Double calRecharge(Double charge, RechargeTypeEnum type) {
		// TODO Auto-generated method stub
		return charge*0.90;
	}

}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;
/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:14:43
 *描述:手机充值
 */
public class MobileStrategy implements Strategy {

	@Override
	public Double calRecharge(Double charge, RechargeTypeEnum type) {
		// TODO Auto-generated method stub
		return charge;
	}

}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;
/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:13:46
 *描述:充值卡充值
 */
public class CardStrategy implements Strategy{

	@Override
	public Double calRecharge(Double charge, RechargeTypeEnum type) {
		return charge+charge*0.01;
	}

}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;

/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:03:38
 *描述:场景类
 */
public class Context {

	private Strategy strategy;
	
	public Double calRecharge(Double charge, Integer type) {
		strategy = StrategyFactory.getInstance().creator(type);
		return strategy.calRecharge(charge, RechargeTypeEnum.valueOf(type));
	}

	public Strategy getStrategy() {
		return strategy;
	}

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
	
}

 

package strategy.strategy;

import java.util.HashMap;
import java.util.Map;

import strategy.RechargeTypeEnum;
/**
 * 
 *作者:alaric
 *时间:2013-8-5上午11:31:12
 *描述:策略工厂 使用单例模式
 */
public class StrategyFactory {

	private static StrategyFactory factory = new StrategyFactory();
	private StrategyFactory(){
	}
	private static Map<Integer ,Strategy> strategyMap = new HashMap<>();
	static{
		strategyMap.put(RechargeTypeEnum.E_BANK.value(), new EBankStrategy());
		strategyMap.put(RechargeTypeEnum.BUSI_ACCOUNTS.value(), new BusiAcctStrategy());
		strategyMap.put(RechargeTypeEnum.MOBILE.value(), new MobileStrategy());
		strategyMap.put(RechargeTypeEnum.CARD_RECHARGE.value(), new CardStrategy());
	}
	public Strategy creator(Integer type){
		return strategyMap.get(type);
	}
	public static StrategyFactory getInstance(){
		return factory;
	}
}

 

package strategy.strategy;

import strategy.RechargeTypeEnum;

public class Client {

	/**
	 * 作者:alaric 时间:2013-8-5上午11:33:52 描述:
	 */
	public static void main(String[] args) {

		Context context = new Context();
		// 网银充值100 需要付多少
		Double money = context.calRecharge(100D,
				RechargeTypeEnum.E_BANK.value());
		System.out.println(money);

		// 商户账户充值100 需要付多少
		Double money2 = context.calRecharge(100D,
				RechargeTypeEnum.BUSI_ACCOUNTS.value());
		System.out.println(money2);

		// 手机充值100 需要付多少
		Double money3 = context.calRecharge(100D,
				RechargeTypeEnum.MOBILE.value());
		System.out.println(money3);

		// 充值卡充值100 需要付多少
		Double money4 = context.calRecharge(100D,
				RechargeTypeEnum.CARD_RECHARGE.value());
		System.out.println(money4);
	}

}

运行结果:

 

85.0

90.0

100.0

101.0

从上面类图和代码可以看出,策略模式把具体的算法封装到了具体策略角色内部,增强了可扩展性,隐蔽了实现细节;它替代继承来实现,避免了if-else这种不易维护的条件语句。当然我们也可以看到,策略模式由于独立策略实现,使得系统内增加了很多策略类;对客户端来说必须知道兜友哪些具体策略,而且需要知道选择具体策略的条件。


设计模式系列目录:

  • 大小: 13.4 KB
  • 大小: 36.9 KB
11
9
分享到:
评论
29 楼 based 2013-10-15  
怎么感觉这个例子用模板方法模式更好。
28 楼 zzq19860626 2013-08-08  
zzq19860626 写道

再扯个蛋。很久以前就听人说,或者从书里看来的:设计模式就是内功心法,xxoo是招式的说法。当时就觉得不赞同,然后随着年纪越来越大,越坚定的认为:设计模式才是招式。 我这么说肯定很多人不赞同,就当我放屁。

设计模式不是方法学方法论,是gof对以往面向对象程序设计经验的总结,只有深刻理解了,在设计开发系统的时候自然利用了才是对的,如果死搬硬套,可能适得其反。所以理解思想很重要。
27 楼 hardPass 2013-08-08  
zzq19860626 写道

忘了说了,目前来说个人觉得用国语写的设计模式中板桥的和闫宏的还是比较好的,觉得他们两人面向对象设计思想已经很高的境界了,毕竟是前辈。所以一向很敬佩他们,对jdon的文章不能说是乱哄哄的吧。


请原谅我的不敬,我从来都是妄语,说错了也不太在乎,有人指出了最好,能进步。

另外解释下为什么说那篇文章“乱哄哄”:

题目是:“你还在用if else吗?”非常吸引眼球。再看其文中的标题“if else替代者”,相信这句话也给很多人造成了误解:误以为是要替代if-else。实际仔细看文章,特别是对“策略模式”的描述,根本不是要"去 if-else",而是在哪里用"if-else"的问题,或者这么说:把"if-else"和具体的行为(Strategy)分离。
摘录下:
引用
策略模式 
  当你面临几种算法或者公式选择时,可以考虑策略模式,传统过程语言情况是:从数据库中读取算法数值,数值1表示策略1,例如保存到数据库;数值为2表示策略2,例如保存到XMl文件中。这里使用if else作为策略选择的开关。



再扯个蛋。很久以前就听人说,或者从书里看来的:设计模式就是内功心法,xxoo是招式的说法。当时就觉得不赞同,然后随着年纪越来越大,越坚定的认为:设计模式才是招式。 我这么说肯定很多人不赞同,就当我放屁。
26 楼 zzq19860626 2013-08-08  
蓝色毒箭蛙 写道
Kevin12 写道
画图工具好像是rational rose 吧

有可能吧。

别猜了我不是说了 是EA吗,全称:Enterprise Architect
25 楼 蓝色毒箭蛙 2013-08-08  
Kevin12 写道
画图工具好像是rational rose 吧

有可能吧。
24 楼 zzq19860626 2013-08-08  
zzq19860626 写道
hardPass 写道
人家所说的“eliminate conditional statements”是consquence,不是intent。

然后请再仔细理解,不是说在所有代码中去if-else,而是把行为分解,最终在每个独立的、可替换的小行为中没有if-else。

实际上在选择不同的策略的时候,即在选择调用哪一种Strategy实现类的时候,依然是可以用if-else的。 即Context在setStrategy的时候,常用到if-else。

如果你一定要去if-else,请用面向过程的方法--责任链模式。

lz,你在引用那个jdon的文章的时候,不要断章取义,虽然那篇文章也乱轰轰的


首先感谢hardPass发表自己的意见看法,当然更希望大家都来讨论学习。
我先说下我写java设计模式笔记的时候参考了以下书籍:
1、《Design Pattern Elements of Reusable Object-Oriented Software》
2、《Design Pattern Elements of Reusable Object-Oriented Software》翻译版
3、《java与模式》
4、《易学设计模式》很老的书了
5、jdon的相关文档
6、其他网络文章
个人理解能力有限,这里举例的代码都是当时想出来的,也就没有什么缜密性可言了,如果写的有误请大家见谅,个人只希望大家能真正理解设计模式,也不希望误人弟子。
我一直所说的是策略模式可以代替一些if-else语句,当然不只是else-if。模式的学习举例和在实际项目中使用还有很大的差别的,这些都是活的不是死的。可以多查查看看GOF他们的意思,当然不同的人理解的可能也不一样。不论哪种做法、哪种模式达到我们的目的就可以了。你看多了了解多了,发现很多模式很接近,很相似,只是用意使用场合不同而已,说不管哪一种都是面向对象设计原则的体现而已。
最后还是很欢迎大家拍砖的~

忘了说了,目前来说个人觉得用国语写的设计模式中板桥的和闫宏的还是比较好的,觉得他们两人面向对象设计思想已经很高的境界了,毕竟是前辈。所以一向很敬佩他们,对jdon的文章不能说是乱哄哄的吧。
23 楼 zzq19860626 2013-08-08  
hardPass 写道
人家所说的“eliminate conditional statements”是consquence,不是intent。

然后请再仔细理解,不是说在所有代码中去if-else,而是把行为分解,最终在每个独立的、可替换的小行为中没有if-else。

实际上在选择不同的策略的时候,即在选择调用哪一种Strategy实现类的时候,依然是可以用if-else的。 即Context在setStrategy的时候,常用到if-else。

如果你一定要去if-else,请用面向过程的方法--责任链模式。

lz,你在引用那个jdon的文章的时候,不要断章取义,虽然那篇文章也乱轰轰的


首先感谢hardPass发表自己的意见看法,当然更希望大家都来讨论学习。
我先说下我写java设计模式笔记的时候参考了以下书籍:
1、《Design Pattern Elements of Reusable Object-Oriented Software》
2、《Design Pattern Elements of Reusable Object-Oriented Software》翻译版
3、《java与模式》
4、《易学设计模式》很老的书了
5、jdon的相关文档
6、其他网络文章
个人理解能力有限,这里举例的代码都是当时想出来的,也就没有什么缜密性可言了,如果写的有误请大家见谅,个人只希望大家能真正理解设计模式,也不希望误人弟子。
我一直所说的是策略模式可以代替一些if-else语句,当然不只是else-if。模式的学习举例和在实际项目中使用还有很大的差别的,这些都是活的不是死的。可以多查查看看GOF他们的意思,当然不同的人理解的可能也不一样。不论哪种做法、哪种模式达到我们的目的就可以了。你看多了了解多了,发现很多模式很接近,很相似,只是用意使用场合不同而已,说不管哪一种都是面向对象设计原则的体现而已。
最后还是很欢迎大家拍砖的~
22 楼 StrongZhu 2013-08-08  
hardPass 写道
StrongZhu 写道


请参考我的client端代码
通过完善的接口策略与枚举定义。客户端在使用时并不需要使用if-else判断。

责任链在实际应用过程中较复杂,比较少用。


你的代码是指 StrategyFactory.getStrategy(someEnum)? 如果是这个的话,getStrategy出现if-else,也不算很平常的事情。

还有,责任链在实际应用过程中较复杂?比较少用?
Filter链,工作流,validate链,logger,等等,非常常见


责任链的话我表述有误,是我在日常工作中应用较少。
通常碰到类似问题,我还是会以策略模式的变种加以实现。感觉上一个调度排序加上一组实现策略会更加清晰。

代码方面,有关消除if else,本人惯用套路如下:
1、识别业务场景,生成枚举
2、为每个枚举定义一个单独的策略实现
3、采用通用工厂管理整个项目的所有策略实现,内部通常用map管理枚举至策略实现的映射。
4、在client端,判断出枚举实例
5、根据枚举实例从工厂获取对应的策略,并调用方法。

整个过程中,唯一需要存在if else的地方是4。
但相比较处理前的代码,通常圈复杂度就会有大规模的下降。
21 楼 闫老三 2013-08-08  
楼主写的真不错
20 楼 hardPass 2013-08-08  
StrongZhu 写道


请参考我的client端代码
通过完善的接口策略与枚举定义。客户端在使用时并不需要使用if-else判断。

责任链在实际应用过程中较复杂,比较少用。


你的代码是指 StrategyFactory.getStrategy(someEnum)? 如果是这个的话,getStrategy出现if-else,也不算很平常的事情。

还有,责任链在实际应用过程中较复杂?比较少用?
Filter链,工作流,validate链,logger,等等,非常常见
19 楼 StrongZhu 2013-08-08  
hardPass 写道
人家所说的“eliminate conditional statements”是consquence,不是intent。

然后请再仔细理解,不是说在所有代码中去if-else,而是把行为分解,最终在每个独立的、可替换的小行为中没有if-else。

实际上在选择不同的策略的时候,即在选择调用哪一种Strategy实现类的时候,依然是可以用if-else的。 即Context在setStrategy的时候,常用到if-else。

如果你一定要去if-else,请用面向过程的方法--责任链模式。

lz,你在引用那个jdon的文章的时候,不要断章取义,虽然那篇文章也乱轰轰的



实际上在选择不同的策略的时候,即在选择调用哪一种Strategy实现类的时候,依然是可以用if-else的。 即Context在setStrategy的时候,常用到if-else。

请参考我的client端代码
通过完善的接口策略与枚举定义。客户端在使用时并不需要使用if-else判断。

责任链在实际应用过程中较复杂,比较少用。
18 楼 hardPass 2013-08-08  
人家所说的“eliminate conditional statements”是consquence,不是intent。

然后请再仔细理解,不是说在所有代码中去if-else,而是把行为分解,最终在每个独立的、可替换的小行为中没有if-else。

实际上在选择不同的策略的时候,即在选择调用哪一种Strategy实现类的时候,依然是可以用if-else的。 即Context在setStrategy的时候,常用到if-else。

如果你一定要去if-else,请用面向过程的方法--责任链模式。

lz,你在引用那个jdon的文章的时候,不要断章取义,虽然那篇文章也乱轰轰的

17 楼 zzq19860626 2013-08-08  
hardPass 写道
另外,策略模式的本质也不是去if-else

策略模式的用意不是去掉if-else,但是在大量条件语句分支的时候就可以使用策略模式来解耦简化你的代码:
GOF设计模式--策略模式 使用性描述:
Use the Strategy pattern when
·  many related classes differ only in their behavior. Strategiesprovide a
way to configure a class withone of many behaviors.
·  you need different variants of an algorithm. For example, you might
definealgorithms reflecting different space/time trade-offs.Strategies
can be used when thesevariants areimplemented as aclasshierarchy of
algorithms [HO87].
·  an  algorithm  uses  data  that  clients  shouldn't  know  about.  Use  theStrategy
pattern to avoid exposingcomplex, algorithm-specific datastructures.
·  a class defines many behaviors, and these appear as multipleconditional
statements in its operations. Instead of manyconditionals, move related
conditional branches intotheir ownStrategy class.


GOF设计模式--策略模式 效果第三点如下描述:
Strategies eliminate conditional statements.The Strategy pattern offers
an alternative to conditional statements forselecting desired behavior.
When  different  behaviors  are  lumped  into  oneclass,  it's  hard  to  avoid  using
conditional statementstoselecttheright behavior. Encapsulatingthe
behavior in separate Strategyclasseseliminates these conditional
statements.

For  example,  without  strategies,  the  code  for  breakingtext  into  lines  could
look like
void Composition::Repair () {
switch (_breakingStrategy) {
case SimpleStrategy:
ComposeWithSimpleCompositor();
break;
case TeXStrategy:
ComposeWithTeXCompositor();
break;
// ...
}
// merge results with existing composition, if necessary
}
The Strategypattern eliminates this case statement by delegating
thelinebreakingtask to aStrategy object:
void Composition::Repair () {
_compositor->Compose();
// merge results with existing composition, if necessary
}
DesignPatterns:Elements of Reusable Object-OrientedSoftware
353
Code containingmany conditionalstatements often indicatestheneed to
applytheStrategy pattern.
16 楼 zzq19860626 2013-08-08  
StrongZhu 写道
我的client端代码最后大概会是
ISomeStrategy strategy = StrategyFactory.getStrategy(someEnum);
strategy.doSomeThing(100D);

StrategyFactory是公用的,不需要每套策略实现一个Factory。

很高兴跟你讨论,你说的有几点比较赞成,既然用枚举了,就不应该去取值来用,
还有就是final的规范问题。当然这些代码也是实例性的,个人也是学习阶段,听听大家的讨论多一些想法,领教了。
15 楼 hardPass 2013-08-08  
另外,策略模式的本质也不是去if-else
14 楼 hardPass 2013-08-08  
把问题复杂化,未必是好事
13 楼 StrongZhu 2013-08-07  
我的client端代码最后大概会是
ISomeStrategy strategy = StrategyFactory.getStrategy(someEnum);
strategy.doSomeThing(100D);

StrategyFactory是公用的,不需要每套策略实现一个Factory。
12 楼 StrongZhu 2013-08-07  
zzq19860626 写道
StrongZhu 写道
支几招:
1、RechargeTypeEnum.E_BANK.value()这样的用法不可取,接口部分全部使用枚举,除非最后转储,不然就枚举到底吧。试试EnumMap或者Map<RechargeTypeEnum, Strategy >
2、考虑一下一个大型项目内如果出现20套以上这样的枚举,而且每个枚举有200个以上实现时候的管理方式。
3、在第二步的基础上再进一步优化,考虑一下如何抽取公共的IStrategy接口以及公共的StrategyFactoryImpl,用于支持20套以上的策略,同时考虑与Spring的整合。

另外代码层面几个小问题
1、建议看一看Eclipse的save action,主要是代码内没final,看的让人别扭。
2、Strategy接口上多了一个无用的枚举

首先感谢你说自己的想法,更欢迎大家来讨论:
1、的确在这里看着这个枚举多余,这里只是简化了的一少部分代码,所以看着无用的,在实际系统中,需要枚举在订单描述中做备注。
2、在大型系统中200个枚举都是有可能的,“而且每个枚举有200个以上实现时候的管理方式。”着半句不是很懂,不论多大的系统,一个枚举的常量值是不可能到达200个的。我这里说下,jdk1.5后增加枚举,是因为枚举更容易使用和管理,所以jdk1.5后提倡使用枚举。
3、个人觉得跟spring整合没什么大的问题,希望能说下你所考虑的问题和解决方法。

另外两个问题: 1、我不太明白  2、上面已经描述过了。
ps:都是个人观点,希望得到高人的指点,不对的地方请谅解。


1、我的意思是这个.value()是多余的,枚举与其他代码的集合部分存在问题。既然定义出了枚举,说明已经识别了正确的业务场景,此时在代码的任何一个地方应尽量使用该枚举驱动,再出现枚举对应的值是不应该的。
2、我习惯使用枚举驱动策略来实现if else的替换,在大型项目中,公共模块部分出现单个枚举200个以上实现是客观存在的,比如多模块要求导出excel,或者批次调度时的步骤等?其管理模式会有较大差异。
3、当有多套策略出现时,在架构层面应该将策略接口再抽一层,同时实现公共的策略工厂,使用枚举驱动策略的创建与获取,此时策略模式会在整个项目层面显示其降低复杂度的巨大优势。同时在这个过程中就会出现spring的整合问题。

4、 Context context = new Context(); 这里的context缺少final,原因是你的save action缺少配置引起。
5、既然是一个策略接口,在其方法上又出现驱动策略的枚举参数,这是多余的。

看到这个帖子是一时手痒,刚好在枚举和策略模式的应用方面也稍有感觉,忍不住拍了个砖
11 楼 wxl24life 2013-08-07  
zzq19860626 写道
StrongZhu 写道
支几招:
1、RechargeTypeEnum.E_BANK.value()这样的用法不可取,接口部分全部使用枚举,除非最后转储,不然就枚举到底吧。试试EnumMap或者Map<RechargeTypeEnum, Strategy >
2、考虑一下一个大型项目内如果出现20套以上这样的枚举,而且每个枚举有200个以上实现时候的管理方式。
3、在第二步的基础上再进一步优化,考虑一下如何抽取公共的IStrategy接口以及公共的StrategyFactoryImpl,用于支持20套以上的策略,同时考虑与Spring的整合。

另外代码层面几个小问题
1、建议看一看Eclipse的save action,主要是代码内没final,看的让人别扭。
2、Strategy接口上多了一个无用的枚举

首先感谢你说自己的想法,更欢迎大家来讨论:
1、的确在这里看着这个枚举多余,这里只是简化了的一少部分代码,所以看着无用的,在实际系统中,需要枚举在订单描述中做备注。
2、在大型系统中200个枚举都是有可能的,“而且每个枚举有200个以上实现时候的管理方式。”着半句不是很懂,不论多大的系统,一个枚举的常量值是不可能到达200个的。我这里说下,jdk1.5后增加枚举,是因为枚举更容易使用和管理,所以jdk1.5后提倡使用枚举。
3、个人觉得跟spring整合没什么大的问题,希望能说下你所考虑的问题和解决方法。

另外两个问题: 1、我不太明白  2、上面已经描述过了。
ps:都是个人观点,希望得到高人的指点,不对的地方请谅解。


@StrongZhu 的第一个建议LZ可能理解的有误。使用枚举没有问题,只是:

Contex下的这个方法 calRecharge(Double charge, Integer type) 的第二个参数声明为 Integer 不如直接用 RechargeTypeEnum 来的清晰

相应的,StrategyFactory 下的 strategyMap 可直接定义为 Map<RechargeTypeEnum, Strategy>

从而不需要在调用时生硬的在枚举后面调用 value() 方法
---

后面他提的两个小问题,
1. 关于 final,我觉得更多的是出于编码规范方面的考虑
2. LZ 定义的 Strategy 接口中的 calRecharge(Double charge, RechargeTypeEnum type) 方法,第二个参数确实是多余的。。。

---
至于@StrongZhu 3点支招里的第二、三点,还请指教了。暂时无思路
10 楼 changtianyise 2013-08-07  
不错,讲解够详细的

相关推荐

    浅析Java设计模式【4】——策略.pdf

    浅析Java设计模式【4】——策略.pdf

    java设计模式之——策略模式

    NULL 博文链接:https://lvwenwen.iteye.com/blog/1456554

    Java设计模式教程-策略模式Java开发Java经验技

    Java设计模式教程——策略模式Java开发Java经验技巧共13页.pdf.zip

    Java设计模式 版本2

    Java设计模式,目录:前言,UML建模技术,深入浅出UML类图,从招式与内功谈起——设计模式概述,面向对象设计原则,工厂三兄弟之简单工厂模式,工厂三兄弟之工厂方法模式,工厂三兄弟之抽象工厂模式,确保对象的唯一...

    java设计模式之——组合模式(结构型模式 )

    NULL 博文链接:https://lvwenwen.iteye.com/blog/1549415

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

    深入浅出设计模式(中文版电子版)

    4.4.2现实中的装饰模式——相架 126 4.4.3C#实例——图书馆中的项目 127 4.4.4Java实例——自定义JButton 131 4.4.5优势和缺陷 133 4.4.6应用情景 134 4.5FacadePattern(外观模式) 134 4.5.1定义 134 4.5.2...

    深入浅出设计模式(中文版)

    4.4.2现实中的装饰模式——相架 126 4.4.3C#实例——图书馆中的项目 127 4.4.4Java实例——自定义JButton 131 4.4.5优势和缺陷 133 4.4.6应用情景 134 4.5FacadePattern(外观模式) 134 4.5.1定义 134 4.5.2...

    java和设计模式ppt教程

    java和设计模式ppt包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...

    设计模式精解 译者:熊节 程序员必看书籍之一 part2

    设计模式精解(Design Patterns Explained) ...如何实现关键模式——Strategy(策略)、Observer(观察者)、Bridge(桥接)、Decorator(装饰)等等。 共同点/变化点分析、设计模式以及它们如何帮助理解抽象类。

    design-pattern-java.pdf

    设计模式趣味学习(复习) 设计模式趣味学习(复习) 设计模式与足球(一) 设计模式与足球(二) 设计模式与足球(三) 设计模式与足球(四) 设计模式综合应用实例 设计模式综合应用实例 多人联机射击游戏 多人...

    Pattern-Decorator-Java:设计模式工作坊——装饰者模式

    策略模式工作坊陈述我们希望扩展在之前的研讨会中开发的保存策略(JSON 和 XML)的功能,添加缓存、加密 (AES) 和操作日志记录服务。 这些服务是可选的,客户可能希望组合这些服务,无论使用哪种保存策略,这些服务...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷6

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    浅谈简单工作流设计——责任链模式配合策略与命令模式的实现

    本文以项目中的一个工作流模块,演示责任链模式、策略模式、命令模式的组合实现!最近在做的一个项目,涉及到的是一个流程性质的需求。关于工程机械行业的服务流程:服务任务流程和备件发运流程。项目之初,需求不是...

    软件设计模式大作业

    java设计模式期末大作业,运用了6种模式,包括简单工厂模式、工厂方法模式、单例模式、门面模式、策略模式、观察者模式,文档包括系统流程,系统类图,各个模式的子类图,源代码,实验截图。绝对完整.

    java高手真经 (UML建模+设计模式+面向服务架构) 卷8

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷3

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

    Java性能调优实战——覆盖80%以上的Java应用调优场景

    避免使用Java序列化14讲多线程之锁优化(下):使用乐观锁优化并行操作16讲多线程调优(下):如何优化多线程上下文切换17讲并发容器的使用:识别不同场景下最优容器21讲深入JVM即时编译器JIT,优化Java编译25讲答疑...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷1

    pattern/src/behavior/strategy //13.1策略模式 pattern/src/behavior/templatemethod //13.2模板方法模式 pattern/src/behavior/observer //13.3观察者模式 pattern/src/behavior/iterator //13.4迭代子模式 ...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷9

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

Global site tag (gtag.js) - Google Analytics