1. 程式人生 > >C# 一個計算器功能實現引發的思考

C# 一個計算器功能實現引發的思考

一.需求

    計算器功能需求,這個眾所周知,很明確了。

二.步驟分析

1)初級實現計算器 

  static int Calculator(int a,int b,string str)
        {
            switch(str)
            {
                case "+":
                    return a + b;
                case "-":
                    return a - b;
                case "*":
                    return a * b;
                case "/":
                    return a / b;
            }
            return 0;
        }

    優勢:程式碼簡單。

    劣勢:如果新增需求,需要不斷在switch中增加分支,並且需要在對應分支寫上相應的邏輯程式碼。程式碼耦合度太高。違背對修改關閉原則。

2)中級實現計算器

      I.先看case分支中對應的操作,都是運算。即,我們可以把其實現抽象出來。

      II.因為我們知道所有的運算都是對兩個數進行運算,所以,可以抽象出一個抽象類,即運算抽象基類BaseCalculate。     

public abstract class BaseCalculate
    {
        public abstract int Calculate(int a, int b);
    }

    public class Add : BaseCalculate
    {
        public override int Calculate(int a, int b)
        {
            return a + b;
        }
    }

    public class Sub:BaseCalculate
    {
        public override int Calculate(int a, int b)
        {
            return a - b;
        }
    }

  優勢:這個操作,我們將case中分支的程式碼抽象出來了。在對應的運運算元類中更改其操作就可以。將具體實現抽離出來。

  劣勢:程式碼量增加,違背了開放-封閉原則。(即開放增加,封閉修改原則)

  上述,就是設計模式中,傳說的簡單工廠模式

3)高階實現計算器

 class Program
    {
        static void Main(string[] args)
        {
            BaseFactory factory = new AddFactory();
            Console.WriteLine(factory.GetCalculate().Calculate(2, 1));

            BaseFactory factory2 = new SubFactory();
            Console.WriteLine(factory2.GetCalculate().Calculate(2, 1));
            Console.Read();
        }
    }

    public abstract class BaseFactory
    {
        public abstract BaseCalculate GetCalculate();
    }


    public class AddFactory:BaseFactory
    {
        public override BaseCalculate GetCalculate()
        {
            return new Add();
        }
    }

    public class SubFactory:BaseFactory
    {
        public override BaseCalculate GetCalculate()
        {
            return new Sub();
        }
    }

  這就是傳說中工廠方法模式,與上述簡單工廠模式對比克服了開放-封閉原則。

  優勢:減去核心邏輯中的switch分支。

  劣勢:程式碼量又增加了。

4)擴充套件&補充

  如果說上述的設計只為int型運算,如果現在需求增加,還需要增加 專門精度為float計算的計算器。上述計算,只針對int型,現在要專門是float型,該如何?

  所以,我們只需要增加基類BaseFloatCalculate,然後進行各種實現。並在BaseFactory中增加 BaseFactory GetFloatCalculate() 即可。程式碼就不貼了,這其實就是擴充套件。

  這就是抽象工廠模式。

  即使上述種種,還是離不開switch分支問題,有可以解決分支問題的辦法嗎。有的,但是不算主流,可以利用反射。

  BaseCalculate cal = (BaseCalculate)Assembly.Load("ConsoleApp7").CreateInstance("ConsoleApp7.Sub");
  Console.WriteLine( cal.Calculate(2, 1));

三.總結

    所謂優秀的功能的實現程式碼,即需要符合高聚酯,低耦合。

    符合高聚酯,低耦合,那就離不開架構設定。

    架構設計,其實無非就是即不斷的抽象,對類抽象,對方法抽象。當然,也不能過度抽象,會造成冗餘。

    因此總結一下,架構設定,就是合理適度的抽象。

    

    筆者認為

      沒有絕對適合某功能的架構框架,只有絕對合理適度的抽象。