重构CollapsibleSplitter

  RssBandit项目中的CollapsibleSplitter作为Splitter控件的改进版,提供了我梦寐以求的功能:可以像Splitter控件一样分割两个相邻控件,允许在运行时调整他们的大小,还提供了单击时最小化指定控件的功能,并在小小的分隔条上画出了相当直观的精细图案。

  这个控件有不太令人满意的地方吗?嗯,有的。它永远只能有8个像素宽(纵向摆放的时候),不能将它设成Splliter默认的4个像素宽,也不能异想天开的将它设成16个像素宽。

  打开CollapsibleSplitter的代码文件——我怎么闻到了一股不太美妙的气味呢?哦,那边Martin Fowler同志说了:这是代码的坏气味,该给它除除臭。

  那么我们就来给它消除异味吧。

  先来看看这个玩意到底有些什么坏气味:

  用了太多的switch、if语句,把面向对象的优点抛到爪哇国去了,看看这些代码吧。这是ToggleSplitter()方法里的代码,这个控件中还有很多这样的代码:

以下为引用的内容:
代码1
if(controlToHide.Visible)
{
    if(useAnimations)
    {
        
        if(parentForm != null)
        {
            if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            {
                
            }
            else
            {
                
            }
        }
        
    }
    else
    {
        
        if(expandParentForm && parentForm != null)
        {
            if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            {
                
            }
            else
            {
                
            }
        }
    }
}
else
{
    // control to hide is collapsed
    if(useAnimations)
    {
        
        if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
        {
            if(parentForm != null)
            {
                
            }
            
        }
        else
        {
            if(parentForm != null)
            {
                
            }
            
        }
        
    }
    else
    {
        // no animations, so just toggle the visible state
        
        if(expandParentForm && parentForm != null)
        {
            if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            {
                
            }
            else
            {
                
            }
        }
    }
}

 

  下面的是animationTimerTick()方法的代码(实际上还被俺去掉了几个if...else...嵌套),有这样代码的方法还有三四个:

以下为引用的内容:
代码2
switch(currentState)
{
    case SplitterState.Collapsing:
        if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
        {
            
        }
        else 
        {
            
        }
        break;

    case SplitterState.Expanding:
        if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
        {
            
        }
        else 
        {
            
        }
        break;
}

  单个方法内代码行数太多,且代码重复率高,如同老婆子般絮絮叨叨、啰唆不清。我们来看看这些长方法的代码行数和重复率:

 
ToggleSplitter()方法,89行,其中重复的语句有
if(parentForm != null),3处
if(expandParentForm && parentForm != null),2处
if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right),4处
if(useAnimations),2处
animationTimerTick(object sender, System.EventArgs e)方法,114行,其中重复的语句有
if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right),2处
if(expandParentForm && parentForm.WindowState != FormWindowState.Maximized && parentForm != null),8处
OnPaint(PaintEventArgs e)方法,254行,其中重复的语句有
if(hot),4处
if(this.Enabled),2处
switch语句(对一个参数进行判断),2处

  臭味如此明显,更显除臭工作之必要,呵呵。那我们就开始伟大的除臭工作吧,还有呢,刚才说了“它永远只能有8个像素宽”,这个特性也不太好啊:对于视力好的人,这个分割条显得如此之大;而对于有点近视的人呢,它又显得如此之小。如此,我们自然应该把这个8像素限制去掉。

  那现在我们的除臭工作目标订好了,如下:

  去掉这些讨厌的、丑陋的、像懒婆娘裹脚布般一层一层又长又臭的switch语句和if语句——即使不能完全去掉也应该把它们集合在一起,而不是到处分散;

  去掉这些千篇一律的、到处一样的、牵一发全身不得不动的重复语句;

 
  缩短这些个超过一屏的、洋洋洒洒的函数代码,把他们拆到多个方法里面去;
 

  最后,我们希望想这个玩意大的时候它就大,想它小的时候它就小,而不是总是那“8像素”宽(或高)。

时间: 2024-08-22 15:20:10

重构CollapsibleSplitter的相关文章

新闻发布系统,SQLHelper重构

在清楚把握牛腩新闻发布系统的需求,以及对系统的数据库也做好了相应的设计后,接下来的几天里就是对后台代码的编写. 在视频中,采用的是经典三层的框架,这对于已经经历过机房重构的我们来说,敲代码还是很容易上手的. 相信大家都不会忘记机房重构中我们的一个好助手,那就是SQLHelper. 在机房重构的时候,看了很多博客,大家都用上了,也都觉得好用,我也就直接借鉴而来.在自己一步一步调试的时候,在自己的程序出现Bug的时候,真的发现SQLHelper的好处多多.但自己也没有去认真研究过这样一个类究竟是怎么

产品前端重构(TypeScript、MVC框架设计)

最近两周完成了对公司某一产品的前端重构,本文记录重构的主要思路及相关的设计内容. 公司期望把某一管理类信息系统从项目代码中抽取.重构为一个可复用的产品.该系统的前端是基于 ExtJs 5 进行构造的,后端是基于 Asp.net MVC 提供的 REST 数据接口.同时,希望通过这次重构,不但能将其本身重构至可用于快速二次开发的产品,同时还要求该前端代码要保证相对的独立,使得同时可以接入 .NET 和 JAVA 两个不同的后端平台所提供的数据接口.   旧代码的问题 老系统的前端代码如下图所示:

浅谈遗留代码的重构

             背景 <重构>诞生至今有近17个年头了,日常开发中大家谈到重构,要么非常随意,认为重构就是改代码:要么非常谨慎,把重构描述成焦油坑,像瘟神一样敬而远之.针对最具挑战性的遗留代码重构,有哪些需要注意的呢? 谈论任何事情,都该有它的上下文.本文谈论的技术背景是大型通信类产品,对于互联网产品不一定适用.另外,本文也不会涉及重构技术,有兴趣读者可以读<重构>或者<Effective Refactoring in C++>. 遗留代码重构决策表 遗留代码

Hi,我们的代码重构了

 作为一名程序员,我最大的愿望是自己写的代码,能够被人称赞,一直留存在项目里,直到永远.能够让自己的代码一直留存在项目里,一方面自己写的代码要健壮,没有任何逻辑错误.另一方面,还要具有很好的扩展性,能够适应需求的变化.对于前者来说,只要有个两三年的基本功,基本上就能保证代码的质量.然而,要写出具有扩展性的代码,却是一件比较困难的事情.       不是因为具有可扩展性的代码不好写,而是因为这个度不好把握.我们知道系统的可扩展性总是与系统的业务和性能成反比,因此,我们不会在追求系统的扩展性上而忽略

重构-使代码更简洁优美:实际经验之谈(提供一技巧,让你省掉N多代码)

这几天没怎么写文,因为在用 CYQ.Data  框架 重构以前的一个博客源码,而在重构的过程中,最关键的就是简化代码了.   今天,我将说一个很典型的示例,看完本示例后,不要惊讶,不要怀疑,它不是神马,也不是浮云,   而是很实在的一种方式,能让你节省了N多的代码,让你的代码看起来更简洁优美.   而这里说的一个很典型的示例,是从我目前重构中的博客中应用而来的:   一:正常的开发方式   1:扫一眼当前的项目解决方案   2:说说Module库 一般我们很常见的会有一个页面基类,当然各花叫法不

做个好重构不容易 怎样才算一个好重构?

文章简介:如何做一个好重构. 用这个标题,是因为前一段时间组里有一个开放式讨论:怎样才算一个好重构?其实,"好"与"坏"向来都是相对的,因为每个人眼中看待"好"与"坏"的标准不一样,不如从自身的角度考虑一下:如何做一个好重构? 先来看一个平时我们遇到的最多的两栏布局: 计算">基本的html代码: 来看具体的CSS代码实现(忽略margin): 很明显在保持同样html结构的情况下,实现两栏布局可以有多种CSS

关于“网站重构”概念解析

概念|网站重构 近来大家总是在标准上争论不休,其实,这些问题一些相关文章已经说得很明白了. 以下我就谈谈我的看法.本帖子有太多的"我认为",说明了我只是想把我的想法拿出来跟大家商榷,或许有太多不对的地方,也请大家一一指出. 1.我对web标准的理解 所谓的web标准,在一些教程文章上已经得到结论:结构化标准(XHTML.XML).表现标准(CSS.XSLT?).行为标准(DOM.ECMAScript).这些东西在网上一搜一大把,在这里我就不多说了.我只说我自己的想法: a.标准是相对的

网页的HTML结构进行重构:语义化标签的意义

文章简介:语义化标签的实战意义. 我收集到一些观点,大家姑且先听上一听,有人说:"没必要考虑语义化,只要我写的代码浏览器运行后没问题就行,反正领导根本不关心这些""语义化是w3c推广的,我是很想语义化我的代码,但总是用不明白""这个不好说,语义化再好有啥用,关键是有好的项目,客户才是金主!""除了专业人士,谁会去看我们的代码是不是语义化的" 不仅仅有页面重构人员的声音,也听一听工程师.设计师.还有项目管理人员,他们是怎么看&q

闪客帝国网站重构访谈

网站重构   高大勇 [ 资料 ] 网名:边城浪子著名FLASH门户闪客帝国创始人闪客帝国副总经理李超 [ 资料 ] 网名:Allan闪客帝国网站运营总监闪客帝国网站技术总监网易学院: 请问你们是怎么想到要用XHTML+CSS2.0技术对闪客帝国进行重新构建的呢? 边城浪子: 这次改版已经酝酿了很长时间.在这期间,我们了解了很多的关于W3C标准的知识,闪客帝国的前身就是一个专注于技术的网站,我们觉得在这方面不应该落后.当然也考虑到浏览器友好以及维护的方便,所以,经过谨慎考虑,我们决定采用Web标