设计模式:helloworld之策略模式

liqiangchn liqiangchn     2022-11-06     558

关键词:

一.概述

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

策略模式的三要素:

抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

具体策略角色:包装了相关的算法和行为。

环境角色:持有一个策略类的引用,最终给客户端调用。

二.案例驱动

提出问题:要求做出一套模拟鸭子的游戏,游戏中会出现各种鸭子,它们一边游泳,一边呱呱叫。

分析:根据OO设计思想,无非就是使各种鸭子实现自己相应的功能即可,如鸭子游泳,鸭子呱呱叫。

解决方案1.0:设计一个接口(Duck),然后根据需要完成不同的实现,如红头鸭,绿头鸭。。。。

public interface Duck 
    public abstract void quack();
    public abstract void swim();
    public abstract void display();

public MallardDuck implements Duck
    public abstract void quack()
        System.out.println("呱呱~~");
    
    public abstract void swim()
        System.out.println("欢快的游泳~~");
    
    public abstract void display()
        System.out.println("绿头鸭~~");
    

public RedHeadDuck implements Duck
    public abstract void quack()
        System.out.println("呱呱~~");
    
    public abstract void swim()
        System.out.println("欢快的游泳~~");
    
    public abstract void display()
        System.out.println("红头鸭~~");
    

突然增加一个新的需求,要求有野鸭,除了具有这两个功能外,还会飞(fly),同时还有一种橡皮鸭,叫声时吱吱。。

此时该方案便暴露了一下缺点。。。。

缺点:牵一发而动全身,我们很难知道所有鸭子的行为,当针对有些实现需要添加新的功能时

解决方案1.1

为了更加灵活,面向接口编程。

public interface Flyable 
    public abstract void fly();

public interface Swimable 
    public abstract void swim();

public interface Quackable 
    public abstract void quack();

public RedHeadDuck implements Quackable implements Swimable ...
public WildDuck implements Quackable implements Swimable implements Flyable ...

如果有一万种鸭子,这种方式简直不敢想象,重复代码太多!

解决方案2.0

采用策咯模式解决此问题。

step1:把会变化的部分取出来,并封装起来,好让其他代码不受影响。

技术分享图片

step2:封装行为的大局观

技术分享图片

step3:代码实现

抽象策略角色

// 飞行行为
public interface FlyBehavior 
    public abstract void fly();

// 叫声行为
public interface QuackBehavior 
    public abstract void quack();

具体策略对象

// 橡皮鸭叫
public RubberDuckBehavior implements QuackBehavior 
    public abstract void quack()
        System.out.println("吱吱~~");
    

// 野鸭叫
public WildDuckBehavior implements QuackBehavior 
    public void quack()
        System.out.println("嘎嘎~~");
    

// 大黄鸭叫
public YellowDuckBehavior implements QuackBehavior 
    public void quack()
        System.out.println("呱呱~~");
    
// 不会飞
public FlyNoWay implements FlyBehavior 
    public void fly()
        System.out.println("不会飞~~");
    

// 用翅膀飞
public FlyWithWings implements FlyBehavior 
    public void fly()
        System.out.println("用翅膀飞~~");
    

// 螺旋桨飞
public FlyLikePlane implements FlyBehavior 
    public void fly()
        System.out.println("用螺旋桨~~");
    

环境角色

抽象类

public abstract class Duck 
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) 
        this.flyBehavior = flyBehavior;
    
    public void setQuackBehavior(QuackBehavior quackBehavior) 
        this.quackBehavior = quackBehavior;
    
    public void performFly() 
        flyBehavior.fly();
    
    public void performQuack() 
        quackBehavior.quack();
    
    public abstract display() 
    public void swim() 
        System.out.println("鸭子天生会游泳!");
    

实现

public class WildDuck implements Duck 
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    public WildDuck() 
        // 默认会飞,野鸭叫嘎嘎
        this.flyBehavior = new FlyWithWings();
        this.quackBehavior = new WildDuckBehavior();
    
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) 
        this.flyBehavior = flyBehavior;
    
    public void setQuackBehavior(QuackBehavior quackBehavior) 
        this.quackBehavior = quackBehavior;
    
    public void performFly() 
        flyBehavior.fly();
    
    public void performQuack() 
        quackBehavior.quack();
    
    public void display() 
        System.out.println("这是一只野鸭!");
    
    public void swim() 
        System.out.println("鸭子天生会游泳!");
    

需求改变:野鸭的翅膀受伤,不会飞了

    public static void main(String[] args) 
        Duck duck = new WildDuck();
        duck.setFlyBehavior(new FlyNoWay());
        duck.performFly();// 输出:不会飞~~
    

需改改变:新增一只火箭鸭,能飞到太空,不会游泳,外形像火箭一样,叫嘎嘎

public RocketDuckFlyBehavior implements FlyBehavior 
    public  void fly()
        System.out.println("飞到太空~~");
    
public class RocketDuck implements Duck 
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    public WildDuck() 
        // 默认会飞,野鸭叫嘎嘎
        this.flyBehavior = new RocketDuckFlyBehavior();
        this.quackBehavior = new WildDuckQuackBehavior();
    
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) 
        this.flyBehavior = flyBehavior;
    
    public void setQuackBehavior(QuackBehavior quackBehavior) 
        this.quackBehavior = quackBehavior;
    
    public void performFly() 
        flyBehavior.fly();
    
    public void performQuack() 
        quackBehavior.quack();
    
    public abstract display() 
        System.out.println("外形像火箭~~");
    
    public void swim() 
        System.out.println("不会游泳");
    

三.策略模式的优缺点

优点:

1.策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把代码转移到符类,从而避免重复代码 。

2.在策略模式中利用组合和委托来让环境角色拥有执行算法的能力,这也是继承的一种更轻便的替代方案。

3.提供了对开放—封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于扩展

4.利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句

缺点:

 1.客户端必须知道所有的策略类,区分他们之间的区别,并自行决定使用哪一个策略类。

 2.针对每一种行为情况需要创建一个策略类,造成很多的策略类。
个人站点地址:www.mycookies.cn(适合java初学者的个人博客项目) github:https://github.com/liqianggh/blog


设计模式之策略模式

...me.翻译如下:策略模式(又名代理模式)是一种行为软件设计模式在运行的过程中能动态的更改算法。由以下几个部分组成:定义一组 查看详情

设计模式之策略模式

策略模式属于对象行为型的设计模式定义:封装了一些列算法,它们之前可以相互替换,此模式使得算法的改变,不会影响到使用它们的客户端  策略模式有以下3个角色组成抽象策略类:所有策略类的父类,为所支持的... 查看详情

《设计模式之禅》之策略模式

一、策略模式的定义策略模式是一种比较简单的模式,也叫做政策模式,其定义如下:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使用的是面向对象的继承和多态机制,我们看看策略模式的三个... 查看详情

设计模式之策略模式

1、定义  策略模式属于对象的行为模式。其用意是针对一组算法,将每一组算法封装到具有共同接口的独立子类中,从而可以使得他们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。2、策略模式... 查看详情

设计模式之策略模式

...,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。介绍意图... 查看详情

015设计模式之策略模式

抽象策略角色:策略类,通常由一个接口或者抽象类实现。-具体策略角色:包装了相关的算法和行为。-环境角色:持有一个策略类的引用,最终给客户端调用。 #pragmaonce//策略接口(纯虚函数)classIStrategypublic: IStrategy() virtual~IStrate... 查看详情

大话设计模式之策略模式

策略模式  定义了一系列的算法,分别封装起来,让他们之间可以互相替换。此模式让算法的改变不会影响到使用算法的客户。  在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对... 查看详情

设计模式之策略模式

  软件工程师都会学习设计模式,设计模式可以说是前人智慧与经验的结晶,虽然不是哪里都用得到,但是在合适的地方使用合适的设计模式,能够带来巨大的收益。我通过学习《headfirst设计模式》,逐渐掌握这些设计方法,... 查看详情

java设计模式之策略模式

    策略模式属于对象的行为模式,策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化。策略模式使这些算法在客户端调用它们... 查看详情

java设计模式之策略模式

...此模式让算法的变化,不会影响到使用算法的客户(大话设计模式)。策略模式UML图      策略模式代码   古代的各种计谋都是一种策略,这次我们的例子就拿其中一种离间计来写的,理解起来非常容易,代码... 查看详情

设计模式之策略模式20170720

行为型设计模式之策略模式:一、含义策略模式是一种比较简单的模式,也叫做政策模式,其定义如下:定义一组算法(可抽象出接口),将每个算法都封装起来,并且使它们之间可以互换(定义一个类实现封装与算法切换) 二、... 查看详情

设计模式之-策略模式(strategypattern)(代码片段)

...,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。 C++实... 查看详情

设计模式之策略模式(代码片段)

设计模式之策略模式  策略模式(StraregyPattern)是一种比较简单的模式,也叫政策模式(PolicyPattern),定义如下:Defineafamilyofalgorithms,encapsulateeachone,andmaketheminterchangeable.(定义一组算法,将每个算法都封装起来,并... 查看详情

设计模式之策略模式

目录 策略模式介绍鸭子事例简单的鸭子会飞的鸭子橡皮鸭登场噩梦开始策略模式鸭子策略模式介绍策略模式就是将功能定义为算法簇,分别封装起来,让他们之间可以替换,此模式可以让算法的变化独立于使用算法... 查看详情

设计模式之策略模式

设计模式之策略模式Jul23,2015策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。正文在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数... 查看详情

java设计模式之策略模式

1.策略模式的介绍  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。简单的... 查看详情

《设计模式之禅》--策略扩展:策略枚举

接上篇《设计模式之禅》--代理扩展:动态代理需求:加减法计算publicenumCalculator{//加法运算ADD("+"){publicintexec(inta,intb){returna+b;}},//减法运算SUB("-"){publicintexec(inta,intb){returna-b;}};Stringvalue="";//定义成员值类型privateCalculator(S 查看详情

设计模式之桥梁模式和策略模式的差别

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式。下面是它们的UML结构图。桥梁模式:策略模式:在桥接模式中,Abstraction通过聚合的方式引用Implementor。举一个样例:策略模式:我要画圆。要实心圆,... 查看详情