首页 > 代码库 > 设计模式(1)--策略模式
设计模式(1)--策略模式
什么是策略模式呢?
策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法分别独立于使用算法的用户。
上面的定义你明白了吗?
我觉得聪明伶俐的你肯定已经明白了,那你看看我是怎么理解的吧。
就是将一个基类中一些行为进行分类,然后在应用到具体的类中选择这些具体的类别,下面我们举个例子来看看。
深入理解策略模式
假如现在有个需求,要求你写一个鸭子基类,这个鸭子基类要求有三个方法,分别是quak、fly、display,具体的鸭子种类继承这个基类。
根据这个需求,首先想到的应该是这样的
public class Duck { private String color; public Duck() { } public Duck(String color) { super(); this.color = color; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void quake() { System.out.println("嘎嘎嘎..."); } public void display() { System.out.println("我是一只" + color + "的鸭子"); } public void fly() { System.out.println("飞啊飞啊..."); } }
这个基类完成后,其他的具体鸭子继承这个基类,然后在写其他的特有属性或方法。
但是呢?这是不是存在一些问题呢?所有的鸭子都是‘嘎嘎嘎’的叫吗,所有的鸭子都能飞吗?我觉得肯定有一些比较奇葩的鸭子...所以呢我们这个设计存在这问题,此时应该怎么解决呢?这时候你应该会想到吧这个定义成一个接口,让其他的子类去实现它。具体代码应该如下:
public interface BaseDuck { void quak(); void display(); void fly(); }
或者我们也可以定义一个抽象类,将一些不怎么需要变化的方法在基类实现,而另外一些方法由子类去实现,示例如下:
public abstract class AbstractDuck { private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public abstract void quak(); public void display() { System.out.println("我是一只" + color + "的鸭子"); } public abstract void fly(); }
这时候这个代码还行,但是它真的没有缺陷了吗?可能忽略了一个问题,那就是我们这种设计是为了适应那些比较奇葩的鸭子种类。其他大部分鸭子应该都是一样的叫声和是可以进行飞行的。那么我们在写子类的时候就会写很多冗余的代码,那么我们如何解决这个问题呢?
策略模式就是解决这种问题的,它是如何实现的呢?先分析这个基类,quak和fly这两个是容易变化的,客户说不定那一天就要你加一个玩具鸭什么的。所以就这两个行为寄抽取出来,单独进行编写。先定义两个接口QuakBehavior和FlyBehavior,然后在根据需求编写一些子类,如能飞和不能飞、‘嘎嘎嘎’和‘吱吱吱’和不会叫等。示例代码如下:
下面代码是多个文件
//QuackBehavior.java public interface QuackBehavior { void quak(); } //FlyBehavior.java public interface FlyBehavior { void fly(); } //Quack.java public class Quack implements QuackBehavior { @Override public void quak() { System.out.println("嘎嘎嘎..."); } } //Squeak.java public class Squeak implements QuackBehavior { @Override public void quak() { System.out.println("吱吱吱..."); } } //QuackNoWay.java public class QuackNoWay implements QuackBehavior { @Override public void quak() { System.out.println("我不会叫..."); } } //FlyWithWings.java public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("飞啊飞啊..."); } } //FlyNoWay.java public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("我不会飞..."); } }
基类应该这样设计:
package model.strategy.v2; public class Duck { private String color; //添加行为接口的字段 private QuackBehavior quackBehavior; private FlyBehavior flyBehavior; public Duck() { } public Duck(String color, QuackBehavior quackBehavior, FlyBehavior flyBehavior) { super(); this.color = color; this.quackBehavior = quackBehavior; this.flyBehavior = flyBehavior; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void quake() {
//调用接口方法 quackBehavior.quak(); } public void display() { System.out.println("我是一只" + color + "的鸭子"); } public void fly() {
//调用接口方法 flyBehavior.fly(); } }
现在想想这个问题是不是很好的解决了!如果新的需求来了,我们只要定义一个新的接口实现了,而不需要修改这个基类中的代码。
我相信这时候已经对策略模式理解的很好了,如果你对该博客有什么见解或疑问,可以留言哦>v<
设计模式(1)--策略模式