转载请注明出处: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方法对策略进行切换。
策略模式把会变化的部分抽离出来,进行封装,可以动态的增加和去除,而不影响不需要变化的部分。(找出应用中可能需要变化之处,把他们独立出来,不要和不需要变化的代码混在一起--设计原则),封装变化。
策略模式让我们针对超类型(接口和虚方法)编程。经常需要变化的实现不依赖具体的实现类,从而可以动态的运作变化的部分。(针对接口编程,而不是针对实现编程--设计原则)
在设计中多用组合,少用继承---设计原则。
代码应当具备弹性,应能够应付变化。