转载请注明出处:http://blog.csdn.net/droyon/article/details/8611418
策略模式:顾名思义就是提供一系列策略,在不同的情形下可以选择不同的策略。
官方定义:定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
学习源代码下载
案例:
家庭的动物们要开音乐会,我们分几种不同的方案实现。最后使用策略模式实现。
1、使用继承实现:
Animal.java
public class Animal { private String mName; private String mSing; public Animal(String name){ mName = name; } public void display(){ System.out.println(mName +"唱歌"+mSing); } public void sing(){ System.out.println("我在唱歌"); } public String getmName() { return mName; } public void sing(Animal animal){ animal.sing(); } }
Cat.java
public class Cat extends Animal{ public Cat(String name) { super(name); } @Override public void sing() { // super.sing(); System.out.println("喵~ 喵喵~"); } }
public class Dog extends Animal{ public Dog(String name) { super(name); } @Override public void sing() { // super.sing(); System.out.println("汪~ 汪汪~"); } }
public class Sheep extends Animal{ public Sheep(String name) { super(name); } @Override public void sing() { // super.sing(); System.out.println("咩~ 咩咩~"); } }
public class StrategyPatternTest { public static void main(String args[]){ System.out.println("家庭动物音乐会"); Animal cat1 = new Cat("小花猫"); Animal cat2 = new Cat("大花猫"); Animal dog = new Dog("小花狗"); Animal sheep = new Sheep("小绵羊"); System.out.println("预备唱-----"); System.out.print(cat1.getmName()+":"); cat1.sing(); System.out.print(cat2.getmName()+":"); cat2.sing(); System.out.print(dog.getmName()+":"); dog.sing(); System.out.print(sheep.getmName()+":"); sheep.sing(); } }测试结果:
家庭动物音乐会
预备唱-----
小花猫:喵~ 喵喵~
大花猫:喵~ 喵喵~
小花狗:汪~ 汪汪~
小绵羊:咩~ 咩咩~
2、接口实现:
SingBehavior.java
public interface SingBehavior { public void singSong();//在具体实现类中实现歌唱 }
public class Animal { private String mName; private String mSing; public Animal(String name){ mName = name; } public void display(){ System.out.println(mName +"唱歌"+mSing); } public void sing(){ System.out.println("我在唱歌"); } public String getmName() { return mName; } }
public class Bird extends Animal implements SingBehavior{ public Bird(String name) { super(name); } @Override public void singSong() { System.out.println("伊~ 呀呀~"); } }
public class Rabbit extends Animal implements SingBehavior{ public Rabbit(String name) { super(name); } @Override public void singSong() { //只会吃萝卜,不会唱歌 } }
public class StrategyPatternTest { public static void main(String args[]){ Bird bird = new Bird("小鸟"); System.out.print(bird.getmName()+":"); bird.singSong(); Rabbit rabbit = new Rabbit("兔子"); System.out.print(rabbit.getmName()+":"); rabbit.singSong(); } }
小鸟:伊~ 呀呀~
兔子:
3、利用组合实现:(策略模式实现)
SingInterface.java 策略接口
package StrategyPattern; public interface SingInterface { public void sing(); }
package StrategyPattern; public class CatSing implements SingInterface{ @Override public void sing() { System.out.println("喵喵喵"); } }
package StrategyPattern; public class DogSing implements SingInterface{ @Override public void sing() { System.out.println("汪汪汪"); } }
package StrategyPattern; public class Animal { private String mName; private String mSing; private SingInterface mSingBehavior;//接口保证了调用时的统一以及方便策略的切换。 public Animal(String name,SingInterface singInterface){ mName = name; mSingBehavior = singInterface; } public void display(){ System.out.println(mName +"唱歌"+mSing); } public void sing(){ mSingBehavior.sing(); } public SingInterface getmSingBehavior() { return mSingBehavior; } public void setmSingBehavior(SingInterface mSingBehavior) { this.mSingBehavior = mSingBehavior; } public String getmName() { return mName; } }
package StrategyPattern; public class Cat extends Animal{ public Cat(String name, SingInterface singInterface) { super(name, singInterface); } }
package StrategyPattern; public class Dog extends Animal{ public Dog(String name, SingInterface singInterface) { super(name, singInterface); } }
package StrategyPattern; /** * 八哥学舌,别人唱什么,他学什么 * @author * */ public class Bage extends Animal{ public Bage(String name, SingInterface singInterface) { super(name, singInterface); } }
package StrategyPattern; public class StrategyPattern { public static void main(String args[]){ SingInterface catSing = new CatSing(); SingInterface dogSing = new DogSing(); Animal cat = new Cat("花猫",catSing); Animal dog = new Dog("小狗",dogSing); Bage bage = new Bage("八哥",null); System.out.println("预备唱---"); System.out.print(cat.getmName()+":"); cat.sing(); System.out.print(bage.getmName()+":"); bage.setmSingBehavior(catSing); bage.sing(); System.out.print(dog.getmName()+":"); dog.sing(); System.out.print(bage.getmName()+":"); bage.setmSingBehavior(dogSing); bage.sing(); } }
预备唱---
花猫:喵喵喵
八哥:喵喵喵
小狗:汪汪汪
八哥:汪汪汪
总结:
继承可以保证代码复用,有时只需改动一下父类,那么所有的子类都具有了相应属性。但为了代码复用采用继承,不是个好主意。因为改动代码,会影响所有的子类,包括那些不需要改变的子类。
接口提供了统一的接口,但必须在每个实现类中进行实现,产生了重复代码。
上述代码中:CatSing,DogSing都是SingInterface的策略,在Animal中可以通过setmSingBehavior方法对策略进行切换。
策略模式把会变化的部分抽离出来,进行封装,可以动态的增加和去除,而不影响不需要变化的部分。(找出应用中可能需要变化之处,把他们独立出来,不要和不需要变化的代码混在一起--设计原则),封装变化。
策略模式让我们针对超类型(接口和虚方法)编程。经常需要变化的实现不依赖具体的实现类,从而可以动态的运作变化的部分。(针对接口编程,而不是针对实现编程--设计原则)
在设计中多用组合,少用继承---设计原则。
代码应当具备弹性,应能够应付变化。