写代码写至最有面向对象味道

写代码写至最有面向对象味道

前几天,搬房子时又拿起《重构----改善既有代码的设计》这本书来随便翻来看下,重构在开发时,是时常也经常会使用得到。
写代码写至最有面向对象味道_第1张图片


她确实教我们怎样把写程序写简洁,清楚 好明白,好理解,好维护......

今天为博客写点重构相关。以网友实际的例子,在论坛上看到的:

public void show2(string day)
    {
        string[] str = new string[] { "09:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00" };
        for (int i = 0; i < str.Length; i++)
        {
            string sql1 = "select position from cwsz where day='" + day + "' and sjd='" + str[i] + "'";
            var dt1 = db.ExecuteQuery(sql1);
            if (dt1.Rows.Count > 0)
            {
                if (dt1.Rows[0]["position"] != null)
                {
                    if (str[i] == "09:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropnine.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropnine.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropnine.SelectedIndex = 3;
                        else
                            dropnine.SelectedIndex = 4;

                    }
                    if (str[i] == "10:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropten.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropten.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropten.SelectedIndex = 3;
                        else
                            dropten.SelectedIndex = 4;
                    }
                    if (str[i] == "11:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropele.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropele.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropele.SelectedIndex = 3;
                        else
                            dropele.SelectedIndex = 4;
                    }
                    if (str[i] == "12:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            droptw.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            droptw.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            droptw.SelectedIndex = 3;
                        else
                            droptw.SelectedIndex = 4;
                    }
                    if (str[i] == "13:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            tropthir.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            tropthir.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            tropthir.SelectedIndex = 3;
                        else
                            tropthir.SelectedIndex = 4;
                    }
                    if (str[i] == "14:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropfour.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropfour.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropfour.SelectedIndex = 3;
                        else
                            dropfour.SelectedIndex = 4;
                    }
                }
            }
        }
    }
复制代码
public void show2(string day)
    {
        string[] str = new string[] { "09:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00" };
        for (int i = 0; i < str.Length; i++)
        {
            string sql1 = "select position from cwsz where day='" + day + "' and sjd='" + str[i] + "'";
            var dt1 = db.ExecuteQuery(sql1);
            if (dt1.Rows.Count > 0)
            {
                if (dt1.Rows[0]["position"] != null)
                {
                    if (str[i] == "09:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropnine.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropnine.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropnine.SelectedIndex = 3;
                        else
                            dropnine.SelectedIndex = 4;

                    }
                    if (str[i] == "10:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropten.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropten.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropten.SelectedIndex = 3;
                        else
                            dropten.SelectedIndex = 4;
                    }
                    if (str[i] == "11:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropele.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropele.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropele.SelectedIndex = 3;
                        else
                            dropele.SelectedIndex = 4;
                    }
                    if (str[i] == "12:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            droptw.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            droptw.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            droptw.SelectedIndex = 3;
                        else
                            droptw.SelectedIndex = 4;
                    }
                    if (str[i] == "13:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            tropthir.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            tropthir.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            tropthir.SelectedIndex = 3;
                        else
                            tropthir.SelectedIndex = 4;
                    }
                    if (str[i] == "14:00")
                    {
                        if (dt1.Rows[0]["position"].ToString() == "3")
                            dropfour.SelectedIndex = 1;
                        else if (dt1.Rows[0]["position"].ToString() == "4")
                            dropfour.SelectedIndex = 2;
                        else if (dt1.Rows[0]["position"].ToString() == "5")
                            dropfour.SelectedIndex = 3;
                        else
                            dropfour.SelectedIndex = 4;
                    }
                }
            }
        }
    }
复制代码


刚开始看到这段代码时,一眼看上去就发现用户写得很相同的代码,即是冗余。用了很多if...else...。这些都是在书所提及需要重构的问题点。

分几步来重构,先来解决代码冗余的部分,从if最内层开始,Insus.NET已经把不同的标记出来了,看下图:

写代码写至最有面向对象味道_第2张图片

 

把相同的代码写一个方法,以后一旦下拉列表的SelectedIndex的维护,只来这个方法修改即可,不必去每一个if内检查,或是查找替换。
写代码写至最有面向对象味道_第3张图片


然后我们就可以去修改上抽离的代码,Insus.NET把重构部分comment掉:
写代码写至最有面向对象味道_第4张图片


现在我们把comment的代码删除,变成下面这个样子,代码简洁多了:
写代码写至最有面向对象味道_第5张图片

但是上面经首次重构之后,if还是太多,学习过设计模式的话,看到这部分程序,自然想起使用《设计模式--中介(Mediator)模式http://www.cnblogs.com/insus/p/4134383.html 中介者模式来解决。只管传入str[i]值进去即可,用户不必明白它是怎样处理与判断,达到封装效果:
写代码写至最有面向对象味道_第6张图片

 


运用设计模式来进行重构:
写代码写至最有面向对象味道_第7张图片

最后一个private int SetSelectIndex(string position)方法,我们也把它移至中介者类别中去了:
所留给用户看到的代码,即是(删除comment):
写代码写至最有面向对象味道_第8张图片

以面向对象编程来说,上面高亮两行代码,应该它来自一个对象,不管你的程序是使用存储过程还是写SQL语句,我们尽量不要出现在xxx.aspx.cs代码页中:
写代码写至最有面向对象味道_第9张图片


这样子,在xxx.aspx.cs代码,就可以改为:
写代码写至最有面向对象味道_第10张图片

 

现在我们回过头去看中介者SwitchObject类,它最底的私有方法,其实使用了switch方法,在重构之中,也是一个很坏的使用。其实switch即是替代多个if判断。出现多个if时,我们又可以使用中介者模式来解决。
写代码写至最有面向对象味道_第11张图片


创建一个中介者类:
写代码写至最有面向对象味道_第12张图片


再来看看Insus.NET怎样对SwitchObject类修改:
写代码写至最有面向对象味道_第13张图片


重构到这里,整段程序也改得差不多了,但是在SwitchObject类中,还是有些代码是很不稳定的。有可能常被修改,因此,我们还是把它移走。只留下稳定代码:
写代码写至最有面向对象味道_第14张图片

 
移到哪里,Insus.NET想把它移至最原始的位置,在移动之前Select()方法,需要小修改一下,期望传入另外一个参数:
写代码写至最有面向对象味道_第15张图片


回至xxx.aspx.cs的 public void show2(string day)方法:
写代码写至最有面向对象味道_第16张图片


重构到这里,你还是看到有一个if判断:

 

似乎改得有点问题,正确来说,当传入的position为空时,它等于4。而不是获取的selectedIndex不等于4时等于4。
写代码写至最有面向对象味道_第17张图片


重构完毕,最终源程序可从下面链接下载:
http://download.cnblogs.com/insus//Refactoring/RefactoringAndMediator_pattern.rar

 

 
分类:  ASP.NETC#Design PatternRefactoringGeneric

你可能感兴趣的:(Pattern,Datatable,Dictionary,selectedIndex,dropdownlist,Mediator,Refactoring,ContainsKey)