面向過程:
假設有兩個類Square(正方形),Rectangle(長方形) 。代碼如下:
如果有一個類Geometry需要計算圖形的面積:
假設現在要添加一個Circle(圓形),并且同樣需要計算Circle的面積。那么需要做哪些修改:
1:需要添加Circle類,代碼如下:
2:因為需要計算Circle的面積,所以Geometry類需要修改
可以看到增加了sharp is Circle 的判斷。
假設現在Geometry類不僅僅需要計算面積,還需要計算sharp的周長。
那么Geometry的代碼大致如下:
可以發現,Square,Rectangle,Circle這三個類不需要做任何更改。
也就是說當需要添加函數的時候,數據結構不會受到影響。
面向對象:
如果使用面向對象的角度來思考這個問題,那么該怎么處理呢?
基本上有 if else,switch的地方就可以考慮使用策略模式。
首先可以創建抽象類Shape,或者是接口IShape
當然,在這里隨便使用哪一個都可以,因為除了計算面積之外,目前不需要繼承字段,屬性,所以我選擇了接口。
Area的名字是面積,不過并沒有體現出獲取面積這個動作,所以我決定將Area重命名為GetArea或者是CalculateArea
代碼如下:
接著創建實現類,Square,Rectangle
Geometry類的實現就比較簡單了
同樣,如果需要添加一個Circle,然后計算Circle的面積。那么該如何做呢?
很簡單,添加一個Circle類就可以了,Geometry不需要任何變化。
也就是說添加數據結構的同時,方法不受影響。
如果現在要添加一個計算周長的方法呢?
首先IShape接口要增加GetPerimeter 方法。
如果現在編譯的話,會得到下面的結果:
無法通過編譯有2點好處:
- 修改了接口會導致無法通過編譯,這是面向過程無法提供的,比如在面向對象的方案中Geometry中的GetPerimeter方法如果忘記了添加Circle的判斷,那么編譯一樣可以通過。
- GetPerimeter方法由類自行管理,復雜度大大下降,代碼結構更加清晰。
以Square為例:代碼如下:
如果這時候編譯,可以發現,可以編譯通過。
所以面向對象的特點是修改數據結構的同時,不影響方法,也就是說添加一個類,不會對原系統的方法有影響。
當然在這里Geometry 需要添加GetPerimeter方法:
不含病毒。www.avast.com |
留言列表