《深入浅出设计模式》读书笔记--策略模式与三个设计原则

本文详细探讨了如何运用设计模式解决实际编程问题,通过模拟鸭子程序,介绍了策略模式的原理及应用,同时展示了如何在角色类中灵活使用策略模式进行武器切换,遵循了设计原则并提供了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从今天开始,学习《深入浅出设计模式》这本书,并每看完一章就自己写些代码来加深理解,并把文中的一些知识写出来,和代码一起更新到博客里。(中文和英文版pdf,另找地址上传,建议英文版,比较清晰)

对于设计模式,先摘抄此书中文版的一句话: 信耶稣的人都要读圣经,而信 OO 的人都要读四人组的《设计模式》

另一句:使用模式的最好方式是:把模式装进脑子,然后在你的设计和已有的应用中,寻找何处可以使用它们。


在第一章,先是以一个模拟鸭子程序开始,一个Duck的父类,有很多个继承Duck类的具体鸭类。目前遇到这样的情况:  

1.       继承,不易知道所有鸭子的公共方法,在父类修改为牵连到所有子类,

 

第一版鸭子程序

 

2.       老板要求增加一个飞方法(fly())时,在父类增加,导致所有鸭子都可飞,有些是塑料鸭子也可以飞了,不妥;

3.      那不在父类增加fly()方法,而是把飞的方法抽象为一接口,让会飞的实体鸭类才实现该接口,但这又导致了重复代码的危险,因为每个实现飞接口的子类都要有相同的飞实现代码,万一以后又要对飞方法的修改,那就要对所有实现了飞接口的子类都修改,仍不妥;

 

4.       最后想出一个办法:增加 FlyBehavior 接口,其中接口中有一个方法,分别是 fly() ,并写相应实现接口的类。

 

 

其中Duck类里的performFly()方法代码(另增加一个设置该类飞行行为的方法setFlyBehavior() ):

	public void performFly() {
		flyBehavior.fly();
	}
	public void setFlyBehavior (FlyBehavior fb) {
		flyBehavior = fb;
	}

到这里,设计已经几乎完成了,如果要更改fly方法,只需增加一个实现FlyBehavior接口的方法,并调用setFlyBehavior,就可以在运行时动态地更改fly方法。

 

 

下面是 提到的设计原则,从上面的代码也可以体现出来:

一. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。(把会变化的部分取出并“封装”起来,使得系统某部分的改变不会影响其它)。

二. 针对接口编程,而不是针对实现编程。

三. 多用组合,少用继承。

 

策略模式的定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

 

接下来是为Design Puzzle里的设计的代码,背景是:

这是一个为动作冒险游戏而设计的程序,其中会用到角色类(Character),角色可以用不同的武器,但一次只能用一种武器,而且在游戏过程中可以更换武器。

背景英文原文 写道
Below you’ll fi nd a mess of classes and interfaces for an action adventure game. You’ll
fi nd classes for game characters along with classes for weapon behaviors the characters
can use in the game. Each character can make use of one weapon at a time, but can
change weapons at any time during the game. Your job is to sort it all out...
 

下面直接贴出答案,自己可以先思考一下。

UML类图为:

character_uml

 

 

鉴于篇幅,只贴部分代码,全部代码见附件:

package chow.hfdp.chapter1.designPuzzle;

//  Generated by StarUML(tm) Java Add-In
//
//  @ Project : Untitled
//  @ File Name : Character.java
//  @ Date : 2011/9/3
//  @ Author : bosshida
//
//

public abstract class Character {
	public WeaponBehavior weapon;
	public void setWeapon(WeaponBehavior weapon){
		this.weapon = weapon;
	}
	
	public abstract void fight();
}
 
package chow.hfdp.chapter1.designPuzzle;

//  Generated by StarUML(tm) Java Add-In
//
//  @ Project : Untitled
//  @ File Name : King.java
//  @ Date : 2011/9/3
//  @ Author : bosshida
//
//

public class King extends Character {
	public void fight() {
		System.out.print("我是国王 ");
		weapon.useWeapon();
	}
}

 

package chow.hfdp.chapter1.designPuzzle;

//  Generated by StarUML(tm) Java Add-In
//
//  @ Project : Untitled
//  @ File Name : WeaponBehavior.java
//  @ Date : 2011/9/3
//  @ Author : bosshida
//
//

public interface WeaponBehavior {
	public void useWeapon();
}
 
package chow.hfdp.chapter1.designPuzzle;

//  Generated by StarUML(tm) Java Add-In
//
//  @ Project : Untitled
//  @ File Name : SwordBehavior.java
//  @ Date : 2011/9/3
//  @ Author : bosshida
//
//

public class SwordBehavior implements WeaponBehavior {
	public void useWeapon() {
		System.out.println("出剑");
	}
}

 

package chow.hfdp.chapter1.designPuzzle;

/**
 * 这是一个为动作冒险游戏而设计的程序,其中会用到角色类(Character),角色可以用不同的武器<br>
 * 但一次只能用一种武器,而且在游戏过程中可以更换武器。这时用到策略模式,并遵守三种设计原则:<br>
 * 1.独立变化并封装(武器更换作为一种Behavior);2.针对接口编程,不是针对实现编程(WeaponBehavior)<br>
 * 为一接口);3.多用组合,少用继承(在Character类里,组合一个weapon对象) <br>
 * 策略模式定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化<br>
 * 独立于使用算法的客户(这里是对使用武器不同而封装)
 * @author bosshida
 * @date 2011-9-3
 */
public class Main {
	public static void main(String[] args) {
		Character king = new King();
		Character troll = new Troll();
		
		king.setWeapon(new BowAndArrowBehavior());
		troll.setWeapon(new AxeBehavior());
		
		king.fight();
		troll.fight();
		
		king.setWeapon(new SwordBehavior());
		king.fight();
	}
}

 

运行结果:

我是国王 拉弓,放箭
我是怪物 挥斧头
我是国王 出剑

 

 

书籍目录 目录 第1章基本概念 1 1.1什么是设计模式 2 1.2设计模式的作用 3 1.3GRASP模式的分类 4 1.4GoF设计模式的分类 4 1.5模式的学习阶段 6 第2章负责任地设计对象——GRASP 9 2.1InformationExpert(信息专家) 11 2.2Creator(创造者) 13 2.3LowCoupling(低耦合) 14 2.4HighCohesion(高内聚) 15 2.5Controller(控制器) 17 2.6Polymorphism(多态) 18 2.7PureFabrication(纯虚构) 19 2.8Indirection(间接) 20 2.9ProtectedVariations(受保护变化) 21 第3章GoF-CreationalDesignPatterns创建型设计模式 23 3.1SimpleFactoryPattern(简单工厂模式) 24 3.1.1定义 24 3.1.2现实例子——国旗生产厂 26 3.1.3C#实例1——电子付款系统 26 3.1.4C#实例2——学校登录系统 29 3.1.5Java实例——手机简单工厂 32 3.1.6优势和缺陷 34 3.1.7应用情景 34 3.2FactoryMethodPattern(工厂方法模式) 35 3.2.1定义 35 3.2.2现实例子——兵工厂 36 3.2.3C#实例——多文档系统 37 3.2.4Java实例——扩展了的手机工厂 41 3.2.5优势和缺陷 44 3.2.6应用情景 44 3.3AbstractFactoryPattern(抽象工厂模式) 45 3.3.1定义 45 3.3.2现实例子——扩展了的兵工厂 48 3.3.3C#实例——大陆生态系统 49 3.3.4Java实例——电脑产品 52 3.3.5优势和缺陷 57 3.3.6应用情景 57 3.4BuilderPattern(建造者模式) 58 3.4.1定义 58 3.4.2现实例子——快餐店 60 3.4.3C#实例——车间造车 61 3.4.4Java实例——建造房屋 65 3.4.5优势和缺陷 69 3.4.6应用情景 70 3.5PrototypePattern(原型模式) 70 3.5.1定义 70 3.5.2现实中的拷贝-粘贴 71 3.5.3C#实例——颜色管理器 72 3.5.4Java实例——简单ToolBar 74 3.5.5ShallowCopyDeepCopy 76 3.5.6优势和缺陷 82 3.5.7应用情景 82 3.6SingletonPattern(单例模式) 82 3.6.1定义 82 3.6.2现?抵械牡ダ??猈indowsTaskManager 83 3.6.3C#实例——负载均衡控制器 84 3.6.4Java实例——系统日志 86 3.6.5DoubleCheckLocking(双检锁) 89 3.6.6优势和缺陷 93 3.6.7应用情景 93 第4章GoF-StructuralDesignPatterns结构型设计模式 95 4.1AdapterPattern(适配器模式) 96 4.1.1定义 96 4.1.2现实中的实例——电脑电源适配器 97 4.1.3C#实例——化学数据银行 98 4.1.4Java实例——清洁系统 102 4.1.5优势和缺陷 104 4.1.6应用情景 104 4.2BridgePattern(桥接模式) 104 4.2.1定义 104 4.2.2现实中的实例——男人的约会 106 4.2.3C#实例——商业对象数据对象 107 4.2.4Java实例——不同系统的图像处理 112 4.2.5优势和缺陷 114 4.2.6应用情景 115 4.3CompositePattern(组合模式) 115 4.3.1定义 115 4.3.2组合模式的现实应用——资源管理器 117 4.3.3C#实例——图形树状对象结构 118 4.3.4Java实例——文档格式化 121 4.3.5优势和缺陷 124 4.3.6应用情景 125 4.4DecoratorPattern(装饰模式) 125 4.4.1定义 125 4.4.2现实中的装饰模式——相架 126 4.4.3C#实例——图书馆中的项目 127 4.4.4Java实例——自定义JButton 131 4.4.5优势和缺陷 133 4.4.6应用情景 134 4.5FacadePattern(外观模式) 134 4.5.1定义 134 4.5.2现实中的实例——顾客服务员 135 4.5.3C#实例——抵押申请审核 136 4.5.4Java实例——冲茶 139 4.5.5优势和缺陷 143 4.5.6应用情景 143 4.6FlyweightPattern(轻量级模式) 144 4.6.1定义 144 4.6.2实例——中游的四国军棋 146 4.6.3C#实例——文档编辑器 147 4.6.4Java实例——装载图像 151 4.6.5优势和缺陷 154 4.6.6应用情景 154 4.7ProxyPattern(代理模式) 154 4.7.1定义 154 4.7.2几个现实中的实例 156 4.7.3C#实例——数学代理 158 4.7.4Java实例——Socket回声 160 4.7.5优势和缺陷 165 4.7.6应用情景 165 第5章GoF-BehavioralDesignPatterns行为型设计模式 167 5.1ChainofResponsibility(责任链模式) 168 5.1.1定义 168 5.1.2现实中的实例——军情的传递 169 5.1.3C#实例——采购分级审批 170 5.1.4Java实例——智能大厦安全系统 174 5.1.5优势和缺陷 178 5.1.6应用情景 178 5.2CommandPattern(命令模式) 179 5.2.1定义 179 5.2.2现实中的实例——餐馆订菜 180 5.2.3C#实例——简单计算器 181 5.2.4Java实例——总开关 185 5.2.5优势和缺陷 189 5.2.6应用情景 189 5.3InterpreterPattern(解释器模式) 190 5.3.1定义 190 5.3.2现实示例——音乐符号 192 5.3.3C#实例——中国金钱大写转换 192 5.3.4Java实例——自定义程序解释器 197 5.3.5优势和缺陷 204 5.3.6应用情景 205 5.4IteratorPattern(迭代器模式) 205 5.4.1定义 205 5.4.2现实示例——电视节目选择器 206 5.4.3C#实例——遍历例子 207 5.4.4Java实例——两个迭代器 211 5.4.5优势和缺陷 213 5.4.6应用情景 214 5.5MediatorPattern(中介者模式) 214 5.5.1定义 214 5.5.2现实示例——机场控制塔 215 5.5.3C#实例——聊天室 216 5.5.4Java实例——多线程通信 220 5.5.5优势和缺陷 223 5.5.6应用情景 223 5.6MementoPattern(备忘录模式) 223 5.6.1定义 223 5.6.2现实示例——音响均衡器 226 5.6.3C#实例——销售目标 226 5.6.4Java实例——多次Undo(取消)操作 231 5.6.5优势和缺陷 236 5.6.6应用情景 236 5.7ObserverPattern(观察者模式) 236 5.7.1定义 236 5.7.2现实例子——拉登现身了 238 5.7.3C#实例——猫和老鼠 238 5.7.4C#实例——股票变化 241 5.7.5Java实例——监控系统 245 5.7.6优势和缺陷 248 5.7.7应用情景 248 5.8StatePattern(状态模式) 248 5.8.1定义 248 5.8.2现实例子——心情好坏 250 5.8.3C#实例——账户分类 250 5.8.4Java实例——汽车的变速档 258 5.8.5优势和缺陷 261 5.8.6应用情景 261 5.9StrategyPattern(策略模式) 261 5.9.1定义 261 5.9.2现实例子——去机场的策略 263 5.9.3C#实例——排序方法 263 5.9.4Java实例——多格式输出 266 5.9.5优势和缺陷 272 5.9.6应用情景 272 5.10TemplateMethodPattern(模板方法模式) 272 5.10.1定义 272 5.10.2现实例子——厨师烹调 274 5.10.3C#实例——数据库连接模板 274 5.10.4Java实例——冒泡排序模板 277 5.10.5优势和缺陷 280 5.10.6应用情景 280 5.11VisitorPattern(访问者模式) 280 5.11.1定义 280 5.11.2现实例子——收银员收银计费 282 5.11.3C#实例——人事评估 283 5.11.4Java实例——维修工程师检查车辆 287 5.11.5优势和缺陷 291 5.11.6应用情??291 第6章模式的综合应用 293 6.1Java实例——扩展的日志记录器 294 6.2C#实例——存储分析器 298 6.3用模式生成程序架构 316 附录1自测题 321 附录2自测题答案 331 参考文献 337
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值