精华内容
下载资源
问答
  • 策略模式实例
    千次阅读
    2020-04-15 13:52:30

    设计模型之策略模式

    1. 策略模式

    1.1 定义与特点

      该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

      策略模式的主要优点如下:

    1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。
    2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
    3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
    4. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
    5. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

      策略模式的主要缺点如下:

    1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
    2. 策略模式造成很多的策略类。

    1.2 模式的结构

      策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性,现在我们来分析其基本结构和实现方法。

      策略模式的主要角色如下:

    • 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
    • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
    • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

    1.3 问题由来

      在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。如果使用多重条件转移语句实现(即硬编码),不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。

    1.4 解决思路

      将这些策略算法抽象类一个接口,具体的策略算法封装成一个一个的类,实现策略接口,当选择发生变化,我们相应的替换策略就可以实现更换策略的目的,同时不会修改原代码,遵守开闭原则。

    1.5 UML类图

      UML类图和解决方法请参考下面文章,策略模式的实现是依照依赖倒置原则的,例子和依赖倒置原则例子一样。
      设计原则之依赖倒置原则(实例加UML完整例子)

    1.6 解决方案

    更多相关内容
  • 策略模式的意义是定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。 一个小例子就能让我们一目了然。 回忆下jquery里的animate方法. 代码如下: $( div ).animate( {“left: 200px”}, 1000, ...
  • 本文实例讲述了Python设计模式之策略模式。分享给大家供大家参考,具体如下: 策略模式(Strategy Pattern):它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户. ...
  • 策略模式实例

    2013-07-24 16:00:38
    策略模式简单实例,只用于做简单介绍演示; 策略模式简单实例,只用于做简单介绍演示。
  • 本文实例讲述了php设计模式之策略模式。分享给大家供大家参考,具体如下: 星际开地图对战,等5秒钟进入地图后,每个玩家都会拥有一个基地,几个农民等,还会有初始的人口供给。但这些是根据种族的不同而不同。 待...
  • 策略模式例子,纯代码,copy后即可运行; 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中...
  • 策略模式 实例代码

    2015-10-15 15:47:45
    《 HeadFirst设计模式》中介绍的第一个模式——策略模式的代码
  • 策略模式实例策略模式实例策略模式实例策略模式实例策略模式实例
  • NULL 博文链接:https://xuningxiaoni.iteye.com/blog/415879
  • vs2010策略模式实例

    2010-11-28 15:47:19
    vs2010策略模式实例 对字符串加密的不同算法用策略模式实现
  • 设计模式之策略模式实例+Demo)

    万次阅读 多人点赞 2018-03-09 21:24:58
    马上要放清明小长假了,各位都想好去哪里玩了没?清明前的周日,整理下发型,... 策略模式的实现及实例。5. 策略模式的优缺点。6.其他 1. 为什么要写这篇文章? 简单来说四个字:记录分享。用来记录供自己快速...

    马上要放清明小长假了,各位都想好去哪里玩了没?清明前的周日,整理下发型,梳理好心情,发个文章,再思考下清明去哪玩,哈哈哈。

    这里写图片描述

    不多废话,切入正题:

    你从本文主要能了解到如下几点:1. 为什么要写这篇文章?2. 什么是策略模式?3.设计原则 4. 策略模式的实现及实例。5. 策略模式的优缺点。6.其他

    1. 为什么要写这篇文章?

    简单来说四个字:记录分享。用来记录供自己快速回顾,分享所学,供他人学习点评参考。

    2. 什么是策略模式?

    这个在文章末尾会给出解释,看耐心看完实例,相信你再看到定义会有更深刻的印象。

    3. 设计原则:

    设计原则有很多,这里直说策略模式中使用到的,参看实例思考哪些地方有用到下面的设计模式:
    1. 封装变化(找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。)
    2. 针对接口,超类编程,而不是针对实现编程。
    3. 多用组合,少用继承。

    4. 策略模式的实现及实例:

    假设我们现在正在开发一款类似植物大战僵尸的游戏产品,产品经理告诉我们说:所有僵尸的必要条件是可以动,可以攻击,外观上可以区分就可以了。
    这没问题,写一个抽象类Character,然后让所有角色(僵尸)继承这个类就可以了。So Easy.

    抽象类

    public abstract class Character {
        void move(){
            System.err.println("move");
        }
        void attack(){
            System.err.println("attack");
        }
        abstract void display();
    }
    public class RedHeadZombie extends Character {//红头僵尸
        @Override
        void display() {
            System.err.println("My head is Red");
        }
    }

    绿头僵尸:

    public class GreenHeadZombie extends Character {
        @Override
        void display() {
            System.err.println("My head is Green");
        }
    }
    

    写完了,问题解决,正准备看看新闻资讯的时候,产品经理走过来对我说,我们需要给我们每个僵尸设置一个前进速度,而且速度要有区别,不能所有僵尸都一样的。好吧,设置速度嘛,也简单,我在抽象类里面添加一个speed的方法,让红头僵尸和绿头僵尸都分别实现这个方法。也不难,分分种搞定。

    public abstract class Character {//抽象类
        ……
        abstract void speed();
    }
    
    public class GreenHeadZombie extends Character {//绿头僵尸
        ……
        @Override
        void speed() {
            System.err.println("speed is 1.0");
        }
    }
    public class RedHeadZombie extends Character {//红头僵尸
        ……
        @Override
        void speed() {
            System.err.println("speed is 3.0");
        }
    }

    这里写图片描述

    好吧,该有的速度也有了,提交代码,这下满足你了吧,产品经理这时走过来告诉你,僵尸的攻击方式不能一样的,你怎么让所有僵尸的攻击方式都一样了,这肯定不行的。好像有点道理的样子,那我就改咯。我重写所有的attack方法不就行了。

    public class RedHeadZombie extends Character {//红头僵尸
        ……    
        @Override
        void attack() {
            System.err.println("RedHeadZombie's attack");
        }
    }
    public class GreenHeadZombie extends Character {//绿头僵尸
          ……
        @Override
        void attack() {
            System.err.println("GreenHeadZombie's attack");
        }
    }

    修改完成,攻击方式也不一样了。
    这里写图片描述

    这时候我偷偷瞄了一眼产品经理,发现这货正在看翘着二郎腿听歌呢!心里不服气,就多看了他一眼,然后眼神就对上了。这时他就缓慢放下他那秀气的腿,向我走过来……此处略掉一万字。反正最后结果就是,他觉得需要再添加两种僵尸(短腿僵尸,无攻击力僵尸),短腿僵尸速度很慢,但是可以远程攻击,无攻击力僵尸(不知道用来干嘛,可能是后勤部队,用来给其他僵尸运送军火的)。可以移动,但是不能攻击。还是乖乖写吧,继续写两个类ShortLegZombie(短腿),NoAttackZombie(无攻击)继承自Character.

    public class ShortLegZombie extends Character {//短腿僵尸
        @Override
        void display() {
            System.err.println("I'm ShortLegZombie");
        }
    
        @Override
        void speed() {
            System.err.println("speed is slow");
        }
    
        @Override
        void attack() {
            System.err.println("ShortLegZombie's attack");
        }
    }
    public class NoAttackZombie extends Character {//无攻击力僵尸
        @Override
        void display() {
            System.err.println("I'm NoAttackZombie");
        }
    
        @Override
        void speed() {
            System.err.println("speed is 5.0");
        }
    
        @Override
        void attack() {
            //nothing to do
        }
    }

    完成了,还好,不算太慢。搞定。
    这里写图片描述

    过一会会,产品经理又走过来和我说,刚刚开会了,我们最后的决定是,你们开发再多添加下面几种僵尸来增加游戏的可玩性,丰富界面,提高用户可选性,辛苦你们了,最近加加班咯。好吧,一看,四十几种。
    这里写图片描述

    //好吧好吧,我写,我写可以吧?……四十几个僵尸类继承Character重写不同的diaplay(),speed(),attack()方法。(这个僵尸类百分百有其他变动,先写两个,等你下个需求我再看怎么修改咯!)

    又添加了几个僵尸类,先拿给产品看一下。产品一看,眼睛微眯,皱着眉头:你这不行呀,你这僵尸怎么速度都是不变的?你遇到障碍物肯定的减速,没有障碍物得加速呀,这个要修改。僵尸在起跑线应该都不具有攻击方式,你这个攻击方式需要修改下。 听你这么一说好像有点道理,当僵尸满足某个条件时修改下速度状态和攻击方式。当是我现在已经创建十几个僵尸类了,这要修改的工作量有点大呀!而且还有几十种都没写上去呢!

    能不能优化一下代码,让新建一个僵尸类的时候尽量用几行代码就搞定?而且可以随时修改其状态。

    这样我们重写梳理下思路:我们编写一个抽象类(Character),让所有的僵尸都继承这个类。速度和攻击方式是可以动态改变的。我们将需要动态改变的部分抽取出来。我们分别编写ISpeedBehavior和IAttackBehavior两个接口,将所有的速度和攻击行为都抽取出来。速度和攻击这里暂时写三种:
    这里写图片描述
    接下里我们重新整理我们的代码:

    抽象类Character及子类

    public abstract class Character {//抽象类
    
        public IAttackBehavior mIAttackBehavior;
        public ISpeedBehavior mISpeedBehavior;
    
        void move(){
            System.err.println("move");
        }
        void attack(){
            mIAttackBehavior.attack();
        }
        void speed(){
            mISpeedBehavior.speed();
        }
    
        public void setIAttackBehavior(IAttackBehavior IAttackBehavior) {
            mIAttackBehavior = IAttackBehavior;
        }
    
        public void setISpeedBehavior(ISpeedBehavior ISpeedBehavior) {
            mISpeedBehavior = ISpeedBehavior;
        }
    
        abstract void display();
    }
    public class RedHeadZombie extends Character {//红头僵尸
        public RedHeadZombie(IAttackBehavior iAttackBehavior, ISpeedBehavior iSpeedBehavior) {
            mIAttackBehavior = iAttackBehavior;
            mISpeedBehavior = iSpeedBehavior;
        }
        @Override
        void display() {
            System.err.println("My head is Red");
        }
    }
    

    ……

    攻击行为类接口:IAttackBehavior及实现类

    public interface IAttackBehavior {
        void attack();
    }
    
    public class OrdinaryAttack implements IAttackBehavior {
        @Override
        public void attack() {
            System.err.println("I use ordinary attack");
        }
    }

    ……

    速度接口ISpeedBehavior及子类:

    public interface ISpeedBehavior {
        void speed();
    }
    public class NormalSpeed implements ISpeedBehavior{
        @Override
        public void speed() {
            System.err.println("My speed is Normal!");
        }
    }

    ……

    最终动态修改速度和攻击的操作:

    /**
     * 策略模式
     */
    public class StrategyActivity extends AppCompatActivity {
    
    
        @BindView(R.id.zombie_tv)
        TextView mZombieTv;
        @BindView(R.id.speed_tv)
        TextView mSpeedTv;
        @BindView(R.id.attack_tv)
        TextView mAttackTv;
    
        private Character mCharacter;
        private IAttackBehavior mIAttackBehavior;
        private ISpeedBehavior mISpeedBehavior;
        private int mRandomZombieNum = 0;
        private int mRandomSpeedNum = 0;
        private int mRandomAttackNum = 0;
        private Random mRandom;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_strategy);
            ButterKnife.bind(this);
            //默认设置
            mIAttackBehavior = new OrdinaryAttack();
            mISpeedBehavior = new NormalSpeed();
            mCharacter = new RedHeadZombie(mIAttackBehavior,mISpeedBehavior);
            mRandom = new Random();
        }
    
        @OnClick({R.id.btn_change_zombie, R.id.btn_change_speed, R.id.btn_change_attack})
        public void onViewClicked(View view) {
            switch (view.getId()) {
                case R.id.btn_change_zombie:
                    mRandomZombieNum = mRandom.nextInt(4);
                    switch (mRandomZombieNum){
                        case 0:
                            mCharacter = new RedHeadZombie(mIAttackBehavior,mISpeedBehavior);
                            mZombieTv.setText("红头僵尸");
                            break;
                        case 1:
                            mCharacter = new GreenHeadZombie(mIAttackBehavior,mISpeedBehavior);
                            mZombieTv.setText("绿头僵尸");
                            break;
                        case 2:
                            mCharacter = new ShortLegZombie(mIAttackBehavior,mISpeedBehavior);
                            mZombieTv.setText("短腿僵尸");
                            break;
                        case 3:
                            mCharacter = new NoAttackZombie(mIAttackBehavior,mISpeedBehavior);
                            mZombieTv.setText("无攻击力僵尸");
                            break;
                    }
                    mCharacter.attack();
                    mCharacter.speed();
                    break;
                case R.id.btn_change_speed:
                    mRandomSpeedNum = mRandom.nextInt(3);
                    switch (mRandomSpeedNum){
                        case 0:
                            mISpeedBehavior = new NormalSpeed();
                            mSpeedTv.setText("My speed is normal");
                            break;
                        case 1:
                            mISpeedBehavior = new SlowSpeed();
                            mSpeedTv.setText("My speed is slow");
                            break;
                        case 2:
                            mISpeedBehavior = new FastSpeed();
                            mSpeedTv.setText("My speed is fast");
                            break;
                    }
                    mCharacter.setISpeedBehavior(mISpeedBehavior);
                    mCharacter.speed();
                    break;
                case R.id.btn_change_attack:
                    mRandomAttackNum = mRandom.nextInt(3);
                    switch (mRandomAttackNum){
                        case 0:
                            mIAttackBehavior = new OrdinaryAttack();
                            mAttackTv.setText("I use ordinary rtdinary attack");
                            break;
                        case 1:
                            mIAttackBehavior = new ReinforceAttack();
                            mAttackTv.setText("I use ordinary reinforce attack");
                            break;
                        case 2:
                            mIAttackBehavior = new SuperAttack();
                            mAttackTv.setText("I use ordinary super attack");
                            break;
                        case 3:
                            break;
                    }
                    mCharacter.setIAttackBehavior(mIAttackBehavior);
                    mCharacter.attack();
                    break;
            }
        }
    }

    这下ok了,随便你添加角色,随便你修改速度和攻击状态,我能随时修改。

    这里写图片描述

    效果图:
    这里写图片描述

    现在,我们来说下什么是策略模式?没错,我们上面的实例用的就是策略模式,分别将程序中变化的部分封装起来,让它们之间可以相互替换(速度和攻击行为)。也就是说策略模式可以让算法的变化独立于使用算法的客户。

    5. 策略模式的优缺点

    无论哪种模式都有其优缺点,当然我们每次在编写代码的时候需要考虑下其利弊。
    策略模式的优点:
    1. 提供了快速替换继承关系的办法:案例中的我们能快速的替换僵尸类,速度,攻击类型。
    2. 减少代码中的if else 等判断语句:我们在更换攻击状态的时候不用去判断,当达到某个条件时直接切换攻击实现类就可以了。比如上文中的普通攻击变超级攻击。
    3. 实现的选择:策略模式可以提供不同的实现。
    策略模式的缺点:
    1. 策略模式会造成很多策略类:上文中的所有速度实现类,攻击实现类……
    2. 通讯开销很大:比如我们上面的速度接口的speed需要传递3个参数。这三个参数对有的僵尸类是有意义的,对大部分僵尸无意义,这时候就会造成没必要的通讯开销。
    3. 必须自行知道所有的实现类有何不同?每次新建一个僵尸类的时候必须要知道所有的速度类及攻击实现类的不同。此时这些就会暴露出具体的实现问题。因此只有当行为类和角色行为相关的时候才需要使用策略模式。

    6. 总结

    现在我们回顾下刚开始说的策略模式所用到的三个设计原则:
    1. 封装变化。我们将变化的速度和攻击行为封装出来,供动态改变调用。
    2. 针对接口,超类编程,不针对实现编程。我们用ISpeedBehavior和IAttackBehavior接口去代表速度和攻击行为,每种具体的行为实现其中一个接口。
    3. 多用组合,少用继承。组合最大的好处就是具有弹性,给代码维护和需求修改提供极大的便利。刚开始我们使用的就是继承的方式,在添加大量僵尸类的时候,代码的维护及修改量将非常大。后面优化过后我们就使用了速度和攻击类及僵尸类的组合去编写代码。

    其实策略模式在游戏开发中是经常会使用到的。比如说街机西游机,有不同的角色,猪八戒,白龙马,孙悟空。他们都有武器,武器可能被妖怪打掉,也能自己捡起来。还能发不同的招数。当然这个就不编写代码了,重在思路。

    最后,大家如果在学习的过程中有疑惑或者对本文的讲解觉得哪些地方值得改进,可以在评论下面留言。

    这里写图片描述

    打赏关注

    If you find this repository helpful, you may make a donation to me via alipay or wechat.

    坚持原创技术分享,您的支持将鼓励我继续创作!

    微信打赏:支付宝打赏:知识星球:微信公众号:
    微信支付这里写图片描述这里写图片描述aserbao
    展开全文
  • 主要介绍了C#策略模式(Strategy Pattern),以一个简单的实例讲述了C#策略模式的实现方法,包括策略模式的用途以及具体实现方法,需要的朋友可以参考下
  • java策略模式实例解析

    千次阅读 2018-06-10 01:05:41
    java策略模式实例解析####1、策略模式概述: 策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式。策略模式是...

    java策略模式实例解析####1、策略模式概述:

    策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式。策略模式是一种行为型模式《设计模式的艺术》

    使用场景:

    策略模式常用于解决某一个问题,或者是实现某个功能时会存在多种实现方法,因而将每个方法进行一定的封装,由使用者决定使用哪种方法。

    2、策略模式UML类图:

    image.png
    Context(环境类):环境类作为策略的使用者,在实现某种功能时可以采取多种方法来实现。在环境类中维护一个策略类的引用,调用策略类的方法。
    Strategy(抽象策略类):作为策略类的公共父类,定义策略类的基础方法。
    ConcreteStrategy(具体策略类):实现抽象策略类中定义的公共接口,完成具体功能。

    3、策略模式示例:

    策略模式实现:
    /**
     * 视频播放器:环境类
     */
    public class MediaPlayer {
    
        private Decoder decoder;
    
        public void setDecoder(Decoder decoder) {
            this.decoder = decoder;
        }
    
        public void decodeVideo() {
            decoder.decodeVideo();
        }
    }
    /**
     * 抽象策略类
     */
    public abstract class Decoder {
    
        abstract void decodeVideo();
    }
    public class MediaCodecDecoder extends Decoder {
    
        @Override
        void decodeVideo() {
            System.out.println("this is MediaCodecDecoder");
        }
    }
    public class FfmpegDecoder extends Decoder {
        @Override
        void decodeVideo() {
            System.out.println("this is FfmpegDecoder");
        }
    }

    上面示例为一个视频播放器模块,由于播放器在解码的时候可以选择多种解码方法, 因此设计时采用策略模式。将每种解码方法封装成一个类,抽象出一个Decoder抽象类,定义解码的标准接口。播放器内部维护一个Decoder对象,根据当前码率以及平台决定使用哪种解码方式。

    4、优缺点分析:

    优点:

    1)策略模式完美体现类开闭原则,扩展性非常好;
    2)使用策略模式与状态模式有个共同有点,避免大量判断逻辑代码;

    缺点:

    1)客户端需要知道所有策略类,自行决定使用哪一种策略;
    2)当有新策略产生时需要增加一个策略类,导致系统的类会越来复杂;

    结束语

    策略模式只适用于一个问题对应多种解决方案的场景,如果不满足次条件不要滥用。相对来说,策略模式理解很简单。

    展开全文
  • 01-策略模式 代码实例

    2017-06-22 11:01:11
    01-策略模式.rar,01-策略模式,bin,com,example,firstduck,RedHeadDuck.class,Duck.class,GreenHeadDuck.class,twoduck,main.class,QuackBehavior.class,GaGaQuackBehavior.class,GoodFlyBehavior.class,FlyBehavior....
  • 【设计模式】策略模式demo,用java实现的,简单易懂,亲测有效
  • 本文实例讲述了PHP设计模式之策略模式原理与用法。分享给大家供大家参考,具体如下: 策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。 策略模式指的是...
  • 1.如果用户选择选项1,请运行类PlainTextStudentsFormatter的单例实例的setStudentsFormatter方法,并调用displa
  • java策略模式

    2017-06-19 22:13:57
    策略模式.zip,策略模式,ShopopingCart_Strategy,bin,com,whf,strategy,Context.class,LianHuanHuaPrice.class,Price.class,OrtherBookPrice.class,ComputerBookPrice.class,JiaoChaiPrice.class,Client.class,....
  • 在看《C++设计新思维》的时候,发现在一开始就大篇幅的介绍策略模式(policy),策略模式不属于经典设计模式中的一种,但是其实在我们日常的开发中是必不可少的。policy,策略,方针,这里的意思是指把复杂功能的类...
  • 本文实例讲述了javascript设计模式 – 策略模式原理与用法。分享给大家供大家参考,具体如下: 介绍:策略模式中可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法。在这里,每一种算法的封装都...
  • 采用工厂模式 + 策略模式 定义策略接口: package com.xhwl.smarthome.service; /** * @author wangxinyu * * @date 2021/11/19 * 设备注册策略接口 */ public interface DeviceRegisterStrategy { Object ...

    项目背景:

    由于做的是物联网项目,现在需要实现的是网关入网+子设备注册;网关有3个逻辑,分别为首次入网、解绑后同一个人入网(恢复)、解绑后换人入网(换人)、子设备注册;

    原先写法是:

    if(type == 1){
        doSomeThing()   //首次入网
    }else if(type == 2){
        doSomeThing()   //恢复
    }else if(type == 3){
        doSomeThing()   //换人注册
    }else if(type == 4){
        doSomeThing()   //子设备注册
    }

    采用这种方式即代码无法复用,存在许多重复代码块。代码都是垂直写到底,然后换另一个type 也是垂直写到底 ;并且每个 if 中若逻辑复杂,其实代码看起来也非常晦涩;

    采用工厂模式 + 策略模式

    定义策略接口:

    package com.xhwl.smarthome.service;
    
    
    /**
     * @author wangxinyu
     * * @date 2021/11/19
     * 设备注册策略接口
     */
    public interface DeviceRegisterStrategy {
    
        Object callIoTRegisterDevice(xxxx);
    
    }
    

    定义策略实现类:

    首次入网:

    package com.xhwl.smarthome.service.impl;
    
    
    /**
     * @author wangxinyu
     * @since 2021/11/19
     * 首次注册策略(网关)
     */
    @Component
    public class FirstRegStrategy implements DeviceRegisterStrategy {
    
        @Override
        public Object callIoTRegisterDevice(xxxxx){
              doSomeThing();    //自定义策略逻辑
        }
    }
    

     恢复(解绑后同一个人入网):

    package com.xhwl.smarthome.service.impl;
    
    
    /**
     * @author wangxinyu
     * @since 2021/11/19
     * 同个人二次注册同一网关设备策略
     */
    @Component
    public class RecoverRegStrategy implements DeviceRegisterStrategy {
    
        @Override
        public Object callIoTRegisterDevice(xxxx) {
            doSomeThing(); //自定义策略逻辑
        }
    
    }
    

    换人注册:

    package com.xhwl.smarthome.service.impl;
    
    
    
    /**
     * @author wangxinyu
     * @since 2021/11/19
     * 换人后注册网关设备策略
     */
    @Component
    public class ReplaceRegStrategy implements DeviceRegisterStrategy {
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public Object callIoTRegisterDevice(xxxxx) {
            doSomeThing();  //自定义逻辑
        }
    }
    

    子设备注册:

    package com.xhwl.smarthome.service.impl;
    
    
    /**
     * @author wangxinyu
     * @since 2022/1/4
     * 子设备注册策略,与网关分开有以下几个考虑:
     * 1、网关逻辑不需要这么多产品校验加工(子设备) , 业务剥离
     * 2、子设备注册返回参数与网关已经不同
     * 3、子设备后续会不断新增加工逻辑,而网关不需要;
     */
    @Slf4j
    @Component
    public class SubDeviceRegStrategy implements DeviceRegisterStrategy {
    
        @Override
        public Object callIoTRegisterDevice(xxxxxxx) {
            doSomeThing();  //自定义逻辑
        }
    }
    

    策略类都定义完了,现在则需要一个工厂模式将其加入到Spring中管理,并在需要时依赖注入

    定义一个工厂类:

    package com.xhwl.smarthome.factory;
    
    import com.xhwl.smarthome.service.DeviceRegisterStrategy;
    import com.xhwl.smarthome.service.impl.FirstRegStrategy;
    import com.xhwl.smarthome.service.impl.RecoverRegStrategy;
    import com.xhwl.smarthome.service.impl.ReplaceRegStrategy;
    import com.xhwl.smarthome.service.impl.SubDeviceRegStrategy;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author wangxinyu
     * @since 2021/11/19
     */
    @Component
    public class DeviceRegisterStrategyFactory {
    
        private static final Map<String, DeviceRegisterStrategy> map = new HashMap<>(4);
    
        @Autowired
        private FirstRegStrategy firstRegStrategy;
    
        @Autowired
        private RecoverRegStrategy recoverRegStrategy;
    
        @Autowired
        private ReplaceRegStrategy replaceRegStrategy;
    
        @Autowired
        private SubDeviceRegStrategy subDeviceRegStrategy;
    
        @PostConstruct
        public void initDeviceRegisterStrategy(){
            map.put("FirstRegister",firstRegStrategy);
            map.put("RecoverRegister",recoverRegStrategy);
            map.put("ReplaceRegister",replaceRegStrategy);
            map.put("SubDeviceRegister",subDeviceRegStrategy);
        }
    
        public static DeviceRegisterStrategy getDeviceRegisterStrategy(String name) {
            return map.get(name);
        }
    
    }
    

    目前改造已经完毕 , 使用时只需要通过工厂类的静态方法 getDeviceRegisterStrategy() 接收一个策略 name 即可 ;为了便于管理 ,name 也可以定义枚举类 ;

    package com.xhwl.smarthome.pojo.enums;
    
    /**
     * @author wangxinyu
     * * @date 2021/11/19
     */
    public enum RegisterEnum {
        FIRST_REG(1,"FirstRegister"),
        RECOVER_REG(2,"RecoverRegister"),
        REPLACE_REG(3,"ReplaceRegister"),
        SUB_DEVICE_REG(4,"SubDeviceRegister");
    
        private int type;
    
        private String name;
    
        public int getType() {
            return type;
        }
    
        public String getName() {
            return name;
        }
    
        RegisterEnum(int type, String name) {
            this.type = type;
            this.name = name;
        }
    
        RegisterEnum(){}
    
        public static RegisterEnum of(int type){
            for (RegisterEnum e : RegisterEnum.values()) {
                if(e.getType() == type){
                    return e;
                }
            }
            return null;
        }
    }
    

    至此,全篇结束,欢迎大佬们指点;

    展开全文
  • .................例子3_计时工资 博文链接:https://zfms.iteye.com/blog/1481020
  • 本文实例讲述了php策略模式。分享给大家供大家参考,具体如下: 策略模式和工厂模式很像。 工厂模式:着眼于得到对象,并操作对象。 策略模式:着重得到对象某方法的运行结果。 示例: //实现一个简单的计算器 ...
  • 策略模式的使用(附案例)

    千次阅读 2021-08-13 15:39:08
    1.策略模式的概念: 通俗讲它就是采用了面向对象的继承和多态机制 2.策略模式 的三个角色和基本类图 Context封装角色:上下文角色,起承上启下的封装作用,屏蔽高层模块对策略,算法的直接访问 封装可能存在的变化 ...
  • 主要介绍了Java设计模式之策略模式原理与用法,结合实例形式较为详细的分析了Java策略模式的概念、原理、定义及使用方法,并总结了相关的优缺点,具有一定参考借鉴价值,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 281,922
精华内容 112,768
关键字:

策略模式实例