`

读《研磨设计模式》-代码笔记-策略模式-Strategy

阅读更多
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/





/*
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化

简单理解:
1、将不同的策略提炼出一个共同接口。这是容易的,因为不同的策略,只是算法不同,需要传递的参数(如果需要)和返回值(如果有)都是一样的
2、需要用到策略的类,持有这个接口。在计算时,就可以转调策略接口来实现

大体框架是这样:
interface IStrategy {
    double calculatePrice(double primeCost);
}

class Context{
    private IStrategy strategy;     由于这里是面向接口,所有切换策略很方便
    public double caculate(double primeCost) {
        return strategy.caculatePrice(primeCost);
    }
}
……
……

策略模式的缺点也很易见:策略太多,会造成有多个策略类

 */

/**
 * 根据不同的优惠政策计算价格
 * @param primeCost 商品原价
 */
interface IStrategy {
	
	double calculatePrice(double primeCost);
	
}


class NormalCustomerStrategy implements IStrategy {

	public double calculatePrice(double primeCost) {
		System.out.println("对于普通用户,不打折,返回原价:");
		return primeCost;
	}
	
}


class RegularCustomerStrategy implements IStrategy {
	
	public double calculatePrice(double primeCost) {
		System.out.println("对于老客户,打95折:");
		return primeCost * (1 - 0.05);
	}
	
}


//对应策略模式中的Context
class Price {
	
	private IStrategy strategy;
	
	public Price(IStrategy strategy) {
		this.strategy = strategy;
	}
	
	//如果primeCost是作为类Price的一个field,那么给IStrategy的calculatePrice传递参数时候,
	//就是传递整个Price对象了
	public double getRealPrice(double primeCost) {
		return this.strategy.calculatePrice(primeCost);
	}
	
}



/*
 * 作一个扩展:
 * 老客户在打95折的基础上,再便宜10块钱
 * 另外,将商品原价作为Price类的一个field
 * 有两种实现
*/
interface IStrategyB {
	
	//传递整个Context对象
	double calculatePrice(PriceContext priceContext);
	
}


class PriceContext {
	
	private IStrategyB strategy;
	private double primeCost;		//将商品原价作为Price类的一个field
	
	public PriceContext(IStrategyB strategy, double primeCost) {
		this.strategy = strategy;
		this.primeCost = primeCost;
	}
	
	public double getPrimeCost() {
		return this.primeCost;
	}
	
	public double getRealPrice() {
		//这里是把整个Context传递进去了
		return this.strategy.calculatePrice(this);
	}
}


//”老客户打95折“
class RegularCustomerStrategyB implements IStrategyB {

	public double calculatePrice(PriceContext priceContext) {
		double primeCost = priceContext.getPrimeCost();
		return primeCost * (1 - 0.05);
	}
	
}

//”再便宜10块钱“
//1.extends strategy.要额外减少的数据来自strategy
class HappyRegularCustomerStrategyB extends RegularCustomerStrategyB {
	
	private double diff;

	public HappyRegularCustomerStrategyB(double diff) {
		this.diff = diff;
	}
	
	public double calculatePrice(PriceContext priceContext) {
		System.out.println("对老客户实行打折后再优惠的策略。差价来自Strategy:");
		return super.calculatePrice(priceContext) - diff;
	}
}

//2.extends Context.要额外减少的数据来自Price(Context)。这样,所有数据都来自Context,较为统一
class HappyPriceContext extends PriceContext {

	private double diff;
	
	public HappyPriceContext(IStrategyB strategy, double primeCost, double diff) {
		super(strategy, primeCost);
		this.diff = diff;
	}
	
	public double getRealPrice() {
		System.out.println("对老客户实行打折后再优惠的策略。差价来自Context:");
		return super.getRealPrice() - diff;
	}
	
}


/**
 * 书上提到策略模式的一个应用:“容错恢复机制”
 * 正常情况下是一种策略,出错了又是另一种策略
 * 书上给的例子是,记录日志到数据库,若出错了(例如连不上数据库),那先记录到文件中,以后再保存到数据库
 */

interface ILogStrategy {
	
	void log(String message);
	
}

class DatabaseLogStrategy implements ILogStrategy {

	public void log(String message) {
		//模拟出错的情况
		if (message != null && message.length() > 5) {
			int i = 5 / 0;
		}
		System.out.println("将以下日志信息记录到数据库中:" + message);
	}
	
}


class FileSystemLogStrategy implements ILogStrategy {

	public void log(String message) {
		System.out.println("将以下日志信息记录到文件中:" + message);
	}
	
}


//这里策略的选择在Context里实现
class LogContext {
	
	//private ILogStrategy strategy;
	
	public void log(String message) {
		ILogStrategy databaseStrategy = new DatabaseLogStrategy();
		try {
			databaseStrategy.log(message);
		} catch (Exception e) {
			System.out.print("出错了,将日志信息先保存在文件中:");
			ILogStrategy fileStrategy = new FileSystemLogStrategy();
			fileStrategy.log(message);
		}
	}
	
}


//书上最后提到了策略模式和模板模式结合使用的方法:在模板中定义业务算法的“骨架”,具体算法(策略)由子类实现

/**
 * 这个类是用来测试的
 */
public class StrategyPattern {
	
	public static void main(String[] args) {
		//测试打折策略
		double primeCost = 1000.0;
		IStrategy strategy = new NormalCustomerStrategy();
		Price price = new Price(strategy);
		double realPrice = price.getRealPrice(primeCost	);
		System.out.println(realPrice);
		
		strategy = new RegularCustomerStrategy();
		price = new Price(strategy);
		realPrice = price.getRealPrice(primeCost);
		System.out.println(realPrice);
		
		System.out.println();
		
		//测试打折再减差价的策略
		double diff = 10.0;
		HappyRegularCustomerStrategyB happyStrategyB = new HappyRegularCustomerStrategyB(diff);		//差价来自Strategy
		PriceContext priceContext = new PriceContext(happyStrategyB, primeCost);
		realPrice = priceContext.getRealPrice();
		System.out.println(realPrice);
		
		RegularCustomerStrategyB strategyB = new RegularCustomerStrategyB();
		priceContext = new HappyPriceContext(strategyB, primeCost, diff);		//差价来自Context
		realPrice = priceContext.getRealPrice();
		System.out.println(realPrice);
	
		System.out.println();
		
		//测试记录日志
		LogContext logContext = new LogContext();
		logContext.log("hello");
		logContext.log("hellooo");
	}

}



1
2
分享到:
评论

相关推荐

    研磨设计模式-配套源代码

    "研磨设计模式-配套源代码"很显然是一份与学习和理解设计模式相关的资源,其中包含了实际的编程示例。这份压缩包可能包括了多种常见设计模式的实现,如单例模式、工厂模式、观察者模式、装饰器模式等,通过源代码的...

    研磨设计模式-配套源代码.7z

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,其配套源代码包含了许多经典设计模式的实际应用示例。这些源代码可以帮助读者更直观地理解设计模式的原理和使用方法,进一步提升软件开发能力。 设计模式是软件...

    研磨设计模式-配套源代码.rar

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,配套源代码是作者为了帮助读者更好地理解和应用书中介绍的设计模式而提供的实践示例。设计模式是软件开发中经过实践检验的、解决常见问题的模板,它为软件设计...

    研磨设计模式-配套源代码 UTF-8格式

    《研磨设计模式》是一本深入探讨软件设计原则与实践的经典书籍,其配套源代码提供了丰富的实例,帮助读者更好地理解和应用各种设计模式。这个UTF-8格式的压缩包包含了书中介绍的各种设计模式的实现,是学习和研究...

    研磨设计模式-陈臣.epub

    “1.1 设计模式是什么 1.1.1 什么是模式 从字面上理解,模,就是模型、模板的意思;式,就是方式、方法的意思。综合起来,所谓模式就是:可以作为模型或模板的方式或方法。... “研磨设计模式”。 iBooks.

    研磨设计模式--chjavach的博客文章

    本文将深入探讨五个关键的设计模式:单例模式、工厂方法模式、策略模式、命令模式和桥接模式,这些都是Java编程中常用且至关重要的设计原则。 首先,我们来看**单例模式**。单例模式确保一个类只有一个实例,并提供...

    研磨设计模式-陈臣.王斌.扫描高清版PDF

    设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;...

    研磨设计模式-陈臣pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式书-配套源代码(全)

    1:本源代码是《研磨设计模式》一书的配套源代码 2:每个模式的示例源代码放在一个单独的文件夹下,以该模式的英文名称命名 3:每个模式下分成多个example,按照书的示例顺序分别命名为example1、example2.........

    研磨设计模式-陈臣.mobi kindle版

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    设计模式Golang实现《研磨设计模式》读书笔记.zip

    设计模式Golang实现《研磨设计模式》读书笔记Go语言设计模式Go语言设计模式的实例代码创建模式工厂简单模式(Simple Factory)工厂方法模式(工厂方法)抽象工厂模式(Abstract Factory)创建者模式(Builder)原型...

    研磨设计模式-part2

    第17章 策略模式(Strategy) 第18章 状态模式(State) 第19章 备忘录模式(Memento) 第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式...

    研磨设计模式-part4

    第17章 策略模式(Strategy) 第18章 状态模式(State) 第19章 备忘录模式(Memento) 第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式...

    研磨设计模式-part3

    第17章 策略模式(Strategy) 第18章 状态模式(State) 第19章 备忘录模式(Memento) 第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式...

    研磨设计模式源码

    《研磨设计模式源码》是一份非常宝贵的资源,它提供了设计模式的实践代码,帮助开发者深入理解并应用这些模式。设计模式是软件工程中经过长期实践总结出来的一套通用解决方案,它们描述了在特定场景下如何解决常见...

    研磨设计模式 源代码

    《研磨设计模式》是一本深入探讨软件设计模式的经典书籍,源代码包含了书中所讲解的各种设计模式的实际应用示例。设计模式是软件工程中的重要概念,它们是经过反复验证、在特定情境下解决常见问题的有效解决方案。...

    研磨设计模式全部源代码

    这个压缩包“研磨设计模式全部源代码”包含了多种设计模式的实现,这些模式可以帮助开发者写出更可维护、可扩展和可复用的代码。下面将详细讲解其中可能包含的一些重要设计模式及其应用。 1. 工厂模式:这是最简单...

    研磨设计模式带书签完整版228M.7z.001

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式(完整带书签).part2.pdf

    第17章 策略模式(Strategy) 第18章 状态模式(State) 第19章 备忘录模式(Memento) 第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式...

    研磨设计模式PDF

    策略模式(Strategy)定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,让算法的变化独立于使用算法的客户;模板方法模式(Template Method)在抽象类中定义一个操作中的算法骨架,而将一些步骤延迟到...

Global site tag (gtag.js) - Google Analytics