重構CollapsibleSplitter(2)

來源:互聯網
上載者:User

在上一篇文章中我們把目標倒是定好了,從哪兒開始呢:去掉可惡的if和switch語句、去掉重複語句,還是減少那些長方法的行數?這是個問題,也許唯一能確定的就是先不去碰那個“8像素”限制了。

仔細分析代碼,我們會發現導致這個控制項中代碼高重複率的主要原因在於大大量使用了if和switch。進一步分析,編CollapsibleSplitter兄弟為什麼會使用這麼多分支語句呢?是這麼這麼這麼的…嘿嘿J:

  1. 此控制項支援五種繪製風格(分別是Mozilla、XP、Win9x、DoubleDots和Lines),代碼需要判斷使用者選擇的是那一種風格;
  2. 此控制項支援四種停靠方式(分別是Top、Bottom、Left和Right),代碼需要判斷使用者選擇的是那一種停靠方式;
  3. 在繪製介面、控制行為的時候控制項會在多種狀態中來回變換。

物件導向語言使用什麼來代替這些分支語句?把問題放到腦子裡轉兩圈——嗯,是策略模式(Strategy)和狀態機器模式(State)。好吧,那下面就使用這兩個模式來進行我們的除臭工作吧。

開始前我們先來溫習一下這兩個模式(從《設計模式迷你手冊》中摘取):

Strategy模式

 

State模式

 

我們先定義風格系列“策略”。依據方向(橫向或縱向)的不同,繪製介面風格的代碼也頗為不同,因此我們為基類定義兩個不同的繪製函數,分別代表橫向繪製和縱向繪製。下面是抽象基類VisualStyle和及其Mozilla繪製風格的子類:

namespace ISAK.WinGui.Controls.Styles
{
    abstract class VisualStyle
    {
        public abstract void DrawVertical(Graphics g, int x, int y, Color lineColor);
        public abstract void DrawHorizontal(Graphics g, int x, int y, Color lineColor);
    }

    class VisualStyleMozilla: VisualStyle
    {
        public override void DrawVertical(Graphics g, int x, int y, Color lineColor)
        {
            for (int i = 0; i < 30; i++)
            {
                // light dot
                g.DrawLine(new Pen(SystemColors.ControlLightLight), x, y + (i * 3), x + 1, y + 1 + (i * 3));
                // dark dot
                g.DrawLine(new Pen(SystemColors.ControlDarkDark), x + 1, y + 1 + (i * 3), x + 2, y + 2 + (i * 3));
                // overdraw the background color as we actually drew 2px diagonal lines, not just dots
                g.DrawLine(new Pen(lineColor), x + 2, y + 1 + (i * 3), x + 2, y + 2 + (i * 3));
            }
        }

        public override void DrawHorizontal(Graphics g, int x, int y, Color lineColor)
        {
            for (int i = 0; i < 30; i++)
            {
                // light dot
                g.DrawLine(new Pen(SystemColors.ControlLightLight), x + (i * 3), y, x + 1 + (i * 3), y + 1);
                // dark dot
                g.DrawLine(new Pen(SystemColors.ControlDarkDark), x + 1 + (i * 3), y + 1, x + 2 + (i * 3), y + 2);
                // overdraw the background color as we actually drew 2px diagonal lines, not just dots
                g.DrawLine(new Pen(lineColor), x + 1 + (i * 3), y + 2, x + 2 + (i * 3), y + 2);
            }
        }
    }
}

其他繪製風格的子類還有VisualStyleXP、VisualStyleWin9x、VisualStyleDoubleDots、VisualStyleLines,其代碼也是直接從OnPaint方法中的相關位置拷貝過去的。

接著,我們為CollapsibleSplitter類添加一個私人成員

private Styles.VisualStyle styleDrawer;

然後,我們修改VisualStyle屬性的set方法:>

public VisualStyles VisualStyle
{
    get{ return this.visualStyle; }
    set
    { 
        this.visualStyle = value;
        switch (value)
        {
            case VisualStyles.Mozilla: 
                styleDrawer = new Styles.VisualStyleMozilla();
                break;

            case VisualStyles.XP:
                styleDrawer = new Styles.VisualStyleXP();
                break;

            case VisualStyles.Win9x:
                styleDrawer = new Styles.VisualStyleWin9x();
                break;

            case VisualStyles.DoubleDots:
                styleDrawer = new Styles.VisualStyleDoubleDots();
                break;

            case VisualStyles.Lines:
                styleDrawer = new Styles.VisualStyleLines();
                break;
        }

        this.Invalidate();
    }

再把OnPaint方法中的兩個switch去掉,上邊的那switch系列的一大堆代碼改成下面的樣子

styleDrawer.DrawVertical(g, x, y, hot ? hotColor : BackColor);

下面那switch系列的一大堆代碼改成>

styleDrawer.DrawHorizontal(g, x, y, hot ? hotColor : BackColor);

這繪製風格方面的臭味算是暫且搞定了,雖尚有些令人不滿意的地方(看看上面的兩個hot ? hotColor : BackColor),但還算過得去。嘿嘿,有些細微的工作麼,留待最後才搞定好了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.