2013年10月16日 星期三

CleanCode 讀書筆記 (二) 物件及資料結構

在這個章節提到的重點是
結構話化程式碼容易添加新的函式  而不需要變動已有的資料結構
而物件導向得程式碼則是容易添加新的類別而不用變動已有的函式


以下是結構化的程式碼
 
    class SalaryCalculator
    {
        public double Calculate(string person)
        {
            if (person.Equals("boss"))
            {
                return 500 * 22 * 24;
            }
            else if (person.Equals("DayWorker"))
            {
                return 200 * 22 * 24;
            }
            else if (person.Equals("partTime"))
            {
                return 100 * 22 * 24;
            }
            throw new NullReferenceException();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            SalaryCalculator calculator = new SalaryCalculator();
            Console.WriteLine(calculator.Calculate("boss"));
            Console.ReadLine();
        }
    }
假設要添加一個SetWorkDays的函式
是蠻容易而且不會變動到已有的結構但是如果要新增一個
NightWorker (夜班) 人員的薪資  就是必要更改現有的函式

    class SalaryCalculator
    {
        private int workHours = 24;
        public void SetWorkHours (int workHours )
        {
            this.workHours = workHours ;
        }
        public double Calculate(string person)
        {
            if (person.Equals("boss"))
            {
                return 500 * 22 * workHours ;
            }
            else if (person.Equals("DayWorker"))
            {
                return 200 * 22 * workHours ;
            }
            else if (person.Equals("partTime"))
            {
                return 100 * 22 * workHours ;
            }
            else if (person.Equals("NightWorker"))
            {
                return 300 * 22 * workHours ;
            }
            throw new NullReferenceException();
        }
    }


接著我們看看  物件導向的程式

    
    interface CalculatorBase
    {        
        public double Calculate();
    }
    class BossSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public override double Calculate()
        {
            return 500 * 22 * workHours;
        }
    }
    class DayWorkerSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public override double Calculate()
        {
            return 200 * 22 * workHours;
        }
    }
    class partTimeSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public override double Calculate()
        {
            return 100 * 22 * workHours;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //SalaryCalculator calculator = new SalaryCalculator();
            CalculatorBase calculator = new BossSalaryCalculate();
            Console.WriteLine(calculator.Calculate());
            Console.ReadLine();
        }
    }


    interface  CalculatorBase
    {             
       public double Calculate();
       public void SetWorkHours(int workHours);
    }
    class BossSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public void SetWorkHours(int workHours)
        {
            this.workHours = workHours;
        }
        public double Calculate()
        {
            return 500 * 22 * workHours;
        }
    }
    class DayWorkerSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public void SetWorkHours(int workHours)
        {
            this.workHours = workHours;
        }
        public double Calculate()
        {
            return 200 * 22 * workHours;
        }
    }
    class partTimeSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public void SetWorkHours(int workHours)
        {
            this.workHours = workHours;
        }
        public double Calculate()
        {
            return 100 * 22 * workHours;
        }
    }
    class NightWorkerSalaryCalculate : CalculatorBase
    {
        private int workHours = 8;
        public void SetWorkHours(int workHours)
        {
            this.workHours = workHours;
        }
        public override double Calculate()
        {
            return 300 * 22 * workHours;
        }
    }
上面的程式使用了interface 將計算的方式分隔開來使我們在新增NightWorker的時候
並不會更改到其他的class  但是當我們需要添加新的函式時反而造成了很大的困擾
必須針對每個class 實做SetWorkHours  當class一多  這樣是很痛苦的

所以必須觀察系統所需要的
若要增加worker的薪資計算的彈性  就要使用物件導向的設計
若要增加worker的函式功能的彈性  就要使用結構化的設計

沒有留言:

張貼留言