策略模式(基于接口编程。随时想到一个问题,那就是如果后期有新的行为需要添加,如何提高代码的弹性和复用性):
抽象类鸭子都会游泳,会有不同的外观。具体类鸭子继承基类,因此具备了基类鸭子的特性和行为。现在有个新的需求,
要求一个会飞的鸭子和吱吱叫的鸭子,如果将会飞行为和叫的行为直接加入基类中,那么所有继承该基类的鸭子都具备了
会飞和叫的行为。有些鸭子子类不会飞,在超类中加上新的行为,会使得某些不适合该行为的子类也具有该行为(那些不
会飞的鸭子也具备了飞行行为)有些鸭子吱吱叫,有些呱呱叫,子类鸭子都要被迫检测是否该覆盖在基类中的新增行为。
需求是不断更新的,如果以后又有新的行为需要增加,那这样的代码完全没有弹性。所以简单的用继承不可行。如果使用
接口,每个行为均为一个接口,类通过实现行为接口来达到目的,这样每个子类都有对接口进行实现,无法做到代码的复
用性。因此将代码中变化的部分提出出来,采用组合替代继承,并基于接口编程而不是基于具体编程。
实现图如下:
抽象鸭子类:
public abstract class Duck { FlyBehavior flyBehavior; //有飞行接口 QuackBehavior quackBehavior;//有叫的接口 public abstract void display(); public void swim() { System.out.println("all ducks can swim"); } public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public FlyBehavior getFlyBehavior() { return flyBehavior; } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public QuackBehavior getQuackBehavior() { return quackBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
飞行接口:
public interface FlyBehavior { public void fly(); }
叫的接口:
public interface QuackBehavior { public void quack(); }
飞行的具体类(会飞,实现飞行接口):
public class FlyWithWings implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I am flying"); } }
飞行接口(不会飞):
public class FlyNoWay implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can't fly"); } }
行为叫的具体类(吱吱叫,实现叫接口):
public class Quack implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("吱吱叫"); } }
行为叫的具体类(呱呱叫,实现叫接口):
public class Squeak implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("呱呱叫"); } }
叫的具体类(不会叫):
public class QuackNoWay implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("I can't quack"); } }
鸭子子类继承抽象类鸭子:
public class SubDuck extends Duck{ public SubDuck(){} public SubDuck(FlyBehavior flyBehavior,QuackBehavior quackBehavior) { this.flyBehavior=flyBehavior; this.quackBehavior=quackBehavior; } @Override public void display() { // TODO Auto-generated method stub System.out.println("green head"); } }
鸭子模拟器:
public class DuckSimulator { public static void main(String [] args) { FlyBehavior flyBehavior=new FlyWithWings(); QuackBehavior quackBehavior=new Quack(); Duck duck=new SubDuck(flyBehavior,quackBehavior); duck.performFly(); duck.performQuack(); FlyBehavior flyBh=new FlyNoWay(); duck.setFlyBehavior(flyBh); duck.performFly(); } }