简单工厂模式 策略模式【设计模式】【学习总结】
来源:互联网 发布:windows app 编辑:程序博客网 时间:2024/04/30 03:14
感觉不懂设计模式的话是不靠谱的,面试的时候面试官问“了解设计模式吗?”,如果回答说“只知道单例模式和工厂模式”感觉就跟没吃过猪肉只见过猪跑一样。所以决心踏踏实实地看一下。书架上有本《大话设计模式》,以前只是简单的翻了一下,现在拿起来好好读,并且认真做一下笔记。声明,文中部分观点来自于原书作者,此处仅用于摘录备忘和学习交流。
简单工厂模式
一句话概括我理解的简单工厂模式就是:给出一个条件,返回不同的实例。当然,这些实例都继承了同样的类或实现了同样的接口,总之就是有同样的功能(方法)。
简单例子
父类
/** * 水果类 */public abstract class Fruit { /** * 味道 * 输出水果的味道 */ public abstract void taste();}
子类
/** * 橘子类 */public class Orange extends Fruit { /** * 味道 * 输出橘子的味道 */ @Override public void taste() { System.out.println("橘子是酸的"); }}/** * 香蕉类 */public class Banana extends Fruit { /** * 味道 * 输出香蕉的味道 */ @Override public void taste() { System.out.println("香蕉没什么味"); }}/** * 西瓜类 */public class Watermelon extends Fruit { /** * 味道 * 输出西瓜的味道 */ @Override public void taste() { System.out.println("西瓜是甜的"); }}
工厂类
/** * 水果工厂类 */public class FriutFactory { private static Fruit fruit; /** * 根据输入条件,生成不同的实例并返回 */ public static Fruit generateFruit(String type) { switch (type) { case "apple": fruit = new Apple(); break; case "orange": fruit = new Orange(); break; case "watermelon": fruit = new Watermelon(); break; default : break; } return fruit; }}
当我们输入不同的条件时将得到不同子类的对象,然后我们将其赋给父类,并且调用父类中的方法时,实际调用的是各子类中重写后的方法。
策略模式
一句话概括我理解的策略模式:封装一系列算法,由一个Context来维护一个策略对象。策略模式下大概分三层,Context+Strategy父类层+Strategy子类层。
简单例子
父类
父类用来定义一系列的算法,为Context提供一系列可供重用的算法和行为。也可以说是接口层。
/** * 计算费用类 */public abstract class CalCharge { /** * 计算需要支付的费用 * @param price 原价 */ public abstract float cal(float price);}
子类
子类继承父类,是各个算法的具体实现。
/** * 打折类 */public class DiscountCalCharge extends CalCharge { /** * 计算打八折后需要支付的费用 * @param price 原价 */ public abstract float cal(float price) { return price * 0.8; }}/** * 满减类 */public class FullCutCalCharge extends CalCharge { /** * 计算优惠后需要支付的费用 * 满300减100 * @param price 原价 */ public abstract float cal(float price) { return price - price / 300 * 100; }}
Context类
Context用来维护一个策略类的实例,其具体实例依赖于传递的参数。
/** * 用来维护一个计算费用类的实例 */public class CalChargeContext { /** 计算费用类实例*/ private CalCharge calCharge = null; /** * 构造方法 */ public CalChargeContext(CalCharge calCharge) { this.calCharge = calCharge; } /** * 计算应该支付的费用 * @param price 原价 */ public float getPrice(float price) { return calCharge.cal(price); }}
在策略模式中,客户端调用时需要传入一个CalCharge的实例来实例化一个CalChargeContext对象,然后调用CalChargeContext对象的getPrice方法来获取结果。对于getPrice实际上调用各个CalCharge子类的cal方法这个过程,客户端是不知道也无须知道的。
但是我们可以发现如下问题:
客户端在使用时需要与两个类来交互,且需要根据不同条件实例化不同的CalCharge的对象,选择具体实现的压力落在了客户端上。该如何改变来把这个职责转移给Context呢?答案很简单,与简单工厂模式结合即可。
简单工厂模式+策略模式
我们只需要修改Context类,将其维护Strategy策略对象时修改为一个简单工厂模式即可。
我们使用上面的例子,修改如下:
Context类
Context用来维护一个策略类的实例,其具体实例依赖于传递的参数。
/** * 用来维护一个计算费用类的实例 */public class CalChargeContext { /** 计算费用类实例*/ private CalCharge calCharge = null; /** * 构造方法 */ public CalChargeContext(String type) { switch (type) { case "discount": calCharge = new DiscountCalCharge(); break; case "fullcut": calCharge = new FullCutCalCharge(); break; default: break; } } /** * 计算应该支付的费用 * @param price 原价 */ public float getPrice(float price) { return calCharge.cal(price); }}
这时候我们在客户端调用的时候需要怎么做呢?
CalChargeContext context = new CalChargeContext("discount");float price = context.getPrice(1000); // 得到结果800context = new CalChargeContext("fullcut");float price = context.getPrice(1000); // 得到结果700
我们可以惊喜的发现在调用时,我们仅需要与CalChargeContext一个类打交道即可。而且判断选择具体实现的职责落到了Context类上,减轻了客户端的压力。
总结
使用简单工厂模式+策略模式结合的方法有如下优点:
- 降低耦合,客户端只需要调用Context即可(策略模式的优点);
- 封装了变化,简化客户端职责,减轻了客户端的压力(简单工厂模式的优点);
- 简化单元测试,每个具体算法实现可以单独进行单元测试(策略模式的优点)。
// 个人学习记录,若有错误请指正,大神勿喷
// sfg1991@163.com
// 2015/5/21
- 简单工厂模式 策略模式【设计模式】【学习总结】
- 设计模式之简单工厂模式和策略模式总结
- 设计模式学习之简单工厂模式和策略模式
- 设计模式--简单工厂模式 策略模式
- 设计模式之简单工厂模式,工厂模式,策略模式
- 大话设计模式学习 策略和简单工厂模式结合
- 【设计模式】策略模式 VS. 简单工厂
- 设计模式:简单工厂与策略模式
- 设计模式之简单工厂模式,工厂模式,抽象工厂模式学习总结
- 设计模式之简单工厂模式,工厂模式,抽象工厂模式学习总结
- 设计模式学习总结之简单工厂模式
- 大话设计模式-----简单工厂模式与策略模式
- 大话设计模式-策略模式与简单工厂模式
- 大话设计模式1 简单工厂模式 策略模式
- 设计模式之策略模式&简单工厂模式
- 设计模式-简单工厂模式和策略模式
- 浅谈设计模式之简单工厂模式与策略模式
- 大话设计模式-策略模式与简单工厂模式
- 在PowerDesigner中设计物理模型1——表和主外键
- QQ互联OAuth2.0 .NET SDK 发布以及网站QQ登陆示例代码
- Asp.net HttpWebRequest和HttpWebResponse发送和接受任何类型数据
- Stream 和 byte[] 之间的转换
- ASP.NET中JSON的序列化和反序列化
- 简单工厂模式 策略模式【设计模式】【学习总结】
- linux系统硬件配置查看方法
- acdsee 15中文版的许可证密钥+激活方法
- JQuery中的DOM动画
- JS,Jquery获取各种屏幕的宽度和高度
- cache共享问题
- T-SQL中的indexof函数
- jquery.cookie.js结合asp.net实现最近浏览记录
- 解构推荐系统:“猜你喜欢”是怎么猜中你的心思