• 设计模式之策略模式


    概述

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

    涉及到的设计原则

    1. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
    2. 针对接口编程,而不是针对实现编程。
    3. 多用组合,少用继承。

    UML

    策略模式

    • Context:上下文角色,负责封装,屏蔽策略。
    • Strategy:抽象策略接口。
    • ConcreteStrategy:实现具体算法。

    类似代理模式,只是没有共同接口。

    优劣简述

    优点:

    • 算法自由切换,避免封装类多重条件判断,由高层决定。
    • 符合开闭原则,扩展性好

    缺点:

    • 策略类数量多,无法复用。

    场景:

    • 多个类只在算法或行为上稍有不同。
    • 算法需要自由切换。
    • 算法需要屏蔽。

    代码实现

    多种鸭子有多种行为。

    接口类及其实现类

    我们把鸭子的不同行为抽象出来,比如飞的行为,但是飞有很多种,我们使用多态来实现。同时鸭子会叫,不同鸭子叫的方式可能不同,我们将使用多态来实现不同的叫声。那么至少应该有FlyBehavior和QuackBehavior两个接口。

    FlyBehavior.java

    public interface FlyBehavior {
    	public void fly();
    }
    

    FlyNoWay.java

    public class FlyNoWay implements FlyBehavior {
    
    	@Override
    	public void fly() {
    		System.out.println("I can't fly.");
    	}
    
    }
    

    FlyWithWings.java

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

    FlyRocketPowered.java

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

    QuackBehavior.java

    public interface QuackBehavior {
    	public void quack();
    }
    

    Quack.java

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

    Squeak.java

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

    MuteQuack.java

    public class MuteQuack implements QuackBehavior {
    
    	@Override
    	public void quack() {
    		// TODO Auto-generated method stub
    		System.out.println("<< Silence >>");
    	}
    
    }
    

    抽象类及其子类

    假设所有的鸭子会游泳,会不同的鸣叫和飞。假设它们游泳的方式都是一样的,只有鸣叫和飞的行为不一样,这样我们就可以在抽象类中实现一样的动作,不去实现不一样的行为。以后不同鸭子只需要继承这个父类鸭子即可。

    Duck.java

    public abstract class Duck {
    	protected FlyBehavior flyBehavior;
    	protected QuackBehavior quackBehavior;
    	public abstract void disPlay();
    	
    	public void performFly(){
    		flyBehavior.fly();
    	}
    	
    	public void performQuack(){
    		quackBehavior.quack();
    	}
    	
    	public void swim(){
    		System.out.println("Swimming...");
    	}
    
    	public void setFlyBehavior(FlyBehavior flyBehavior) {
    		this.flyBehavior = flyBehavior;
    	}
    
    	public void setQuackBehavior(QuackBehavior quackBehavior) {
    		this.quackBehavior = quackBehavior;
    	}
    }
    

    ModelDuck.java

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

    MallardDuck.java

    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 mallardDuck.");
    	}
    
    }
    

    Duck2.java

    public class Duck2 extends Duck{
    
    	public Duck2(){
    		flyBehavior = new FlyNoWay();
    		quackBehavior = new Squeak();
    	}
    	@Override
    	public void disPlay() {
    		// TODO Auto-generated method stub
    		System.out.println("I'm duck2...");
    	}
    	
    }
    

    使用

    MiniDuckSimulator.java

    public class MiniDuckSimulator {
    	public static void main(String[] args) {
    		Duck duck = new MallardDuck();
    		duck.performFly();
    		duck.performQuack();
    		
    		Duck duck2 = new Duck2();
    		duck2.performFly();
    		duck2.performQuack();
    		
    		Duck duck3 = new ModelDuck();
    		duck3.performFly();
    		duck3.performQuack();
    		duck3.setFlyBehavior(new FlyRocketPowered());
    		duck3.performFly();
    	}
    }
    
  • 相关阅读:
    html基础知识整理
    全局变量报错:UnboundLocalError: local variable 'l' referenced before assignment
    python简易版学生管理系统
    L2-024. 部落(并查集)
    python 飞机大战 实例
    Python3没有dict.has_key方法
    python学习-字符串 列表 元祖
    vim产生的.swap文件
    caffe 参数介绍 solver.prototxt
    ReentrantLock 实现原理
  • 原文地址:https://www.cnblogs.com/pinnsvin/p/8573242.html
Copyright © 2020-2023  润新知