你的位置:首页 > ASP.net教程

[ASP.net教程]关于模板方法和策略模式的一点思考


  该随笔的思想原点,应该算是在两三年前了。当时和一前同事聊天、不知怎得就聊到了Http访问。

  一、我记得他和我说过的第一句话,大概是:有没有已经封装好的、比较强大的HttpUtil。也可能是受业务的影响(接口对内)、我当时接触到的Http访问,大多比较“规范”,至少有一个接口约束在约定着某些东西,不至于一会传递json,返回json, 一会又要传递

  记得当时,面对这个问题时、我的第一意识:模板方法,并且似乎还在哪里见过这样的使用方式。因为:整个Http访问的流程无外乎:

  1、根据Url创建请求对象,

  2、设置请求参数,比如:不使用缓存、设置Header、Cookie、超时时间 等等。

  3、发送数据,比如:Post方法。

  4、创建响应对象

  5、接收数据。

  6、获取响应参数

  7、初上述流程之外,无论是作为Util、还是作为一个强大的框架、很有可能还进行异常处理、日志记录等附加流程。

  定义一个算法主干、将步骤的细节实现延迟到子类,使得。在基类中复用代码,形成一个继承体系,最终,只需要在最底层的类中、重写函数处理三件事,一个是提供请求地址,第二个是提供请求数据,第三个是处理响应数据,当然这样处理、默认认为请求方法已经被封装了。这么一想,这个方案似乎不错啊?

  但是,如果系统中有成百上千个需要对接的接口,结果会咋样?成百上千个类? 似乎也可以接受?

  再复杂一点,如果请求的数据可能是表单、Json、

  再多浪费一点思考的精力,如果将大量的可复用代码放入基类(访问权限是受保护的),然后在子类中选择性进行调用,似乎也可以解决上文提到的“多个变化点独立变化”的问题,但是那样一来,基类会极其臃肿,灵活性会大大降低,并且多种数据处理方式之间的耦合性会成指数级上升【这算是一种更失败的设计】。  

  

  回头瞅一眼,刚开始、模板方法也不错啊、即便一个对接接口对应一个类,在某种程度上也是可以接受的啊。毕竟每个接口都具有独立性、单个类进行对应,符合单一职责原则。如果多个接口具有相似性(指的是业务上的相似性),也可以很方便的借助模板方法的继承体系、只需新建一个Method,便可以搭建成一个简单工厂模式,以便隐藏掉更多的实现类、达到简化使用的目的。只是后来由于“多个变化点独立变化”,才引发了一些问题,如若不然,前者的设计依然可以很好地工作。那么“多个变化点独立变化”的问题,该怎么解决呢?答:策略,对每一个变化点,单独使用策略模式。至此、这个比较强大的HttpUtil,算是暂告一段落。至少,在实际应用中,以 模板方法 + 策略模式 这样的组织方式,构建出来的代码已经满足了现有需求,如有其它问题,欢迎留言。

 

  二、当我提出了模板方法之后,我问同事,有什么想法?他的回答是,似乎觉得使用了策略模式之后,模板方法就不需要了,或者说模板方法可以完全被策略模式所替代。并且我当时也有一个错误认知,模板方法 = 一组策略模式。在代码效果上来看,模板方法 和 一组策略模式 确实是可以划等号的,但两者真的“相等”吗? 如果相等,那么模板方法似乎没必要存在了?我们先看一下两者的意图吧:

  模板方法的意图:定义一个算法流程,将一些特定步骤的具体实现、延迟到子类。使得可以在不改变算法流程的情况下,通过不同的子类、来实现“定制”流程中的特定的步骤。

  策略模式的意图:使不同的算法可以被相互替换,而不影响客户端的使用。

  在意图上看,模板方法更加强调:

  1)定义一条线(算法流程),线上的多个点是可以变化的(具体实现在子类中完成),线上的多个点一定是会被执行的,并且一定是按照特定流程被执行的。

  2)算法流程只有唯一的入口,对于点的访问是受限的【通常用受保护的虚函数来定义可变点】。

  策略模式更注重于: 一个“策略”是一个整体的(完整的)算法,算法是可以被整体替换的。而模板方法只能被替换其中的特定点,算法流程是固定不可变的。

  

  在这样的细节上看来,模板方法 和 一组策略模式 是不可以划等号的。

 

  三、在这个“古老”的模式——模板方法面前,似乎 “优先使用对象组合,而不是继承” 的策略模式 很是趾高气昂?我个人还是觉得、各有优缺,只是各自适应的场景不一样而已。当遇到“多个变化点独立变化”时,这时就需要策略模式来救场了,如若不然,原有架构可以很好地进行维护和扩展,那还有必要去大动干戈、非要去找到那个暂时最完美的答案吗?似乎没有吧。

 

  四、附参考资料《设计模式精解》: