• 策略模式-Strategy(Java实现)


    策略模式-Strategy

    在策略模式中,一个类(策略使用者)可以更改自己的执行策略. 比如以排序算法为例子, 多种排序算法都归属于排序算法, 但是实现的算法细节不同, 使用者可以很轻松地替换策略, 选择其中一个来执行任务.

    本文基本就是copy了一下Ilkka Seppälä(github里的iluwatar)的例子,  他的例子非常形象.

    场景是这样的: 有一个屠龙勇士, 他会替换不同的装备(策略)来对抗不同的龙.

    类关系图如下:

    依赖关系图如下:

    定义

    DragonSlayingStrategy接口

    策略模式有很多的策略, 在这里把屠龙策略抽象出来, 定义一下屠龙场景中的策略DragonSlayingStrategy接口.

    /**
     * 屠龙策略接口
     */
    @FunctionalInterface
    public interface DragonSlayingStrategy {
        void execute();
    }

    DragonSlayer类

    在这里定义了屠龙勇士DragonSlayer.

    屠龙勇士有一个默认策略, 还可以进行替换策略的操作, 还可以使用当前的策略来进行攻击.

    /**
     * 屠龙勇士
     */
    public class DragonSlayer {
        /**
         * 屠龙策略
         */
        private DragonSlayingStrategy strategy;
    
    
        /**
         * 如果是空参构造器, 那么赋上一个默认的策略
         */
        public DragonSlayer() {
            strategy = new DragonSlayingStrategy() {
                @Override
                public void execute() {
                    System.out.println("默认策略: 拳打脚踢");
                }
            };
        }
    
        /**
         * 传入一个策略, 根据这个策略来进行实例化屠龙勇士
         */
        public DragonSlayer(DragonSlayingStrategy strategy) {
            this.strategy = strategy;
        }
    
        /**
         * 策略是可以随时变的, change一下就好了
         */
        public DragonSlayer changeStrategy(DragonSlayingStrategy strategy) {
            this.strategy = strategy;
            return this;
        }
    
        /**
         * 使用当前策略来执行屠龙
         */
        public void goToBattle() {
            this.strategy.execute();
        }
    }

    实现

    基本的模型已经出来, 但是咱们还没有创建具体的策略类呢, 让我们来创建两个吧

    SpellStrategy类

    /**
     * 念魔咒策略
     */
    public class SpellStrategy implements DragonSlayingStrategy{
    
        @Override
        public void execute() {
            System.out.println("魔咒策略: 念魔咒把龙封印掉");
        }
    }

    FireStrategy类

    /**
     * 火器策略
     */
    public class FireStrategy implements DragonSlayingStrategy {
        @Override
        public void execute() {
            System.out.println("火器策略: 用火烧");
        }
    }

    Main

    这里是运行示例

    public class Main {
        public static void main(String[] args) {
            // 有一个屠龙勇士
            DragonSlayer slayer = new DragonSlayer();
    
            System.out.println("
    幼龙出现啦");
    
            slayer.goToBattle();
    
            /*-************世界安静了片刻**************-*/
    
            System.out.println("
    冰龙出现啦!");
    
            //屠龙勇士发现可以用火克制他, 于是换了火器策略, 进行攻击
            slayer.changeStrategy(new FireStrategy()).goToBattle();
    
            /*-************世界安静了片刻**************-*/
    
            System.out.println("
    远古巨龙出现啦!");
    
            // 巨龙太强大了, 只能装备好念魔咒这个技能, 然后攻击
            slayer.changeStrategy(new SpellStrategy()).goToBattle();
    
            /*-************世界安静了片刻**************-*/
    
            System.out.println("
    魔龙出现啦");
    
            // 屠龙勇士用光了所有策略, 现场学会了一个新的技能, 还没来得及给这个技能起名字呢, 屠龙要紧, 快快快
            slayer.changeStrategy(new DragonSlayingStrategy() {
                @Override
                public void execute() {
                    System.out.println("神秘技能: 顿悟出一套从天而降的掌法, 如来神掌!");
                }
            }).goToBattle();
    
            /*-************世界安静了片刻**************-*/
            System.out.println("
    神龙出现啦");
    
            // 屠龙勇士利用函数式编程发明了一种新的神级招式: 洗脑
            slayer.changeStrategy(()-> System.out.println("洗脑策略: 洗脑~~~~~~")).goToBattle();
        }
    }
    

    本文例子的代码github地址: https://github.com/GoldArowana/design-patterns/tree/master/src/main/java/com/king/patterns/strategy

  • 相关阅读:
    POJ 3683 Priest John's Busiest Day (2-SAT+输出可行解)
    Codeforces #2B The least round way(DP)
    避免死锁的银行家算法C++程序实现
    源代码编译安装MySQL5.6.12具体过程
    Android 设计模式
    Java与设计模式-适配器模式
    Java和Flex整合报错(五)
    三层架构—再思考
    怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
    找出你的短板
  • 原文地址:https://www.cnblogs.com/noKing/p/java_design_patterns_Strategy.html
Copyright © 2020-2023  润新知