策略模式(Strategy Pattern)

1. 问题引出

设计一个鸭子基类(Duck),并由这个基类派生多个子类鸭子(MallardDuck,RedheadDuck,.......)。鸭子基类中可能包含以下方法让子类继承或者重载quack(),swim(),fly()和display()等等。
如果我们使用简单的继承和implements interface的方式有以下缺点:1.如果使用继承,某些鸭子的行为在子类里不断的改变,并且让所有的子类都有这些行为是不恰当的,例如玩具鸭子不能飞(不应该继承fly()方法)。2.实现Flyable和Quackable接口,看似解决了问题(只有会飞的鸭子才继承Flyable接口),但是java接口不具有实现代码,所以implements接口无法达到代码的复用。这意味着,无论何时你需要修改某个行为,你必须得往下追踪并在每一个定义此行为的类中修改它,容易出错。

2. 模式定义:

策略模式:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
策略模式类图:

设计原则:
(1)找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
(2)针对接口编程,而不是针对实现编程。
其中这里的接口可以是java中定义的interface,也可以是abstract class。
(3)多用组合,少用继承。

3.代码实现:

FlyBehavior.java:
package net.pmpa.strategy;

public interface FlyBehavior {
	public void fly();
}


FlyWithWings.java:
package net.pmpa.strategy;

public class FlyWithWings implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I can fly with wings!!");
	}

}


FlyRocketPowered.java:
package net.pmpa.strategy;

public class FlyRocketPowered implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying with a rocket");
	}
}


FlyNoWay.java:
package net.pmpa.strategy;

public class FlyNoWay implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I can't fly!!");
	}

}


QuackBehavior.java:
package net.pmpa.strategy;

public interface QuackBehavior {
	public void quack();
}


Quack.java:
package net.pmpa.strategy;

public class Quack implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("Quack!!");	
	}

}


Squeak.java:
package net.pmpa.strategy;

public class Squeak implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("Squeak!!");	
	}

}


MuteQuack.java:
package net.pmpa.strategy;

public class MuteQuack implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("I can't quack!!");	
	}

}


Duck.java:
package net.pmpa.strategy;

public abstract class Duck {
	FlyBehavior flybehavior;
	QuackBehavior quackbehavior;
	
	public void swim(){
		System.out.println("All ducks can swim!!");
	}
	public abstract void display();
	public void performQuack()   //委托子类实现
	{
		quackbehavior.quack();
	}
	public void performFly()
	{
		flybehavior.fly();
	}

	public void setFlybehavior(FlyBehavior flybehavior) {   //可以动态设定duck的行为,先定义一个FlyBehavior的对象,再赋予该duck
		this.flybehavior = flybehavior;
	}

	public void setQuackbehavior(QuackBehavior quackbehavior) {
		this.quackbehavior = quackbehavior;
	}

}


MallardDuck.java:
package net.pmpa.strategy;

public class MallardDuck extends Duck {
	
	public MallardDuck()
	{
		flybehavior = new FlyWithWings();
		quackbehavior = new Quack();
	}

	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("I'm a Mallard Duck!!");
	}

}


RedHeadDuck.java:
package net.pmpa.strategy;

public class RedHeadDuck extends Duck {
 
	public RedHeadDuck() {
		flybehavior = new FlyWithWings();
		quackbehavior = new Quack();
	}
 
	public void display() {
		System.out.println("I'm a real Red Headed duck");
	}
}


RubberDuck.java:
package net.pmpa.strategy;

public class RubberDuck extends Duck {
 
	public RubberDuck() {
		flybehavior = new FlyNoWay();
		quackbehavior = new Squeak();
	}
 
	public void display() {
		System.out.println("I'm a rubber duckie");
	}
}


DecoyDuck.java:
package net.pmpa.strategy;

public class DecoyDuck extends Duck {
	public DecoyDuck() {
		setFlybehavior(new FlyNoWay());
		setQuackbehavior(new MuteQuack());
	}
	public void display() {
		System.out.println("I'm a duck Decoy");
	}
}


ModelDuck.java:
package net.pmpa.strategy;

public class ModelDuck extends Duck {
	public ModelDuck() {
		flybehavior = new FlyNoWay();
		quackbehavior = new Quack();
	}

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


MiniDuckSimulator.java  测试类:

package net.pmpa.strategy;

public class MiniDuckSimulator {
 
	public static void main(String[] args) {
 
		MallardDuck	mallard = new MallardDuck();
		RubberDuck	rubberDuckie = new RubberDuck();
		DecoyDuck	decoy = new DecoyDuck();
 
		Duck model = new ModelDuck();

		mallard.performQuack();
		rubberDuckie.performQuack();
		decoy.performQuack();
   
		model.performFly();	
		model.setFlybehavior(new FlyRocketPowered());  //动态行为设定
		model.performFly();
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值