Java与设计模式-策略模式

在实际开发中,可能会遇到这样一个情况,某一功能的实现分为多种算法,这些算法可以认定为策略,在实际操作时选择不同算法或策略进行操作得出最终结果。在实际生活中,这些例子也是举不胜举,例如,商场举行活动,满100元减10元,满200元减30元,满500元减100元等等...这样每消费一笔,根据这一笔钱消费的多少,计算最终应支付的钱对应着不同的算法,这些对应的不同计算方法就可以认定为是不同的策略。在某东购物时,根据不同的用户等级,打折力度也是不同的。

策略模式的UML类图参照下图:

假如没有策略模式,实现某东购物计算最终付款的方法怎样呢?

package com.strategy.demo;

public class NoStrategy {
	/**
	 * 不使用测量模式实现
	 * @param args
	 */
	private static final int NOCARDUSER=1;
	private static final int IRONCARDUSER=2;
	private static final int GOLDCARDUSER=3;

	public static void main(String[] args) {
		NoStrategy NoStrategy1=new NoStrategy();
		NoStrategy NoStrategy2=new NoStrategy();
		NoStrategy NoStrategy3=new NoStrategy();

		System.out.println("没有卡牌的买家买100元货物最终应付款:"+NoStrategy1.getPrice(100.0, 1));

		System.out.println("铁牌的买家买100元货物最终应付款:"+NoStrategy2.getPrice(100.0, 2));

		System.out.println("金牌的买家买100元货物最终应付款:"+NoStrategy3.getPrice(100.0, 3));

	}

	private double getNoCardPrice(double price){
		 return price;
	}

	private double getIronCardPrice(double price){
		 return price*0.9;
	}

	private double getGoldCardPrice(double price){
		 return price*0.7;
	}

	private double getPrice(double price,int type){
		 if(type==NOCARDUSER){
			 return getNoCardPrice(price);
		 }else if(type ==IRONCARDUSER){
			 return getIronCardPrice(price);
		 }else if(type ==GOLDCARDUSER){
			 return getGoldCardPrice(price);
		 }else {
			 return 0;
		 }
	}

}

运行实例:

呀,得出正确的答案了,这时你是不是应该满足了呢,应该高枕无忧了呢?突然,主管说要增加钻石用户的类别,钻石用户打六折,这时你怎么实现呢?在里面在增加钻石用户的类型,再增加计算钻石用户的方法,再再最后的判断里增加i f else?  这样的确可以实现功能,但是是不是不满足开闭原则呢?而且随着用户种类的不断增加,你的if  else是不是也越来越长,逻辑也越来越复杂呢?导致系统扩展性和稳定性越来越差呢? 所以,这种方式在实际中显然实不可取的,下面我们看一下如何使用策略模式来实现上面的需求。

1.PriceStrategyInterface 接口,对应UML类图中的Strategy接口:

package com.strategy.demo;

public interface PriceStrategyInterface {

	double calPrice(double price);
}

2.实现类,无卡用户:

package com.strategy.demo;

public class NoCardUserStrategy implements PriceStrategyInterface {
	/**
	 * 无牌买家,原价
	 */

	@Override
	public double calPrice(double price) {
		return price;
	}

}

3.实现类,铁卡用户:

package com.strategy.demo;

public class IronCardUserStrategy implements PriceStrategyInterface {
	/*
	 * 铁牌买家
	 * (non-Javadoc)
	 * @see com.strategy.demo.PriceStrategyInterface#calPrice(double)
	 */

	@Override
	public double calPrice(double price) {
		return price*0.9;
	}

}

4.实现类,金卡用户:

package com.strategy.demo;

public class GoldCardUserStrategy implements PriceStrategyInterface {
	/**
	 * 金牌买家
	 */

	@Override
	public double calPrice(double price) {
		return price*0.7;
	}

}

5.环境对象,用来操作策略:

package com.strategy.demo;

public class PriceContext {
	/**
	 * 操作类
	 */

	PriceStrategyInterface priceStrategyInterface;
	/*
	 * 通过初始化传入对象
	 */
	public PriceContext(PriceStrategyInterface priceStrategyInterface) {
		this.priceStrategyInterface=priceStrategyInterface;
	}
	/*
	 * 通过对象计算返回值
	 */
	public double getPrice(double price){
		 return priceStrategyInterface.calPrice(price);
	}
}

环境对象初始化时,将对应的策略对象传入,然后调用方法返回计算值。

6.构建测试类,测试:

package com.strategy.demo;

public class TestClass {

	public static void main(String[] args) {
		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
		System.out.println("没有卡牌的买家买100元货物最终应付款:"+priceContext.getPrice(100.0));

		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
		System.out.println("铁牌的买家买100元货物最终应付款:"+priceContext2.getPrice(100.0));

		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
		System.out.println("金牌的买家买100元货物最终应付款:"+priceContext3.getPrice(100.0));

	}

}

运行上面的实例:

得到了和第一个方法一样的正确答案,这时我们假如要增加一个钻石买家的种类,怎么实现呢?我们只需要增加一个策略实现类:

package com.strategy.demo;

public class DiamondUserStrategy implements PriceStrategyInterface {

	@Override
	public double calPrice(double price) {
		return price*0.6;
	}

}

然后测试类增加一条钻石类买家的购物:

package com.strategy.demo;

public class TestClass {

	public static void main(String[] args) {
		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
		System.out.println("没有卡牌的买家买100元货物最终应付款:"+priceContext.getPrice(100.0));

		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
		System.out.println("铁牌的买家买100元货物最终应付款:"+priceContext2.getPrice(100.0));

		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
		System.out.println("金牌的买家买100元货物最终应付款:"+priceContext3.getPrice(100.0));

		PriceContext priceContext4=new PriceContext(new DiamondUserStrategy());
		System.out.println("钻石卡的买家买100元货物最终应付款:"+priceContext4.getPrice(100.0));

	}

}

运行实例:

是不是扩展起来特别容易?条理也十分清晰。总结一下策略模式的优点:

1. 结构清晰,使用简单直观;

2. 系统耦合性降低,扩展方便;

3. 操作封装彻底,数据更为安全。(在TestClass中,只知道相关实现类,并不涉及具体计算方法)

当然,策略方式也存在一定的缺点:

由图可以直观的看出,随着策略的不断增加,子类数量变得庞大。

喜欢的朋友关注我和我的微信平台

时间: 2024-11-03 05:32:33

Java与设计模式-策略模式的相关文章

Java常用设计模式——策略模式

     策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化.策略模式使这些算法在客户端调用它们的时候能够互不影响地变化,它是一种行为型模式 策略模式中有三个对象: 环境对象(Context):该类中实现了对抽象策略中定义的接口或者抽象类的引用. 抽象策略对象(Strategy):它可由接口或抽象类来实现. 具体策略对象(ConcreteStrategy):它封装了实现同不功能的不同算法 定义抽象策略对象 package co

设计模式 - 策略模式(Strategy Pattern) 具体解释

策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全部, 禁止转载, 如有须要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间能够相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族须要常常扩展新的功能, 为了使用父类比較灵活的加入子类, 把父类的行为写成接口(interface)的形式; 使用set()方法

设计模式 - 策略模式(Strategy Pattern) 详解

策略模式(Strategy Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权所有, 禁止转载, 如有需要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间可以相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族需要经常扩展新的功能, 为了使用父类比较灵活的添加子类, 把父类的行为写成接口(interface)的形式; 使用set()方法,

24天学会设计模式------策略模式

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.策略模式(Stragegy Pattern) 1.简介 Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略).Strategy模式主要用来平滑地处理算法的切换 . 2.意图 定义一系列的算法,把它们一个个封装起来,并且它们可相互替换.使得算法可独

2.大话设计模式-策略模式

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DesignModel 8 { 9 /// <summary> 10 /// 策略模式 11 /// </summary> 12 public class TacticsModel 13 { 14 //对于

设计模式---策略模式Strategy(对象行为型)

1. 概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理. 2. 应用场景 (1)多个类只区别在表现行为不同,在运行时动态选择具体要执行的行为. (2)需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现. (3)对客户隐藏具体策略(算法)的实现细节,彼此完全独立. 3. 示例 出行旅游:我们可以有几个策略可以考虑:可

设计模式—策略模式

什么是策略模式? 策略模式定义了算法家族,分别封装起来,让它们之间能够相互替换,此模式让算法的变化不会影响到使用算法 的客户. 策略模式是一种定义一系列算法的方法,从概念上看全部这些算法完毕的都是同样的工作,仅仅是实现不同,它可 以以同样的方式调用全部的算法,降低了各种算法类与使用算法之间的耦合. 策略模式的长处? (1)策略模式的Strategy类层为Context类定义了一系列的可供重用的算法和行为.继承有助于析取出这些算法 的公共功能. (2)简化了单元測试(每一个算法都有自己的类,能够通

说说设计模式~策略模式(Strategy)

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(interface or abstract class),多个具体策略对象(implement class )和一个调用策略的入口组成. 何时能用到它? 对于UI来说,可能一个功能会有多种实现方式,而且实现方式可能还会有扩展,例如,一个ATM机,它目前支持工行,建行,家行,以后可能又出现了占占银行,而这时,ATM

head first 设计模式 策略模式

HEAD FIRST:策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 设计模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于它的客户而变化. 大话设计模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 使用这个模式的原因: 用许多的算法对一类进行计算.那么如果把这些算法强行编码到这个类当中.其实是不可取的.因为很多时候下不同的情况下使用不同的算