• Head First之策略模式


    1、策略模式的定义

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

    2、鸭子设计

    2.1 需求

    定义绿头鸭,红头鸭,橡胶鸭,诱饵鸭(前俩个都是普通鸭子,外观不同,橡胶鸭不会飞,诱饵鸭不会飞也不会叫)

    2.2 设计方式1(一般实现)


    这种设计应该说是我们大多数人下意识都会想到的,既通过超类抽取了游泳和外观的方法(继承抽取共性,所有的鸭子都会游泳,所有的鸭子都有外貌,当然fly()方法和quack()方法也可以抽取到父类中,子类重写,但是你要这么写,可能你的上司就要找你谈心让你回炉重造了),又通过接口来实现不同鸭子的不同需求(诱饵鸭不会飞就不实现Flyable接口,橡胶鸭呱呱叫就实现Quackable接口。
    当我第一次看到这个设计的时候,觉得没毛病,如果是我的话我也会这么做,可是它实在不是一个值得称赞的设计。

    2.3 设计方式2 (优化)


    ①很明显,这样设计增加了我们的代码量(多了两个类实现接口),但是这样做飞行动作和呱呱叫的动作就可以复用了,不必再被迫关联到鸭子超类。
    ②此外,我们可以动态增加一些行为,又不会对原有的行为造成影响。

    3、代码实现

    ①实现鸭子的基本逻辑

    public abstract class Duck {
    	public FlyBehavior flyBehavior;
    	public QuackBehavior quackBehavior;
    	public Duck() {
    		// TODO Auto-generated constructor stub
    	}
    	
    	public abstract void display();
    	
    	public void performFly() {
    		flyBehavior.fly();
    	}
    	
    	public void performQuack() {
    		quackBehavior.quack();
    	}
    	
    	public void swim() {
    		System.out.println("All ducks float, even decoys!");
    	}
    	
    }
    
    Duck
    public interface FlyBehavior {
    	public void fly();
    }
    
    
    FlyBehavior
    public class FlyNoWay implements FlyBehavior{
    
    	@Override
    	public void fly() {
    		// TODO Auto-generated method stub
    		System.out.println("I can't fly");
    	}
    
    }
    
    
    FlyNoWay
    public class FlyWithWings implements FlyBehavior{
    
    	@Override
    	public void fly() {
    		// TODO Auto-generated method stub
    		System.out.println("I can fly");
    	}
    
    }
    
    
    FlyWithWings
    public interface QuackBehavior {
    	public void quack();
    }
    
    
    
    QuackBehavior
    public interface QuackBehavior {
    	public void quack();
    }
    
    
    
    Quack
    public class Squeak implements QuackBehavior{
    
    	@Override
    	public void quack() {
    		// TODO Auto-generated method stub
    		System.out.println("squeak");
    	}
    
    }
    
    
    Squeak
    public class MuteQuack implements QuackBehavior{
    
    	@Override
    	public void quack() {
    		// TODO Auto-generated method stub
    		System.out.println("silence");
    	}
    
    }
    
    MuteQuack
    public class MallardDuck extends Duck{
    
    	public MallardDuck() {
    		flyBehavior = new FlyWithWings();
    		quackBehavior = new Quack();
    	}
    	
    	public void display() {
    		System.out.println("I'm a real Mallard duck");
    	}
    	
    }
    

    MallardDuck

    MallardDuck
    public class MiniDuckSimulator {
    	public static void main(String[] args) {
    		Duck mallark = new MallardDuck();
    		mallark.performFly();
    		mallark.performQuack();
    	}
    	
    }
    

    运行结果

    I can fly
    Quack
    

    ②动态设定鸭子的行为

    Duck类中新增set方法

    	public void setFlyBehavior(FlyBehavior fb) {
    		flyBehavior = fb;
    	}
    	
    	public void setQuackBehavior(QuackBehavior qb) {
    		quackBehavior = qb;
    	}
    

    定义鸭子类型模型鸭

    public class ModelDuck extends Duck {
    	public ModelDuck() {
    		// TODO Auto-generated constructor stub
    		flyBehavior = new FlyNoWay();
    		quackBehavior = new Quack();
    	}
    
    	@Override
    	public void display() {
    		// TODO Auto-generated method stub
    		System.out.println("I'm a model duck");
    		
    	}
    
    }
    
    ModelDuck

    定义火箭飞行行为

    public class FlyRocketPowered implements FlyBehavior {
    
    	@Override
    	public void fly() {
    		// TODO Auto-generated method stub
    		System.out.println("I'm flying with a rocket"); //定义火箭飞行
    	}
    
    }
    
    FlyRocketPowered

    改变测试类

    public class MiniDuckSimulator {
    	public static void main(String[] args) {
    		Duck mallark = new MallardDuck();
    		mallark.performFly();
    		mallark.performQuack();
    		Duck model = new ModelDuck();
    		model.performFly();
    		model.setFlyBehavior(new FlyRocketPowered()); //动态设定行为
    		model.performFly();
    	}
    	
    }
    

    运行结果

    I can fly
    Quack
    I can't fly
    I'm flying with a rocket
    

    设计总览

    4.小结

    这个是书上的例子,它很全面但是它不好,它讲得不清楚,更不易理解,虽然结合实际但是看了还是让人不知道什么时候用。所以暂时先放在这里,过段时间写篇易理解的。这篇着实难懂,但我还是不会删它,因为理解了策略模式,你只会觉得这篇just so so.

  • 相关阅读:
    17.天堂和地狱只在你的一念之间
    14.事情原来可能更糟
    如何评价一个网站的人气(Link Popularity Check)
    1.人生何必一定要成功
    4.何不看开一点
    字符串到枚举的转换代码
    广州泳场一览表
    收集开源项目
    7.把“失去”当作“抛弃”
    经常使用的Oracle监控语句
  • 原文地址:https://www.cnblogs.com/dearnotes/p/14372370.html
Copyright © 2020-2023  润新知