首页 > 代码库 > 高效的策略模式设计方法

高效的策略模式设计方法

    在实现策略模式的时候,我们习惯用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的方式,配置对应的类型和策略,但如果这点不计较的话,哪两种其实都是无所谓的。

高效的策略模式设计方法