大数据

程序员该如何管理后宫:怎样哄女孩儿(策略模式)

0x00 前言

试问,哪个帝王不想开疆拓土,成就万世之霸业,流传千古?!

朕,虽坐享盛世,仍不忘对外扩张以彰显国威。

近日上朝,有大臣上奏,近邻女儿国因缺乏壮丁,国力衰弱,正是入侵的最好时机。朕当然批准出兵讨伐。

这下可坏事了,朕的皇后听闻此事后,大怒!!!不再与朕言语。晚上都不让进屋了……

朕虽不才,但麾下谋士无数。找来国师gg商议。国师倒也给力,赠与朕妙计三方。依时机使用即可。

这三个妙计分别是:

  1. 夸皇后漂亮
  2. 给皇后送礼物
  3. 带皇后去看戏剧

想想看,这三个妙计有什么相似之处?这些妙计都需要朕去做些什么,也就是说,三个妙计都需要一个执行方法。至于执行方法的的内容,则由妙计决定。

0x01 论怎样哄女孩儿之策略模式

先上一个类图看看。三个妙计都实现了IStrategy接口,每一个妙计都有一个operate方法,里面是具体的妙计内容。

光有妙计还不行,我们还需要一个地方来承载妙计,这就是锦囊。下面的Context就是一个锦囊类。它负责承载和执行锦囊。

1. 代码清单 IStrategy 接口

接口很简单,就一个方法。

public interface IStrategy {
    public void operate() ;
}

2. 代码清单 PraiseStrategy类

朕来对付皇后的三个策略:夸奖、送礼、陪玩。

下面写出来一个,剩下的就不再列代码了。详细代码可以看github。

public class PraiseStrategy implements IStrategy{
    @Override
    public void operate() {
        System.out.println("yyj,你是天下第一美人~");
    }
}

3. 代码清单 Context类

这是锦囊类,代码也很简单。它主要来承载妙计。

public class Context {
    private IStrategy strategy;
    public Context(IStrategy strategy) {
        this.strategy = strategy;
    }

    public void operate() {
        this.strategy.operate();
    }
}

4. 代码清单 Emperor类

最后来看一下朕的动作。每次拿出来一个锦囊,然后执行其中妙计。

public class Emperor {
    public static void main(String[] args) {
        //拿出朕的锦囊
        Context context;

        System.out.println("------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------");
        //拿出妙计
        context = new Context(new PraiseStrategy());
        //实施妙计
        context.operate();

        System.out.println("------皇后依旧不高兴,不理朕。拆开第二个锦囊!------");
        //拿出妙计
        context = new Context(new SendGiftStrategy());
        //实施妙计
        context.operate();

        System.out.println("------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------");
        //拿出妙计
        context = new Context(new WatchDramaStrategy());
        //实施妙计
        context.operate();

        System.out.println("------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------");

    }
}

看一下执行结果。看看,一个妙计不行,就上俩,俩还不行,就来仨。最后把皇后哄开心了吧!

女孩子就是这样哄才行嘛。

------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------
yyj,你是天下第一美人~
------皇后依旧不高兴,不理朕。拆开第二个锦囊!------
yyj,我摘了个小一点的太阳当礼物送给你暖暖手~
------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------
走!朕带你去看戏!
------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------

0x02 扩展型策略模式(策略枚举)

上面已经描述了策略模式长什么样子,但是呢,这个用起来毕竟不是那么顺手,朕用一个妙计,还得先弄一个锦囊,再弄出来妙计,再执行,而且每个妙计都得写一个类,反正不管怎么样就是看着没那么爽。

下面呢,要对它做一些扩展,让它看起来更厉害一点。这就是策略枚举

1. 代码清单 Strategies枚举

这个看代码就能看出来。我们把所有的策略都写到了枚举中。相当于每个枚举成员就成了一个具体的策略。而且读起来也更容易让人理解。

public enum Strategies {
    WatchDrama {
        public void operate() {
            System.out.println("走!朕带你去看");
        }
    },
    SendGift {
        public void operate() {
            System.out.println("yyj,我摘了个小一点的太阳当礼物送给你暖暖手~");
        }
    },
    Praise {
        public void operate() {
            System.out.println("yyj,你是天下第一美人~");
        }
    };

    public abstract void operate();
}

2. 代码清单 Emperor类

看,执行类是不是也简单了,这样子更像是拿出来今年,然后执行了妙计。运行结果和之前一样,就不再贴出来了。

 System.out.println("------皇后十分不高兴,正在扔瓶子。拆开第一个锦囊!------");

        //拿出妙计,实施妙计
        Strategies.Praise.operate();

        System.out.println("------皇后依旧不高兴,不理朕。拆开第二个锦囊!------");
        //拿出妙计,实施妙计
        Strategies.SendGift.operate();

        System.out.println("------皇后态度稍缓,但仍一脸寒霜。拆开第三个锦囊!------");
        //拿出妙计,实施妙计
        Strategies.WatchDrama.operate();

        System.out.println("------皇后总算好了,不再生气了。朕可以发兵打仗了!!!------");

3. 注意

策略枚举是一个非常优秀和方便的模式,但是它受枚举类型的限制,每个枚举项都是public、final、static的,扩展性受到了一定的约束,因此在系统开发中,策略枚举一般担当不经常发生变化的角色。

0xFF 参考