zoukankan      html  css  js  c++  java
  • Refactoring to Patterns 项目实践

             摘要:通过重构实现、趋向和去除模式,这是我从Kerievsky那本叫Refactoring to Patterns的书中看到的。
    而今天文章的内容是一种对其思想的实践案例。有趣的是在这篇文章中所说到的代码开发和重构过程发生在
    2006年7月份, 而我看到的这本书的相关内容只是两天前的事。我在这里不是想说自已的思想与作者已经走
    到了一起,而是想说作者的思想也是从实践中来的,而我们的编程也是一种实践,这必然会有相交的可能。
    这也是为什么实践类的文章会如此受欢迎的原因。
     
              废话不多说了。


              应用场景:论坛模版生成类和用户定制生成类

              模式名称:Template Method (模版方法)

              在开始设计论坛的模版生成功能时,其实一开始程序很简单,只是用如下的方法来直接生成相关的模版
    页面:

              class PageTemplate
              {
                      //skinName 所用的皮肤名字(这与模版所存放的文件夹对应)
                      //templateName 要生成的模版页的名称
                      public static GetTemplate(string skinName, string templateName, 
              ......


              而在外面只是用一个普通类包装了一下这个方法而已。因为设计需求就是这么简单。

              但到了2006年 7月份,情况发生了变化,用户反映应该有按用户自定义变量来生成模版的功能,换句话说
    我们需要改进一下上面的那个函数了。起初我们只是想把自定义功能直接写一个方法,然后把方法的调用放到
    上面的那个函数里。但当我们完成了这个小改动后准备去做别的功能时(当时开发任务非常重,经常是要同时
    开发几个功能),雪人发现如果将来要支持第三方做模版功能的后续开发时,眼下的这个设计是无论如何也无
    法让用户满意的。就这样,雪人很快写出了如下的类来继承自上面的那个方法的封装类:
     
            public class ForumPageTemplate : PageTemplate
           {
                  public ForumPageTemplate()
                  {
                  }

                  /// <summary>
                  /// 解析特殊变量
                  /// </summary>
                  /// <returns></returns>
                  public override string ReplaceSpecialTemplate(string skinName,string strTemplate)
                  {
                            ....第三方或用户自定义模版变量要实现的功能
                  }

                 public override string GetTemplate(string skinName, string templateName, int nest,int templateid)
               {
                      return base.GetTemplate(skinName,templateName,nest,templateid);
               }

             我们设计的想法也是很简单,只想当用户调用这个类的GetTemplate 方法时,先直接调用基类PageTemplate
    中的方法,这里出现了基类上的第二次变动。首先我们把基类改成了abstract类型,然后在基类中声明了如下的
    函数:
                public abstract string ReplaceSpecialTemplate(string skinName,string strTemplate);  
                接着又去在基类的GetTemplate方法中加入对新增抽象函数的调用。

                在编译通过后,发现程序执行顺序如下,即:
                1.    先运行ForumPageTemplate.GetTemplate()
                2.    接着运行PageTemplate.GetTemplate()
                3.    PageTemplate.ReplaceSpecialTemplate()方法(当然,这是个抽象方法,它会返回并直接运行第4步)
                4.    ForumPageTemplate.ReplaceSpecialTemplate

                基本上按我们想的执行顺序运行着,就这样我们完成了这次改造(或可以称作是重构)。

             到这里可能有人会说为什么不用 virtual去实现上面的PageTemplate类中ReplaceSpecialTemplate方法,而要用
    abstract 呢?其实这也有我们的考虑, 因为我们自己定义的模块翻译过程如果我们自己去用的话,是不应该存在
    去写一个ReplaceSpecialTemplate方法,因为根本没有必要。这个函数只是用于对应一些特殊的模版,如第三方定
    制或用户自己增加的模版变量, 因此只是简单的用了abstract  来标记。另外因为virtual 的使用势必会增加系统运行
    时内存资源的消耗(这方面资料可以看一下多年前侯捷翻译的那本《c++对象模型深度探索》)。
        
             当我们完成工作后去吃中午饭的路上,我脑子里突然冒出了一张图,也就是DP上说的Template Method 的图,
    原来我们不知不觉已把这种模式在这次改造中利用上了,越想越觉得有意思。因为在这之前,我个人一直是习惯
    于在软件设计时就先用模式来打框架的,而在开发时是很不愿意做这种程序类结构上的大幅变化的。不过当看到
    这段程序经过我们这么一翻“折腾”后,功能加强了,结构也条理了,也能拿得出手了,心里还是感到很欣慰的。

             最后再套用《重构》书中的一句话“设计模式重构提供了目标”。即使达到不了目标的彼岸,也要死在这
    条通往目标的路上。因为目的只有一个,就是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质
    量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。

              代码示例:
              http://nt.discuz.net 最新的论坛版本。
       
              说明:
              PageTemplate类位于             Discuz.Common.DLL
              orumPageTemplate类位于     Discuz.Forum.DLL
              为了表明开源的决心,我们的代码未进行加密处理,可直接用reflector和相关插件反向所有代码。
       

  • 相关阅读:
    someThink
    快捷键
    typedef 的本质
    读取配置文件
    stl file
    摘自CSDNhttp://blog.csdn.net/gnuhpc/archive/2009/11/13/4808405.aspx
    thread demo
    B/S和C/S区别 java程序员
    上传文件 java程序员
    (八)VS的操作和使用技巧 java程序员
  • 原文地址:https://www.cnblogs.com/daizhj/p/599246.html
Copyright © 2011-2022 走看看