我聽過有人說好的設計涉及到使用繼承而不是亂拋垃圾的代碼。在什麼情況下我們應該使用繼承,並且當條件塊很好時?繼承或條件?
繼承或條件?
回答
通常,這是不好的面向對象編程的做法有如下代碼:
var chioce = PAINT_SCREEN_BLUE
if (choice == PAINT_SCREEN_BLUE):
paintScreen(blue)
else if (choice == PAINT_SCREEN_RED):
paintScreen(red)
else if (choice == PAINT_SCREEN_GREEN):
paintScreen(green)
上面可以利用多態性調用一些方法,該方法將執行在共同祖先的相關類別中抽象出的動作:
interface ScreenPainter:
function perform()
class BlueScreenPainter implements ScreenPainter:
function perform():
paintScreen(blue)
...
// The conditional block can be replaced with the following call:
var choice = PAINT_SCREEN_BLUE
ScreenPainter p = Painters.getPainter(choice)
p.perform()
然而,這種做法絕對不應該適用於所有條件語句然而,當涉及到長switch
塊或if-elseif-else
塊,在許多情況下,繼承的使用將會使你的代碼更具擴展性和更強大的。
這裏是我跑進了一天
PHP是我的首選語言
class Cache {
public function __construct($resource) {
// if statement to determine from type if it is a file, url or string. instead, change it to accept a string
}
}
或者......它可能的被延長
class cacheURL extends Cache {
public function __construct($url) {
$string = file_get_contents($url);
parent::__construct($string);
}
}
粗糙的例子,但我希望你趕上我的漂移....
在我看來,兩者並不相互排斥。當我有2個或更多具有通用功能的類時,我通常會使用繼承。
像這樣的一個重構被稱爲Replace Conditional With Polymorphism。
我們確實青睞composition over inheritance,但是......這裏討論的主題實在太廣泛,但the book值得一讀,可以幫助您入門。
如果用於根據參數類型決定執行什麼邏輯的塊(或開關塊)應該用多態性替換。
如果程序中的新功能會導致您創建其他案例或使用多態性塊。
如果語句應該用於自然排序類型比較(<,>,==等)或檢查是否爲空。
當某些條件正在檢查不斷檢查的對象的內在物體(如狀態或類型)時,繼承效果會更好。在這個例子中,它是一個數學表達式樹的運算符。像加法這樣的運算符在加號前後有一個表達式(infix notation),所以我將它們稱爲左和右,因爲它表示爲樹。還有像連字符這樣的一元操作符可以否定值,但它只有一個孩子表達式。
使用繼承意味着類型(簡化爲一元對比二進制)被計入繼承:
class Operator
{
abstract string ToString();
}
class UnaryOperator : Operator
{
Expression Expression { get; }
override string ToString() {...}
}
class BinaryOperator : Operator
{
Expression LeftExpression { get; }
Expression RightExpression { get; }
}
class AdditionOperator : BinaryOperator
{
override string ToString()
{
return this.LeftExpression.ToString() + "+" + this.RightExpression.ToString();
}
}
至於反對:
class Operator
{
Expression LeftExpression { get; }
Expression RightExpression { get; }
OperatorType Type { get; }
string ToString()
{
switch(this.Type)
{
case OperatorType.Addition:
return this.LeftExpression.ToString() + "+" + this.RightExpression.ToString();
case OperatorType.Negation:
return "-" + this.LeftExpression.ToString();
case ...:
}
}
}
enum OperatorType
{
// Unary operators
Negation,
// Binary operators
Addition,
Subtraction,
Multiplication
}
這裏你一元運算符沒有左,右的表情,只是一種表達。這意味着你必須引入使用Left和Right爲空的約定。 ToString將不得不檢查OperatorType;那麼其他任何方法都需要根據它是什麼操作符來操作。
後一種方法最常見於XML DOM實現,其中XmlNode幾乎是任何XML節點可能包含的東西...永遠。它使一些非常混亂的情況:
- 如何可以屬性或文本節點有ChildNodes?
- 如果一個文檔只有一個文檔可以有一個ChildNodes,它該如何處理? (它不一定是一個集合)
- 文檔如何具有ParentNode?
- 文件如何具有價值?
- 等等
這是那些問題,雖然其他人可以提供指引,針對任何特定情形最終的答案永遠是,一個「這要看情況。」
能夠開發回答任何特定情況的能力的最佳方式是獲得經驗:即實驗。嘗試兩種方式,你可以合理地做到這一點。 (很明顯,你不想在需要修改一千行代碼的情況下來回翻轉)。哪個更好?你覺得更好嗎?爲什麼?
這樣做夠了,你很快就會達到不再需要一般建議的專業水平,人們開始問你如何知道在特定情況下要做什麼。 (您將無法解釋它;這是專業性質的一部分。有關更多詳細信息,請參見The Dreyfus Model of Skill Acquisition。
- 1. 玉繼承與條件
- 2. 單表繼承或類表繼承?
- 3. 類繼承或單表繼承2.3
- 4. 類可以從「參數」類繼承嗎? (有條件繼承)
- 5. 組成或繼承
- 6. 繼承或枚舉
- 7. 模塊或繼承?
- 8. 繼承或組成?
- 9. 繼承或組成
- 10. Django的條件模板繼承
- 11. @條件不處理繼承類?
- 12. C#中的條件類繼承問題
- 13. Rails的條件類繼承模型
- 14. Python中的條件類繼承
- 15. C++:有條件繼承可能
- 16. C++執行條件對繼承類
- 17. 條件包括單表繼承模型
- 18. 域事件 - 繼承或使用枚舉
- 19. AS3繼承:load或init事件?
- 20. 繼承控件
- 21. Python的繼承或小面
- 22. 擴展方法或繼承?
- 23. Java繼承或GUI出錯
- 24. 私有繼承或遏制
- 25. 繼承或封裝View/Viewmodel
- 26. 如何繼承或odoo
- 27. 繼承或設置,選項
- 28. 多繼承或多接口
- 29. 抽象或繼承用例?
- 30. 繼承std :: istream或等效