深入浅出设计模式之策略模式

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

分析
• 上面我们采用继承的来解决程序的开放性 和可扩充性;遇到了问题;为什么会这样
• 因为超类作为所有类的父类;拥有所有子类 的共性;但未来会出现什么子类;无从得知; 因此;无法确定哪些是共性方法和共性属性
ቤተ መጻሕፍቲ ባይዱ
继承
• 继承本是为了代码的复用;节省子类的代码 • 但由于未来的不确定性;无法预知子类的多
产生一个新的飞行类
• public class FlyRocketPowered implements FlyBehavior
• public void fly • System out printlnI am flying with
rocket ; •
动态改变行为
Duck model = new ModelDuck; model performFly; model setFlyBehaviornew FlyRocketPowered;
少 • 继承必须有父类和子类;确定父类的属性和
方法很关键
继承的问题
• 代码在多个子类出现不必要的重复 • 无法事先预知所有的子类的所有行为 • 改变父类;会同时改变子类
采用接口
• 接口在Java中是一个非常重要的概念 • Java不支持多继承;但一个类可以实现多个
接口 • 采用接口覆盖鸭子飞和叫的方法;每一个会
• 优秀的OO设计必须具备可复用;可扩充;可 维护的特性
• 模式可以让我们建造更好的质量的软件 • 模式也可以认为是历经考验的OO设计经验
本章要点
• 模式不是具体的代码;是解决问题的思想 • 模式允许软件改变;但改变对软件影响减小 • 系统中变化的部分进行封装 • 模式让高级开发者具有共同语言
– 需求改变 – 平台改变 – 数据改变
程序设计原则
• 找出应用中可能需要变化之处;将其独立出 来;把它们和无需变化的代码分割开;分而治 之
• 当需求改变时;代码需要改变;这部分是可变 的;从而区分出那些是需要改变的;哪些是稳 定的代码
• 上面的例子中;duck类中;fly;quack方法会随 着duck的不同而改变;因此提取出来
Cat
makeSound() { meow() ;} meow(){ 喵喵叫』
Dog d= new Dog d bark;
Animal animal = new Dog; animal makeSound;
a = getAnimal; a makeSound;
实现鸭子的飞行行为
<<interface>> FlyBehavior
• 采用行话可以节省很多时间;行话的信息量 大
• 在软件行业;设计所采用的各种模式就是设 计者之间的行话
使用共享模式的好处
• 减少沟通的信息量 • 站的层次较高 • 不易产生误会 • 有利于刚参加工作人的进步
设计模式的使用
• 设计模式的使用首先在于设计者采用设计 模式来对软件进行分析设计
• 设计模式在于如何组织每一个类及类之间 的关系 等级高于库和框架
飞的或会叫的子类实现接口
接口带来的问题
• 接口可以让每一个子类自己实现有特色的 方法
• 子类的代码无法重用;每一个子类都实现接 口;即使子类的行为完全一致;也必须各自实 现
软件编写
• 尽量少修改 • 遇到新情况;希望不修改程序或少修改程序 • 程序必须适应变化;而自身需要稳定 • 最不变的就是变化
• 因该说库和框架也使用了某种设计模式 没 有关于设计模式的库
设计模式和OO原则的和区别
• 了解和掌握OO原则并不能设计出高质量;开 放性好的优质软件
• 设计模式在于可以更好的使用OO原则;设计 出适应变化的软件
• 设计是一门艺术;取舍很重要;不同人即使使 用相同的设计模式;也不一定设计的软件相 同
时间 但增加了后期维护的费用 没有哪一个 软件开发完成后;就一成不变的 • 后期的维护所花费的时间远远大于前期开 发的时间
策略模式
• 定义了算法簇;分别封装起来;让它们之间可 以互相替换;让算法的变化独立于算法的的 使用者
思考迷题 p25
设计模式的使用
• 每一个行业都有自己的行话;软件设计也不 例外
设计模式的入门
策略模式
本章的学习要点
• 了解设计模式的用途和优点 • 掌握设计OO的基本原则 • 理解本章所举的实例
开发实例
• 实例描述:我们要开发一个游戏鸭子;可以 戏水;可以鸣叫 而且;在游戏中可能出现很 多各种各样的鸭子
• 设计:将设置一个鸭子超类;解决所有鸭子 的共有操作;如游泳;鸣叫等;子类实现自己 特殊的操作
绿头鸭
超类;实现共有的东西;将 有特色的东西设为抽象
方法
红头鸭
添加方法
• 如果需要给鸭子添加飞的方法;根据OO
带来的问题
• 超类添加一种方法;必然给所有的子类带来 同样的方法 上述的例子;就是所有的鸭子都 可以飞
• 如何解决这个问题:我们可以采用子类方 法覆盖的方法;如橡皮鸭子不会飞;覆盖橡皮 鸭子飞的方法
Model performFly;
封装了鸣叫行为
封装行为
Duck
封装了飞行行为
FlyBehavior flyBehavior QuackBehavior quackBehavior
Swim Display performFly performBehavior
组合和继承
• 继承是 is a 关系 • 组合是 has a 关系 • 设计原则;多用组合;少用继承 • 继承的优点是代码的复用;节省初次开发的
• 设计时一定要考虑将来的变化;千万不要写 死
• 抽象 • 封装 • 多态 • 继承
OO基础
OO模式
• 策略模式:定义一组算法簇;分别封装起来; 可以互相替换;让算法的变化独立于使用者
OO原则
• 封装变化 • 多用组合;少用继承 • 针对接口编程;不对实现编程
本章要点
• 知道OO;不能保证设计出优质的弹性好的程 序
•我们将duck的fly行为和quack行为分别设计一 个类
fly duck
quack
设计原则
• 针对接口编程;而不是针对实现编程 • 我们利用接口代表每一个行为;如
FlyBehavior QuackBehavior • Duck类不实现这个接口;而是由我们设立的
行为类来实现
<<interface>> FlyBehavior
• 上述的设计;让鸣叫;飞行等行为已经与duck 类无关了;
• 我们增加duck类的行为;不会影响到鸣叫;飞 行等行为
注意的问题
• 刚开始设计程序时;可能不会完全预测将来 的情况;因此;应该使程序保持足够的弹性;以 应付将来的可能的变化
• 事先考虑的面面俱到是不可能的 • 飞行;鸣叫等的动作行为成为一个类是可以
fly()
FlyWithWings fly(){ …}
FlyNoWay fly(){ nothing}
• 设计新的类时;子类使用接口所表示的行为; 实现在行为类中;而不在子类中
• 接口可以实现多态
• 在声明对象变量时;最好用超类型
Animal makeSound()
Dog
makeSound() { bark() ;} Bark(){ 汪汪叫』
产生一个模型鸭
• public class ModelDuck extends Duck
• public ModelDuck • quackBehavior = new Quack; • flyBehavior = new FlyNoWay; • • public void display • System out println"I am a model duck"; •
fly()
FlyWithWings fly(){ …}
FlyNoWay fly(){ nothing}
实现鸭子的鸣叫行为
<<interface>> QuackBehavior
quack()
Quack quack(){ 普通鸭子叫}
Squack quack(){橡皮鸭子叫}
MuteQuack quack(){ nothing}

思考题
• 如果现在有了一种新的玩具duck;它采用螺 旋浆飞行;该如何处理
• 什么类还会用到FlywithWings
设计思想的实现
• 根据前面我们的设计;我们来实现duck类
Duck
FlyBehavior flyBehavior QuackBehavior quackBehavior
performQuack Swim Display
performFlay
public class Duck
QuackBehavior quackBehavior;
public void performQuack quackBehavior quack;
子类的具体实现
public class MallardDuck extends Duck public MallardDuck quackBehavior = new Quack; flyBehavior = new FlyWithWings;
public void display System out pringln;
动态设定行为
• Duck类中加入两个新方法: public void SetFlyBehaviorFlyBehavior fb flyBehavior = fb;
public void SetQuackBehaviorQuackBehavior qb quackBehavior = qb;
相关文档
最新文档