策略模式学习案例

转载请注明出处: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("喵~  喵喵~");
	}
	
}


Dog.java

public class Dog extends Animal{

	public Dog(String name) {
		super(name);
	}

	@Override
	public void sing() {
//		super.sing();
		System.out.println("汪~  汪汪~");
	}
	
}

Sheep.java

public class Sheep extends Animal{

	public Sheep(String name) {
		super(name);
	}

	@Override
	public void sing() {
//		super.sing();
		System.out.println("咩~  咩咩~");
	}
	
}

StrategyPatternTest.java

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();//在具体实现类中实现歌唱
}

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;
	}	
	
}

Bird.java

public class Bird extends Animal implements SingBehavior{

	public Bird(String name) {
		super(name);
	}

	@Override
	public void singSong() {
		System.out.println("伊~  呀呀~");
	}

}

Rabbit.java

public class Rabbit extends Animal implements SingBehavior{

	public Rabbit(String name) {
		super(name);
	}

	@Override
	public void singSong() {
		//只会吃萝卜,不会唱歌
	}
	
}

StrategyPatternTest.java

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();
}

CatSing.java 歌唱策略

package StrategyPattern;

public class CatSing implements SingInterface{

	@Override
	public void sing() {
		System.out.println("喵喵喵");
	}

}

DogSing.java 歌唱接口

package StrategyPattern;

public class DogSing implements SingInterface{

	@Override
	public void sing() {
		System.out.println("汪汪汪");
	}

}

Animal.java

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;
	}	
}

Cat.java

package StrategyPattern;

public class Cat extends Animal{

	public Cat(String name, SingInterface singInterface) {
		super(name, singInterface);
	}
	
}

Dog.java

package StrategyPattern;

public class Dog extends Animal{

	public Dog(String name, SingInterface singInterface) {
		super(name, singInterface);
	}

}

Bage.java

package StrategyPattern;
/**
 * 八哥学舌,别人唱什么,他学什么
 * @author
 *
 */
public class Bage extends Animal{

	public Bage(String name, SingInterface singInterface) {
		super(name, singInterface);
	}

}

StrategyPattern.java

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方法对策略进行切换。

策略模式把会变化的部分抽离出来,进行封装,可以动态的增加和去除,而不影响不需要变化的部分。(找出应用中可能需要变化之处,把他们独立出来,不要和不需要变化的代码混在一起--设计原则),封装变化。

策略模式让我们针对超类型(接口和虚方法)编程。经常需要变化的实现不依赖具体的实现类,从而可以动态的运作变化的部分。(针对接口编程,而不是针对实现编程--设计原则)

在设计中多用组合,少用继承---设计原则。


代码应当具备弹性,应能够应付变化。



你可能感兴趣的:(策略模式学习案例)