学习:设计模式之策略模式
来源:互联网 发布:淘宝店铺怎么加客服 编辑:程序博客网 时间:2024/05/19 16:33
本文来自www.lanttor.org
会飞的鸭子
经验
把模式装进你的脑子里,然后在你的设计和已有的应用里,寻找何处可以使用它们。以往是代码复用,现在是经验复用。
设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。把会变化的部分取出并“封装”起来,让其他部分不会受到影响。结果如何?代码变化引起的不经意后果变少,系统变得更有弹性。
设计鸭子的行为
我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变。
为了要把这两个行为从Duck类中分开,我们将把它们从Duck类中取出来,建立一组新类来代表每个行为。
从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。
设计原则
针对接口编程,而不是针对实现编程。“这对接口编程”的真正意思是“针对超类型(supertype)编程”。更明确的说:变量的声明类型应该是超类型,通常是一个抽象类,或者是一个接口。如此,只要是具体实现此超类型的类所产生的对象,都可以指定给这个对象。这也意味着,声明类时不用理会以后执行的真正对象类型。
针对实现编程的例子(反面示例):
Dog d = new Dog();
d.bark()
针对接口编程的例子(正面示例):
Animal animal = new Dog();
Animal.makeSound();
更棒的例子(在运行时才指定具体实现的对象):
a = getAnimal();
a.makeSound();
为此,我们有两个接口,FlyBehavior和QuackBehavior,还有它们对应的类,负责实现具体的行为:
整合鸭子的行为
关键在于,鸭子类现在会将飞行和呱呱叫的动作“委托”(delegate)别人处理,而不是使用定义在Duck类(或子类)内的呱呱叫和飞行方法。
1. 首先,在Duck类中加入两个实例变量,分别为"flyBehavior"和"quackBehavior",声明为接口类型。
2. 现在,我们来实现performQuack():
3. 设定flyBehavior与quackBehavior的实例变量。看看MallardDuck类:
测试Duck的代码
Duck.java代码:
package headfirst.strategy;
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void setFlyBehavior (FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
abstract void display();
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
}
FlyBehavior接口代码(FlyBehavior.java):
package headfirst.strategy;
public interface FlyBehavior {
public void fly();
}
QuackBehavior接口代码(QuackBehavior.java):
package headfirst.strategy;
public interface QuackBehavior {
public void quack();
}
MallarDuck.java代码:
package headfirst.strategy;
public class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display() {
System.out.println("I'm a real Mallard duck");
}
}
Quack.java代码:
package headfirst.strategy;
public class Quack implements QuackBehavior {
public void quack() {
System.out.println("Quack");
}
}
FlyWithWings.java代码:
package headfirst.strategy;
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying!!");
}
}
ModelDuck.java代码:
package headfirst.strategy;
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
public void display() {
System.out.println("I'm a model duck");
}
}
FlyNoWay.java代码:
package headfirst.strategy;
public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("I can't fly");
}
}
测试代码MiniDuckSimulator1.java:
package headfirst.strategy;
public class MiniDuckSimulator1 {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}
FlyRocketPowered.java代码:
package headfirst.strategy;
public class FlyRocketPowered implements FlyBehavior {
public void fly() {
System.out.println("I'm flying with a rocket");
}
}
运行测试结果
Quack
I'm flying!!
I can't fly
I'm flying with a rocket
总结
策略模式定义了算法族,分别分装起来,让它们之间可以相互转换,此模式让算法的变化独立于使用算法的客户。
设计原则多用组合,少用继承
本文的完整文档请参考"设计模式之策略模式.pdf“
- 学习设计模式之--------策略模式
- 设计模式之策略模式学习
- 设计模式学习笔记之策略模式
- 设计模式学习笔记之策略模式
- 设计模式学习之策略模式
- 设计模式学习之路-----策略模式
- 设计模式之策略模式学习
- 学习:设计模式之策略模式
- 设计模式学习之策略模式
- 学习篇:设计模式之策略模式
- 设计模式之策略模式的学习
- java设计模式学习之策略模式
- 设计模式学习之--策略模式
- 设计模式学习之策略模式
- 设计模式学习笔记之策略模式
- 设计模式学习笔记之策略模式
- C++设计模式学习之策略模式
- 设计模式学习之路-策略模式
- 为什么寄存器比内存快?
- java 两个int数组删除重复的数字,并返回删除后的数组
- 揭开Socket编程的面纱
- 在广州传智播客学平面设计,有点像高考
- 单链表查找节点
- 学习:设计模式之策略模式
- mac上登陆aws ec2方法
- Java_数组定义及常用方法
- 能力风暴智能机器人函数
- 单链表插入节点
- Linux平台Makefile文件的编写基础篇
- spring mvc json
- 当你有一天发现ie主页变成hao123的时候
- 项目的权利是你必须在项目开始前必须确认清楚