`

读《研磨设计模式》-代码笔记-策略模式-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
分享到:
评论

相关推荐

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

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

    ### 2024年第一季度青岛房地产市场季度简报总结、市场综述

    2024年第一季度,青岛房地产市场经历了显著变化,总体呈现供需双降的趋势。一季度全市商品房新增10,721套,面积约152.04万平方米,同比下降29%;销量为14,936套,面积约200.85万平方米,同比下降38%,成交均价为14,204元/平方米,同比下降2%。土地市场方面,供应总量为39万平方米,同比减少7%,但成交面积为27万平方米,同比增长31%,楼面地价为6,625元/平方米,同比增长253%,土地出让金为17.61亿元,同比增长354%。二手房市场新增挂牌2.9万套,成交13,405套,132.21万平方米,累计挂牌51.70万套,挂牌均价17,800元/平方米。此外,青岛市出台多项政策支持房地产市场平稳健康发展,包括降低房贷利率、优化开发用地土地规划政策、支持房企融资等。这些政策旨在促进市场供需平衡,防止市场大起大落。

    Linux常用命令大全.markdown

    linux常用命令大全

    MATLAB代码,用于模拟具有无限半空间体积导体的电机单元电势(MUP),星号.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    空调销售网站策划案例.doc

    空调销售网站策划案例.doc

    全球6G技术大会2024年以用户为中心的6G接入网技术研究白皮书31页.pdf

    全球6G技术大会2024年以用户为中心的6G接入网技术研究白皮书31页.pdf

    简约专业风格毕业答辩模板47个

    简约专业风格毕业答辩模板是一系列专为追求简洁与高效表达的大学生设计的答辩文档模板,共47个。这些模板融合了经典的设计元素与现代审美,强调信息的清晰传递与视觉的整洁,旨在帮助学生在答辩中以最专业的面貌展示自己的研究成果。 每个模板都具备结构合理的布局,适用于各个学科和研究领域,从人文社科到自然科学,均能满足不同需求。简约风格的设计使得学生能够专注于内容本身,避免冗余信息的干扰,提升答辩的专业性和可信度。此外,模板中合理运用的色彩、字体和图表设计,不仅增强了视觉吸引力,也使信息更易于理解。 通过使用这些简约专业风格的毕业答辩模板,毕业生能够自信地呈现自己的学术成果,提升答辩的整体效果,为成功的学术交流打下坚实基础。这些模板是展示个人研究与风格的理想选择。

    【数据集和模型】ChatGPT文本二分类

    由 Epsilon Luoo 在 HC3-Chinese 的基础上进行了一些细微的修改和清洗

    数字人动作捕捉:MATLAB-Kinect骨骼数据实时插值算法.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    HI3519DV500 配置无线网依赖库以及编译脚本

    HI3519DV500 配置无线网依赖库以及编译脚本

    定制小米8-lineage22.1安卓15-fast功能项目线刷双版root 解锁bl后fast线刷

    资源说明; 1-----刷写前提是手机必须解锁bl先。而且会在fast模式刷写固件 2-----刷写方法与官方刷写步骤一样 3-----此固件为定制初始固件。可以在fast模式刷写 4-----属于适配固件。也许有个别bug。不接受请勿下载 5-----需要一定的刷机常识与动手能力的友友刷写。 6-----资源有可复制性。下载后不支持退。请知悉 7-----定制其他需求可以在csdn私信博主 博文参阅:https://csdn9.blog.csdn.net/article/details/143058308

    【机械臂路径规划】基于matlab快速探索随机树RRT和概率路网PRM串联机械臂路径规划【含Matlab源码 13167期】.zip

    Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    世邦魏理仕:2021年西安房地产市场回顾与2022年展望.pdf

    世邦魏理仕:2021年西安房地产市场回顾与2022年展望

    Android Studio 2022.1.1和java编程语言yinyuebofangqi.zip

    Android Studio 2022.1.1和java编程语言yinyuebofangqi

    C知道对话分享图片下载

    C知道对话分享图片

    png-jpg-gif-webp-tiff等图片压缩工具基于nodejs的实现

    png-jpg-gif-webp-tiff等图片压缩工具基于nodejs的实现,绿色本地免安装,解压后运行exe文件,将图片文件或者包含图片的文件夹拖拽到软件界面即可压缩

    派对屋A1效果器电脑调音软件

    我们要了解什么是DSP(Digital Signal Processing)。DSP即数字信号处理,是一种利用数字计算方法对信号进行分析、变换和操作的技术。在汽车音响领域,DSP被广泛应用于改善音质,通过调整频率响应、延时、相位和增益等参数,使声音更加均衡、立体。 惠威是一款数字信号处理器,适用于那些希望升级原车音响系统但预算有限的用户。它通常拥有多个输入和输出接口,可以连接到汽车的音频源和扬声器,通过软件进行调音,使得声音能够适应不同的驾驶环境和听音偏好。 ,集成了先进的噪声抑制技术和强大的功率放大器,旨在为发烧友级别的车载音响系统提供卓越的性能。用户可以通过软件对整个系统的每一个细节进行优化,包括主动分频、时间校正等,以达到Hi-Fi级别的音乐享受。

    通信工程分包合同.docx

    通信工程分包合同.docx

    demo1(1).py

    demo1(1).py

    金融量化交易:MATLAB_构建多因子选股模型的完整开发指南.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

Global site tag (gtag.js) - Google Analytics