zoukankan      html  css  js  c++  java
  • 策略模式-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

  • 相关阅读:
    hdu 2586 How far away ?(LCA模板题)
    Kattis
    SPOJ LEXSTR 并查集
    POJ 3159 Candies(spfa、差分约束)
    POJ 2240 Arbitrage (spfa判环)
    hdu 3974 Assign the task (线段树+树的遍历)
    POJ 2387 Til the Cows Come Home (dijkstra模板题)
    FZU 2150 Fire Game (高姿势bfs--两个起点)
    POJ 3414 Pots (dfs,这个代码好长啊QAQ)
    LightOJ 1422 Halloween Costumes
  • 原文地址:https://www.cnblogs.com/noKing/p/java_design_patterns_Strategy.html
Copyright © 2011-2022 走看看