高效的策略模式设计方法

    在实现策略模式的时候,我们习惯用switch-case来代替if-else if-else,在代码结构上会更加清晰,但这也只是从代码结构这个层面上来考虑,我们可以从代码速度上来考虑设计问题。

    无论是switch-case还是if-else if-else的设计,都会遇到一个问题:如果判断的条件很多,假设是n个,而满足的条件恰好是最后一个,那么代码的执行效率就是o(n)。

    为了找到一个能够执行的代码,我们实际上是判断了n次,当然,这个判断其实是很快的,一般情况下的效率折损是不用考虑的,就算判断条件很多,但涉及那么多判断条件的业务场景,本身就是个灾难了。

    我们可以通过一种数据结构来解决这个问题。

    策略模式的目的就是根据某种类型寻找对应的策略,如果将该类型理解为key,而策略就是value的话,我们很快就能明白,这就是key-value的查找。

    key-value的容器类自然想到HashMap。

    在我们之前的文章 http://www.cnblogs.com/wenjiang/p/6019000.html 中提到了一个业务场景,就是根据对应的广告平台寻找对应的平台调用方法。这里利用HashMap来重新整理我们的代码结构。

    我们定义了Enum类ShowType表示要展示的广告类型,然后各种类型的Controller就是对应的策略类。

Map<ShowType, Object> controllerMap = new HashMap();
controllerMap.put(ShowType.Banner, createBannerProperties(activity, slotId, viewGroup, platforms);
...

    我们定义一个ShowType为key值,Controller为value值的HashMap,然后将对应的key-value放进去。

    原先我们是根据传进来的ShowType返回对应的Controller:

 1         Object controller = null;
 2         switch (showType) {
 3             case Banner:
 4                 properties = createBannerProperties(activity, slotId, viewGroup, platforms);
 5                 controller = ((BannerProperties) properties).getController();
 6                 break;
 7             case Feed:
 8                 properties = createFeedProperties(activity, slotId, platforms);
 9                 controller = ((MMUFeedProperties) properties).getController();
10                 break;
11             case Insert:
12                 properties = createInsertProperties(activity, slotId, platforms);
13                 controller = ((InsertProperties) properties).getController();
14                 break;
15             case LoopImage:
16                 properties = createLoopImageProperties(activity, slotId, viewGroup, platforms);
17                 break;
18             case Welcome:
19                 properties = createWelcomeProperties(activity, slotId, viewGroup, platforms);
20                 controller = ((WelcomeProperties) properties).getController();
21                 break;
22             default:
23                 break;
24         }

    上面是我们原先的实现,现在有了这个HashMap后,代码可以这样修改:

Controller controller = creatorMap.get(type);

    不仅代码上更加简洁,效率上也提升了,HashMap的查找效率是要比switch-case逐个查询要快的。

    当然,如果查询条件多的话,HashMap在设置数据的时候,也是要设置多条数据的,并且HashMap本身也是占用内存的,所以这是典型的用空间换取时间的例子,不过这点内存空间在很多场景下也是可以忽略的。

    到底选用哪种方式,取决于我们的业务场景的扩展性,如果考虑到以后我们的业务会增加更多的场景,如果不想修改暴露出去的接口方法,可以采用HashMap的方式,配置对应的类型和策略,但如果这点不计较的话,哪两种其实都是无所谓的。

posted @ 2016-11-15 21:27  文酱  阅读(1160)  评论(2编辑  收藏  举报