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

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设计模式之——策略模式

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式主要通过定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。这种模式的核心是策略...

    Java设计模式源代码——自己看pdf写的

    以上只是部分Java设计模式的介绍,实际的“DesignPatterns”压缩包可能包含了这些模式的源代码实现,通过阅读和学习这些代码,开发者可以更好地理解和运用设计模式,提升代码质量。同时,结合博主提供的博客链接,...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    《Java设计模式》刘伟 课后习题及模拟试题答案.rar

    《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...

    设计模式浅谈1——策略模式

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件工程中,我们经常遇到需要根据不同条件或场景动态地改变算法的情况。策略模式就是为了解决这类问题而诞生的,它允许我们用不同的策略(即算法)...

    设计模式-Java语言中的应用(pdf)

    通过深入学习《设计模式——Java语言中的应用》,开发者能够更好地理解和应用这些模式,从而编写出更加高效、可扩展的Java程序。无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的...

    JAVA学习——集合与三层设计模式

    在Java编程语言中,集合和三层设计模式是两个非常重要的概念,对于开发高效、可维护的软件系统至关重要。本文将详细探讨这两个主题。 首先,我们来了解Java中的集合。Java集合框架是Java SE API的一个核心部分,它...

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

    在"Java设计模式教程——策略模式Java开发Java经验技巧共13页.pdf.zip"这份资料中,可能会详细讲解如何在实际项目中应用策略模式,包括但不限于以下内容: 1. 策略模式的基本结构和工作原理。 2. 如何定义策略接口...

    java设计模式经典教程

    ### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...

    Java与模式——源码

    《Java与模式——源码》这个主题涉及到的是Java编程语言中的设计模式应用,以及如何通过源代码来理解和学习这些模式。设计模式是软件工程中的一种最佳实践,它们是解决常见问题的经验总结,使得代码更易读、易维护、...

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

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

    java设计模式

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

    JAVA设计模式.chm

    本资源“JAVA设计模式.chm”聚焦于一种重要的设计模式——工厂模式。工厂模式是面向对象设计中的一种经典模式,它在Java程序中扮演着核心角色。 工厂模式的核心思想是提供一个创建对象的接口,但让实现这个接口的类...

    java 设计模式幽默解读

    "大牛解读Java设计模式.pdf"这本书籍,作为这个主题的载体,很可能是由资深专家撰写,用生动的语言和实例帮助读者理解抽象的设计概念,从而提升他们的编程技能。无论你是初学者还是有经验的开发者,都能从中受益匪浅...

    深入浅出设计模式一——Duck设计(策略模式)

    《深入浅出设计模式一——Duck设计(策略模式)》 在软件开发中,设计模式是一种被广泛接受并重复使用的解决方案,它针对特定问题提供了一种通用的、可复用的设计方案。策略模式是其中一种行为设计模式,用于定义...

    java设计模式--策略模式

    Java设计模式——策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。策略模式定义了一族算法,并将每一个算法封装起来,使它们可以互相替换。这种模式让算法的变化独立于使用算法的客户。 在Java中,...

    java设计模式(23种设计模式大全)

    根据提供的标题、描述以及部分内容,本文将深入探讨Java设计模式,并着重分析23种常见的设计模式,以帮助Java程序员更好地理解和应用这些模式。 ### Java设计模式概述 Java设计模式是面向对象软件设计的一种通用可...

Global site tag (gtag.js) - Google Analytics