• 关于模板方法和策略模式的一点思考


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

      一、我记得他和我说过的第一句话,大概是:有没有已经封装好的、比较强大的HttpUtil。也可能是受业务的影响(接口对内)、我当时接触到的Http访问,大多比较“规范”,至少有一个接口约束在约定着某些东西,不至于一会传递json,返回json, 一会又要传递xml,返回xml,甚至更奇葩的是,上传个文件、返回0或者1。如果真出现这样的状态,HttpUtil依然能够方便、灵活的适应着各种情况、我想这个Util已经绝对强大了。而不巧的是,我同事那里恰恰就是要满足这样奇葩的需求(和多个第三方进行系统对接)。

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

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

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

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

      4、创建响应对象

      5、接收数据。

      6、获取响应参数

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

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

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

      再复杂一点,如果请求的数据可能是表单、Json、Xml、文件,而响应的数据也有可能是这些、甚至更多,那么面对这样的需求,如果继续使用模板方法会咋样?仔细想想,继承可以实现代码复用、但面对上述的需求,如果只是使用继承、能实现高效复用吗(尤其是面对单继承的情况下)?请注意在这里处理请求数据 和 处理响应数据是两个变化点、并且是两个变化点独立变化,即请求数据可能是模拟的一个表单,而响应数据可能是一段Json、一段Xml、一张Image(验证码), 甚至可能是一个文件 或者一个压缩包(多个文件)。而如果请求数据是Json、Xml 等等格式,响应数据依然有可能是如上的情况。也就说一旦遇到多个变化点独立变化时,单继承瞬间就被打回原形了。

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

      

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

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

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

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

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

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

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

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

      

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

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

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

  • 相关阅读:
    两台电脑间的消息传输
    商品库存订购管理管理程序代写代做代开发
    基于ssh的汽车配件进销存系统
    Ajax初识
    系统排队仿真源代码
    模拟一个排队系统
    Linux下,C++编程论坛题目抽取
    实践是检验真理的唯一标准2 脱壳篇03
    迪杰斯特拉算法
    最短路径求法
  • 原文地址:https://www.cnblogs.com/08shiyan/p/4989203.html
Copyright © 2020-2023  润新知