设计模式---策略模式
2013-03-26 15:12
337 查看
今日在学习设计模式,深深地认识了自己的不足之处啊!!也认识到了一句话:“单纯为实现功能的代码不是好代码!”。我们必须要考虑到软件行业“多变”这个老魔头,时刻保持代码的可扩展性。为了丰富自己的羽翼,也为了能够和更多的人一起学习交流,写点东西吧!
策略模式
1、什么是策略模式?
策略模式定义了算法族,分别封装起来。让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
2、策略模式设计原则?
2.1 封装“变化”,使易于变化的部分独立于不变的部分,以便修改“变化”时,其他部分不受影响。
2.2针对“接口”编程而非针对实现编程。针对“接口”编程就是针对“超类型”编程,这个“超类型”可以是“接口《interface》“也可以是”抽象类《abstract class》”。
2.3多用组合,少用继承。可能随着你的编程技术的成熟,你会越来越发现,继承是有弊端的,如:代码在多个子类中重复,运行时的行为不容易改变,
改变会牵一发动全身等等。 解决这个弊端的好方法之一就是使用组合。
3、如何实现策略模式?
3.1封装“变化”,针对“接口”编程
实现策略模式很简单,按照策略模式设计原则,我们应该把基类中易于变化的“东西”拿出来,这一部分封装成“接口”或者“抽象类”。那么我们所谓的“方法族”就是实现这个接口(或抽象类)的具体的类。比如,基类是某游戏中的“鸭子”类,我们知道所有鸭子都可以游泳,但不是所有鸭子都能呱呱叫,比如橡皮鸭子,他只会吱吱叫;也不是所有鸭子都能飞翔,橡皮鸭子就不会飞。又如,在游戏中,我们通常要加入魔幻场景,比如让鸭子借助火箭力量飞起来等。显然要用继承实现不是最好的。我们应该抽象出“飞”的行为,FlyBehavior,这个接口提供一个fly()方法。让那些飞,不会飞,借助火箭飞等等这些方法作为具体类族来实现这个接口。同理,“叫”(QuackBehavior)也是如此。这里就会有人问了,类不是对现实世界的抽象吗?不是把某个“东西”抽象吗?怎么方法也抽象出类了?对了!你说的没错,只不过,在这的这个“东西”就是个行为。
3.2利用组合
我们把变化的部分从基类中拿出来了,怎么把它放回去呢?——组合!在鸭子类这个基类中,添加一个FlyBehavior的对象,同理还有QuackBehavior的对象。这样,每个鸭子类的子类就都具有了FlyBehavior和QuackBehavior的对象。我们再给基类鸭子类中添加flyBehavior和quackBehavior的setter方法,以便可以运行时动态设置flyBehavior和quackBehavior。
4、策略模式类图
每次在着手写代码前画好类图是一个非常好的编程习惯。
先来看一下通用的策略模式类图:
在这里,Strategy就是接口,它定义了一个方法AlgorithmInterface,ConcreteStrageA,ConcreteStrageB,ConcreteStrageC都是具体的策略,要实习这个AlgorithmInterface方法。Context就是我们的基类,他要维护一个Strategy的对象。将来在写客户调用代码时,就可以根据需要来初始化这个Strategy的对象了。
下面我们来看一下刚才跟鸭子有关系的小游戏的类图
5、实现代码:
关于策略模式一书《HEAD FIRST》中的动作冒险游戏代码可以给我发邮件(13623215228@163.com)
策略模式
1、什么是策略模式?
策略模式定义了算法族,分别封装起来。让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
2、策略模式设计原则?
2.1 封装“变化”,使易于变化的部分独立于不变的部分,以便修改“变化”时,其他部分不受影响。
2.2针对“接口”编程而非针对实现编程。针对“接口”编程就是针对“超类型”编程,这个“超类型”可以是“接口《interface》“也可以是”抽象类《abstract class》”。
2.3多用组合,少用继承。可能随着你的编程技术的成熟,你会越来越发现,继承是有弊端的,如:代码在多个子类中重复,运行时的行为不容易改变,
改变会牵一发动全身等等。 解决这个弊端的好方法之一就是使用组合。
3、如何实现策略模式?
3.1封装“变化”,针对“接口”编程
实现策略模式很简单,按照策略模式设计原则,我们应该把基类中易于变化的“东西”拿出来,这一部分封装成“接口”或者“抽象类”。那么我们所谓的“方法族”就是实现这个接口(或抽象类)的具体的类。比如,基类是某游戏中的“鸭子”类,我们知道所有鸭子都可以游泳,但不是所有鸭子都能呱呱叫,比如橡皮鸭子,他只会吱吱叫;也不是所有鸭子都能飞翔,橡皮鸭子就不会飞。又如,在游戏中,我们通常要加入魔幻场景,比如让鸭子借助火箭力量飞起来等。显然要用继承实现不是最好的。我们应该抽象出“飞”的行为,FlyBehavior,这个接口提供一个fly()方法。让那些飞,不会飞,借助火箭飞等等这些方法作为具体类族来实现这个接口。同理,“叫”(QuackBehavior)也是如此。这里就会有人问了,类不是对现实世界的抽象吗?不是把某个“东西”抽象吗?怎么方法也抽象出类了?对了!你说的没错,只不过,在这的这个“东西”就是个行为。
3.2利用组合
我们把变化的部分从基类中拿出来了,怎么把它放回去呢?——组合!在鸭子类这个基类中,添加一个FlyBehavior的对象,同理还有QuackBehavior的对象。这样,每个鸭子类的子类就都具有了FlyBehavior和QuackBehavior的对象。我们再给基类鸭子类中添加flyBehavior和quackBehavior的setter方法,以便可以运行时动态设置flyBehavior和quackBehavior。
4、策略模式类图
每次在着手写代码前画好类图是一个非常好的编程习惯。
先来看一下通用的策略模式类图:
在这里,Strategy就是接口,它定义了一个方法AlgorithmInterface,ConcreteStrageA,ConcreteStrageB,ConcreteStrageC都是具体的策略,要实习这个AlgorithmInterface方法。Context就是我们的基类,他要维护一个Strategy的对象。将来在写客户调用代码时,就可以根据需要来初始化这个Strategy的对象了。
下面我们来看一下刚才跟鸭子有关系的小游戏的类图
5、实现代码:
//定义飞行方法族 public interface FlyBehavior { void fly(); } public class FlyWithWings:FlyBehavior { public void fly() { Console.WriteLine("我有翅膀,可以飞翔"); } } class FlyWithRocketPower:FlyBehavior { public void fly() { Console.WriteLine("我可以借助火箭的力量飞翔"); } } public class FlyNoWay:FlyBehavior { public void fly() { Console.WriteLine("我不会飞!"); } }
//定义“叫”方法族 public interface QuackBehavior { void quack(); } public class MuteQuack:QuackBehavior { public void quack() { Console.WriteLine("我不会叫!"); } } public class Quack:QuackBehavior { public void quack() { Console.WriteLine("我会呱呱叫!"); } } public class Quack:QuackBehavior { public void quack() { Console.WriteLine("我会呱呱叫!"); } }
//鸭子基类 public class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior; public void swim() { Console.WriteLine("我会游泳"); } public virtual void display() { } public void performFly() { this.flyBehavior.fly(); } public void performQuack() { this.quackBehavior.quack(); } public void setFlybehavior(FlyBehavior fly) { this.flyBehavior = fly; } public void setQuackbehavior(QuackBehavior quack) { this.quackBehavior = quack; } } //诱饵鸭 public class DecoyDuck:Duck { public DecoyDuck() { this.flyBehavior = new FlyNoWay(); this.quackBehavior = new Quack(); } public override void display() { Console.WriteLine("我是诱饵鸭!"); } } //橡皮鸭 public class RubberDuck:Duck { public override void display() { Console.WriteLine("我是橡皮鸭"); } public RubberDuck() { this.flyBehavior = new FlyNoWay(); this.quackBehavior = new Squeak(); } } //红头鸭 public class RedheadDuck:Duck { public override void display() { Console.WriteLine("我是红头鸭!"); } public RedheadDuck() { this.flyBehavior = new FlyWithWings(); this.quackBehavior = new Quack(); } } //绿头鸭 public class MallardDuck:Duck { public override void display() { Console.WriteLine("我是绿头鸭!"); } public MallardDuck() { this.flyBehavior = new FlyWithWings(); this.quackBehavior = new Quack(); } }
//测试代码 class Program { static void Main(string[] args) { Duck redduck = new RedheadDuck(); redduck.performFly(); redduck.performQuack(); redduck.setFlybehavior(new FlyWithRocketPower()); redduck.performFly(); Console.ReadKey(); } }
关于策略模式一书《HEAD FIRST》中的动作冒险游戏代码可以给我发邮件(13623215228@163.com)
相关文章推荐
- 设计模式之策略模式
- 【设计模式篇】Android设计模式之-策略模式 自我见解
- 学习JavaScript设计模式(策略模式)
- JS设计模式之策略模式概念与用法分析
- 一口一个设计模式--策略模式
- 设计模式_策略模式(Strategy Pattern)
- 设计模式之Strategy(策略)
- javascript 设计模式实践之策略模式--输入验证
- 设计模式之策略(Strategy)模式
- Java设计模式之策略模式
- 设计模式学习(一)——策略模式
- php设计模式之策略模式
- 设计模式之一(策略模式)
- 设计模式之策略模式的使用
- 设计模式学习——策略模式
- 设计模式—策略模式
- 设计模式之策略模式(笔记)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式之----策略模式