策略设计模式解读

news2024/11/27 12:40:47

目录

问题引进

鸭子问题

传统方案解决鸭子问题的分析和代码实现

传统的方式实现的问题分析和解决方案

策略模式基本介绍

基本介绍

策略模式的原理类图

策略模式解决鸭子问题

 策略模式的注意事项和细节


问题引进

鸭子问题

编写鸭子项目,具体要求如下:
1) 有各种鸭子(比如 野鸭、北京鸭、水鸭等, 鸭子有各种行为,比如 叫、飞行等)
2) 显示鸭子的信息

传统方案解决鸭子问题的分析和代码实现

传统的设计方案(类图)

代码实现 

Duck 

public abstract class Duck {
    public Duck() {
    }
    public abstract void display();//显示鸭子信息
    public void quack() {
        System.out.println("鸭子嘎嘎叫~~");
    }
    public void swim() {
        System.out.println("鸭子会游泳~~");
    }
    public void fly() {
        System.out.println("鸭子会飞翔~~~");
    }
}

PekingDuck  

public class PekingDuck extends  Duck{
    @Override
    public void display() {
        System.out.println("~~北京鸭~~~");
    }

    //因为北京鸭不能飞翔,因此需要重写 fly
    @Override
    public void fly() {
        System.out.println("北京鸭不能飞翔");
    }
}

ToyDuck  

public class ToyDuck extends  Duck{
    @Override
    public void display() {
        System.out.println("玩具鸭");
    }
    //需要重写父类的所有方法
    public void quack() {
        System.out.println("玩具鸭不能叫~~");
    }
    public void swim() {
        System.out.println("玩具鸭不会游泳~~");
    }
    public void fly() {
        System.out.println("玩具鸭不会飞翔~~~");
    }

}

WildDuck  

public class WildDuck extends  Duck{
    @Override
    public void display() {
        System.out.println(" 这是野鸭 ");
    }
}

传统的方式实现的问题分析和解决方案


1) 其它鸭子,都继承了 Duck 类,所以 fly 让所有子类都会飞了,这是不正确的
2) 上面说的 1 的问题,其实是继承带来的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。会有溢出效应
3) 为了改进 1 问题,我们可以通过覆盖 fly 方法来解决 => 覆盖解决
4) 问题又来了,如果我们有一个玩具鸭子 ToyDuck, 这样就需要 ToyDuck 去覆盖 Duck 的所有实现的方法 => 解决思路 -》 策略模式 (strategy pattern) 

策略模式基本介绍

基本介绍

1) 策略模式(Strategy Pattern)中,定义算法族(策略组),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
2) 这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合/聚合,少用继承(客户通过组合方式使用策略)。

策略模式的原理类图

说明:从上图可以看到,客户 context 有成员变量 strategy 或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定 

策略模式解决鸭子问题

1) 应用实例要求
编写程序完成前面的鸭子项目,要求使用策略模式
2) 思路分析(类图)
策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为的变化独立于算法的使用者

代码实现 

FlyBehavior  

public interface FlyBehavior {

    void fly(); // 子类具体实现
}

BadFlyBehavior  

public class BadFlyBehavior implements  FlyBehavior{

    @Override
    public void fly() {
        System.out.println("飞翔技术一般");
    }
}

GoodFlyBehavior  

public class GoodFlyBehavior implements  FlyBehavior {

    @Override
    public void fly() {
    // TODO Auto-generated method stub
        System.out.println(" 飞翔技术高超 ~~~");
    }
}

NoFlyBehavior  

public class NoFlyBehavior implements  FlyBehavior{
    @Override
    public void fly() {
        System.out.println("不会游泳");
    }
}

Duck  

public abstract class Duck {
    //属性, 策略接口
    FlyBehavior flyBehavior;
    public Duck() {
    }
    public abstract void display();//显示鸭子信息
    public void fly() {
        //改进
        if(flyBehavior != null) {
            flyBehavior.fly();
        }
    }
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
}

ToyDuck  

public class ToyDuck extends  Duck{
    public ToyDuck() {
        flyBehavior = new NoFlyBehavior();
    }
    @Override
    public void display() {
        System.out.println("玩具鸭");
    }

}

WildDuck  

public class WildDuck extends Duck{
    @Override
    public void display() {
        System.out.println("野鸭");
    }

    public WildDuck() {
        flyBehavior =new GoodFlyBehavior();
    }

}

PekingDuck   

public class PekingDuck  extends  Duck{

    //假如背景鸭可以游泳但飞翔技术一般
    public PekingDuck() {
        flyBehavior =new BadFlyBehavior();
    }

    @Override
    public void display() {
        System.out.println("北京鸭");
    }
}

 策略模式的注意事项和细节

1) 策略模式的关键是:分析项目中变化部分与不变部分
2) 策略模式的核心思想是:多用组合/聚合 少用继承;用行为类组合,而不是行为的继承。更有弹性
3) 体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多重转移语句(if..else if..else)
4) 提供了可以替换继承关系的办法: 策略模式将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展
5) 需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GlobalMapper精品教程】059:基于las点云创建数字高程地形并二三维着色显示

本文讲述在globalmapper免费中文版中基于地形点云las数据创建数字高程地形、数字高程二三维联动可视化并进行数字高程着色显示。 文章目录 一、加载地形点云las数据二、创建数字高程地形三、数字高程二三维联动可视化四、数字高程着色显示相关阅读:ArcGIS实验教程——实验二十…

如何看待 Facebook 上线支付功能?

随着科技的不断进步,电子支付在我们的生活中变得越来越普遍。最近,Facebook宣布推出自己的支付功能,这引起了广泛的关注和讨论。作为世界上最大的社交媒体平台之一,Facebook进入支付领域的举措无疑具有重要意义。那么,…

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager

Jetpack Compose:使用PagerIndicator和Infinity实现滚动的HorizontalPager 可能你已经知道,Jetpack Compose 默认不包含内置的ViewPager组件。然而,我们可以通过在 build.gradle 文件中添加 accompanist 库依赖,将 ViewPager 功能…

有了这套方案,企业降本增效不再是纸上谈兵 (2)

一、生存压力逼近,企业如何应对经济下行残酷挑战? 当前市场经济下滑,客户预算紧缩和投资削减可能导致IT项目推迟或取消,从而直接影响公司收入和盈利能力。各大厂商都在陆续裁员或调整业务,以人力等成本为主的IT公司也必…

双塔模型dssm实践

最近在学习向量召回,向量召回不得不用到dssm双塔模型,双塔模型的原理非常简单,就是用两个任务塔,一个是query侧的query任务塔,另一个是doc侧的doc任务塔,任务塔向上抽象形成verctor隐向量后,用c…

【多同步挤压变换】基于多同步挤压变换处理时变信号和噪声信号研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

2022年国赛高教杯数学建模B题无人机遂行编队飞行中的纯方位无源定位解题全过程文档及程序

2022年国赛高教杯数学建模 B题 无人机遂行编队飞行中的纯方位无源定位 原题再现 无人机集群在遂行编队飞行时,为避免外界干扰,应尽可能保持电磁静默,少向外发射电磁波信号。为保持编队队形,拟采用纯方位无源定位的方法调整无人机…

win10录屏软件哪个好用?强烈推荐这3款!

案例:想要录制我的电脑屏幕,但是不知道如何选择合适的录屏工具,有没有好用的win10录屏软件? 【我想找一款好用的win10录屏工具,录制我的电脑屏幕,但是找了很久还没有找到,大家有好用的录屏软件…

Kibana:使用 Kibana 自带数据进行可视化(二)

在今天的练习中,我们将使用 Kibana 自带的数据来进行一些可视化的展示。希望对刚开始使用 Kibana 的用户有所帮助。这个是继上一篇文章 “Kibana:使用 Kibana 自带数据进行可视化(一)” 的续篇。 前提条件 如果你还没有安装好自己…

占据80%中国企业出海市场,亚马逊云科技如何为出海客户提供更多资源和附加值

亚马逊云科技就可以做到,作为占据80%中国企业出海市场的亚马逊云科技,其覆盖全球的业务体系,从亚马逊海外购、亚马逊全球开店、亚马逊智能硬件与服务,Amazon Alexa,Amazon Music都是属于亚马逊云科技“梦之队”的一员。…

【Android】WMS(二)Window的添加

软件盘相关模式 在 Android 应用开发中,软键盘的显示与隐藏是一个经常出现的问题,而 WindowManager 的 LayoutParams 中定义的软键盘相关模式则为开发者提供了一些解决方案。 其中,SoftInputMode 就是用于描述软键盘的显示方式和窗口的调整…

【LeetCode】HOT 100(6)

题单介绍: 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

python包装与授权

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和…

ai聊天对话工具哪种好用?这些ai对话聊天工具不要错过

在如今信息爆炸的时代,人工智能技术正在逐渐渗透到我们的生活和工作中。ai对话聊天技术作为其中的一项重要应用,吸引了越来越多的关注。但是,ai对话聊天技术并不是万能的,它需要一定的技巧和策略才能真正发挥其价值。那么&#xf…

CAN总线转串口

一、CAN总线在工程机械中的广泛应用 随着科技的进步和现代施工项目大型化的要求,新一代工程机械需要实现集成化操作和智能控制。CAN总线是国际上应用最广泛的现场总线之一。CAN总线以其高可靠性、实时性、无破坏仲裁、多主等特性,已广泛应用于工程机械中&#xff0c…

这里推荐几个前端动画效果网站

1. AnimistaAnimista 是一个 CSS 动画/转场库和在线工具。它有许多现成的 CSS 动画片段可以直接使用,也可以在线定制动画。 网站地址:Animista - On-Demand CSS Animations Library 2. Animate.cssAnimate.css 是一个免费的 CSS 动画库,里面有 Attention Seekers 、 Bouncing E…

【Java|多线程与高并发】线程安全问题以及synchronized使用实例

文章目录 1. 前言2. 线程安全问题演示3.线程安全问题的原因4.synchronized关键字5. 总结 1. 前言 Java多线程环境下,多个线程同时访问共享资源时可能出现的数据竞争和不一致的情况。 线程安全一直都是一个令人头疼的问题.为了解决这个问题,Java为我们提供了很多方式…

MySQL为什么有了redolog还需要double write buffer?

MySQL为什么有了redolog还需要double write buffer? 问题 我们知道MySQL InnoDB引擎使用redolog作为异常容灾恢复的机制,当MySQL进程发生异常退出、机器断电等,在重新启动时,使用redolog恢复。 OK,redolog是被MySQL…

进程同步与进程通信(#include <windows.h>)

目录 实验二 进程同步与进程通信 一、实验目的 二、实验内容 任务一、进程同步与互斥 任务二、进程通信 实验二 进程同步与进程通信 备注:大二(下)操作系统实验二 一、实验目的 掌握基本的同步与互斥算法,理解P&#xff…

移植蓝牙芯片后,PCM 无声音问题记录

背景:投影仪项目上的蓝牙模组本地已经验证ok,送到客户那里发现HFP打电话没声音。 1. 客户平台是3566,android 11的环境, 该环境下其他的模组是可以的 2. 在3566上安装QQ, 波通VOIP电话后, 无阴影, 3. 通过示波器接收pcm 无波形输出, 问题分析查证 1.查看HCI log ,…