第一章 代码无错就是优吗?(简单工厂模式)

  今天是设计模式的第一章由于工作比较忙所以一直想写点什么,但是还是没时间写。这篇的主题是代码无错可以运行就是优质代码吗?

  首先要实现一个业务代码:有部门A,B,C,D 四个部门但是A部门的奖金是10%,B部门的是20%,C部门是30%,D部门的是40% 编写一段代码实现输入底薪后计算出最后薪水

  

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入底薪:");
            int a =Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("请输入部门:");
            string b = Console.ReadLine();
            string d = String.Empty;
            
            if (b == "a")
            {
                d = (a * 0.1 + a).ToString();
            }
            if (b == "b")
            {
                d = (a * 0.2 + a).ToString();
            }
            if (b == "c")
            {
                d = (a * 0.3 + a).ToString();
            }
            if (b == "d")
            {
                d = (a * 0.4 + a).ToString();
            }
            Console.WriteLine("您的薪水是:{0}RMB",d);
            Console.ReadKey();
        }
    }

 

先看上面的代码,复制运行下看看。 没问题吧需求的业务功能都实现了。但是这样的代码真的好吗?

首先临界值的问题放在一边不说:

项目大了这样的命名自己都搞不清楚这个变量是什么用的了,就像是给软件埋了几个地雷,谁来改谁就踩了地雷了。那么来改改?

 

 

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入底薪:");
            int BasicSalary  =Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("请输入部门:");
            string Department = Console.ReadLine();
            string Salary = String.Empty;

            switch (Department)
            {
                case "a" :
                    Salary = (BasicSalary * 0.1 + BasicSalary).ToString();
                    break;
                case "b":
                    Salary = (BasicSalary * 0.2 + BasicSalary).ToString();
                    break;
                case "c":
                    Salary = (BasicSalary * 0.3 + BasicSalary).ToString();
                    break;
                case "d":
                    Salary = (BasicSalary * 0.4 + BasicSalary).ToString();
                    break;

                default:
                    break;
            }

            Console.WriteLine("您的薪水是:{0}RMB",Salary);
            Console.ReadKey();
        }
    }

这样行了吗?修改了命名修改了用switch代替if减少判断次数。哈哈你看到下面还有篇幅就猜到还不行。

这样的代码没有面向对象复用性很差 解决的办法是业务的封装再来改改

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入底薪:");
            int BasicSalary = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("请输入部门:");
            string Department = Console.ReadLine();
            Console.WriteLine("您的薪水是:{0}RMB", GetResult(Department, BasicSalary));
            Console.ReadKey();
        }


        public static string GetResult(string _department, int _basicsalary)
        {
            string Salary = String.Empty;
            switch (_department)
            {
                case "a":
                    Salary = (_basicsalary * 0.1 + _basicsalary).ToString();
                    break;
                case "b":
                    Salary = (_basicsalary * 0.2 + _basicsalary).ToString();
                    break;
                case "c":
                    Salary = (_basicsalary * 0.3 + _basicsalary).ToString();
                    break;
                case "d":
                    Salary = (_basicsalary * 0.4 + _basicsalary).ToString();
                    break;

                default:
                    break;
            }

            return Salary;

        }
    }

 嗯改了下业务和视图分开 这样Web,手机程序等等都可以调用这样业务逻辑就不用再Ctrl+C,在Ctrl+V了而且到后期业务逻辑修改了也不用再一个一个副本去修改了,改一下GetResult函数就可以咯。

我们继续 哈哈 还有啊...

如果今天公司发展和业务的需要加了一个部门f 那代码就需要修改业务代码了 破坏了代码的封装性 那怎么处理才是不破话封装呢。那就是面向对象的其他2个特性多态和继承

请看下面的代码:

public class Operation
    {
        private int basicsalary;

        public int BasicSalary
        {
            get { return basicsalary; }
            set { basicsalary = value; }
        }


        public virtual string GetResult()
        {
            string Salary = String.Empty;
            return Salary;
        }
    }

    class OperationA : Operation
    {
        public override string GetResult()
        {
            string Salary = String.Empty;
            Salary = (BasicSalary * 0.1 + BasicSalary).ToString();
            return Salary;
        }
    }

    class OperationB : Operation
    {
        public override string GetResult()
        {
            string Salary = String.Empty;
            Salary = (BasicSalary * 0.2 + BasicSalary).ToString();
            return Salary;
        }
    }

    class OperationC : Operation
    {
        public override string GetResult()
        {
            string Salary = String.Empty;
            Salary = (BasicSalary * 0.3 + BasicSalary).ToString();
            return Salary;
        }
    }

    class OperationD : Operation
    {
        public override string GetResult()
        {
            string Salary = String.Empty;
            Salary = (BasicSalary * 0.4 + BasicSalary).ToString();
            return Salary;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入底薪:");
            int BasicSalary = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("请输入部门:");
            string Department = Console.ReadLine();
            Operation oper = OperationFactory.createOperate(Department);
            oper.BasicSalary = BasicSalary;

            Console.WriteLine("您的薪水是:{0}RMB", oper.GetResult());
            Console.ReadKey();
        }


    }

    public class OperationFactory
    {
        public static Operation createOperate(string operate)
        {
            Operation oper = null;
            switch (operate)
            {
                case "a":
                    oper = new OperationA();
                    break;
                case "b":
                    oper = new OperationB();
                    break;
                case "c":
                    oper = new OperationC();
                    break;
                case "d":
                    oper = new OperationD();
                    break;
                default:
                    break;
            }
            return oper;
        }
    }

怎么样现在只要写一个运行对象然后加个new 就可以楼 不用去修改原来的业务逻辑噢。如果要修改界面就只要改界面的类楼。下面是UML图

 

 

 

吴蒋

2010.8.13


posted @ 2010-08-13 10:49  吴蒋  阅读(600)  评论(4编辑  收藏  举报