HeadFirst --策略模式

HeadFirst --策略模式



本来是要做一个鸭子应用的:





1. 很容易想到用继承, Duck基类中有很多方法,子类只要重写父类方法即可;

这样有些问题:比如基类中增加一个方法fly ,那么所有的子类都有了fly()方法,但是并不是需要所有的子类都有这个方法的。

extends 只要是抽象方法,都是要求子类去实现的,每增加一个子类就要被迫去实现 父类所有方法。


为了避免这样的问题,我们很容易想到用接口实现,只要实现接口中,你需要的方法即可



这个实现方法,确实可以避免每个子类都要去实现基类的方法,但是也引入了一个新的问题

啥问题呢?  无法复用基类的代码,如果只要稍微改动接口中的某个方法,那么所有的子类可能都需要修改。

这是从一个坑跳到另外一个坑, 不是特别好的设计。


设计原则1 :

 找出应用中需要变化之处,将他们独立出来,不要和那些不需要的变化的代码放在一块。


设计原则2:

  针对接口编程,而不是针对实现编程。


也就是说,鸭子的行为被放在分开的类中,此类专门提供某行为接口的实现。

针对接口编程,其实是针对超类型编程


上图中可以看到:

//面向实现编程
Dog  dog = new Dog();
//面向接口编程
Amimal animal = new Dog();
animal.makeSound();
// 更高级一些,子类实例化不需要硬编码,而是运行时 才指定实际的对象
a = getAnimal();
a.makesound();



可以清楚看到面向实现编程和面向接口编程的区别。


行为类都单独抽取出来一个接口,一个FlyBehavior 和一个QuackBehavior 。

鸭子类继承Duck;

飞行行为实现FlyBehavior,呱呱行为QuackBehavior接口


设计原则 3:

     多用组合,少用继承


下面看下具体实现代码

定义一个鸭子:

package designPattern.strategy;

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
 
	public Duck() {
	}
 
	public void setFlyBehavior (FlyBehavior fb) {
		flyBehavior = fb;
	}
 
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
 
	abstract void display();
 
	public void performFly() {
		flyBehavior.fly();
	}
 
	public void performQuack() {
		quackBehavior.quack();
	}
 
	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}
}


两个行为类接口:

package designPattern.strategy;

public interface QuackBehavior {
	public void quack();
}


package designPattern.strategy;

/**
 * 
 * @author wangxiaoming
 * 定义一个基本行为接口
 */
public interface FlyBehavior {
	public void fly();
}


然后你想实现哪种行为类的就去实现这个行为类的接口,继承鸭子基类,用get set方法定义鸭子行为,即可实现,你想要怎样的鸭子都行,能飞的,不能飞的,能叫的,不能叫的。 
package designPattern.strategy;

public class FlyWithWings implements FlyBehavior {
	@Override
	public void fly() {
        System.out.println("I am Flying");
	}

}

package designPattern.strategy;

public class MuteQuack implements QuackBehavior {

	@Override
	public void quack() {
        System.out.println("<< Slience >>");
	}

}

看模拟器:

package designPattern.strategy;

public class MiniDuckSimulator1 {
	
	/**
	 * 
	 * @param args
	 * 啥叫用组合方式 这里面的FlyBehavior 和QuackBehavior 其实就是组合 不同的行为组合起来
	 * 而不是说鸭子有这两个行为然后继承即可,也就是说有一个会比是一个 好。
	 */
	public static void main(String[] args){
		// 高级一些的实现方式
		Duck mallard = new MallardDuck();
		mallard.setFlyBehavior(new FlyWithWings());
		mallard.performQuack();
		mallard.performFly();

		Duck model = new ModelDuck();
		model.performFly();
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();
		
	}
	
}











package designPattern.strategy;

public class MallardDuck extends Duck {
	 
	public MallardDuck() {
		quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
	}
 
	public void display() {
		System.out.println("I'm a real Mallard duck");
	}
}


package designPattern.strategy;

/**
 * 
 * @author wangxiaoming
 * 模型鸭,不能飞
 */
public class ModelDuck extends Duck {
	public ModelDuck() {
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}

	public void display() {
		System.out.println("I'm a model duck");
	}
}


























猜你喜欢

转载自blog.csdn.net/wangming520liwei/article/details/78942130
今日推荐