引论介绍:
想要编写一个鸭子接口,用来实现各种鸭子的抽象方法,如swim、quack、dispaly,最简单的做法如下,声明一个Duck类型的接口(抽象类,接口不能实例化方法),由超类实现swim和quack,子类实现display用来展示名字。
问题:
1、那么如果接口(抽象父类)中的方法并不适用与所有子类,比如新建一个木头鸭子不会叫也不会游泳,这时可能需要子类重写该方法实现覆盖。但是这样会有大量的编码在子类重复。结构复杂。
2、如果把游泳抽象为接口、叫的方法也抽象为接口,其他所有鸭子分别继承,那么也会出现不同类型的鸭子叫声不一致,导致子类必须重写。
策略模式:
定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的改变独立于使用该算法的客户。
解释:
1、首先需要将变化的部分分离出来,封装成“算法”。在鸭子问题中,变化的部分是swim和quack,因为鸭子的游泳方式和发出声音的方式有可能不同,所以讲他们分别封装起来。
2、算法族。也就是让不同的swim继承自统一接口,但是这样实现了多种swim方法,quack同理。他们之间自然可以相互替换。
3、他们之间自然可以相互替换。因为实现同一接口。
核心原则:面向接口编程
找出可能变化的部分,封装起来
多用组合少用继承。
实现类图:
每一个鸭子类都会在自己的构造函数里,设计超类鸭子中FlyBehavior和SwimBehavior的值来实现不同的swim和quack.
代码实现:
1 package com.strategy; 2 3 public abstract class Duck { 4 FlyBehavior flybahavoir; 5 QuackBehavior quackbehavior; 6 7 protected void FlyPerform(){ 8 this.flybahavoir.fly(); 9 } 10 11 protected void QuackPerform(){ 12 this.quackbehavior.quack(); 13 } 14 15 public void setFlyBeHavior(FlyBehavior flybahavoir){ 16 this.flybahavoir = flybahavoir; 17 } 18 19 public void setQuackBehavior(QuackBehavior quackbehavior){ 20 this.quackbehavior = quackbehavior; 21 } 22 23 protected void swim(){ 24 System.out.println("游泳的方法!!!!"); 25 } 26 27 public abstract void display(); 28 29 }
1 package com.strategy; 2 3 public class ModelDuack extends Duck { 4 public ModelDuack(){ 5 this.flybahavoir = new FlyWithNoWings(); 6 this.quackbehavior = new Quack(); 7 } 8 9 @Override 10 public void display() { 11 // TODO Auto-generated method stub 12 System.out.println("i am a modelduck"); 13 } 14 15 16 }
1 package com.strategy; 2 3 public interface FlyBehavior { 4 public void fly(); 5 6 }
1 package com.strategy; 2 3 public class FlyWithNoWings implements FlyBehavior{ 4 5 @Override 6 public void fly() { 7 // TODO Auto-generated method stub 8 System.out.println("wu翅膀的飞行行为!!!!!"); 9 } 10 11 }
1 package com.strategy; 2 3 public class FlyWithWings implements FlyBehavior{ 4 5 @Override 6 public void fly() { 7 // TODO Auto-generated method stub 8 System.out.println("有翅膀的飞行行为!!!!!"); 9 } 10 11 }
1 package com.strategy; 2 3 public interface QuackBehavior { 4 public void quack();//不能声明为private默认public 5 6 }
1 package com.strategy; 2 3 public class Squack implements QuackBehavior{ 4 5 @Override 6 public void quack() { 7 // TODO Auto-generated method stub 8 System.out.println("呱呱叫"); 9 } 10 11 }
1 package com.strategy; 2 3 public class MinimDuackSimulater { 4 public static void main(String args[]){ 5 Duck modelDuck = new ModelDuack(); 6 modelDuck.display(); 7 modelDuck.FlyPerform(); 8 modelDuck.setFlyBeHavior(new FlyWithWings()); 9 modelDuck.FlyPerform(); 10 } 11 12 }