2009-05-21 18 views
2

私は、良いデザインはifブロックでコードを捨てる代わりに継承を使用することを言っていると聞いてきました。どのような状況で我々は継承を使用する必要があり、条件ブロックはちょうど良いですか?ここで継承または条件ですか?

答えて

2

、次のようなコードを持っていることは良いオブジェクト指向プログラミングの練習ではありません。

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ブロックに来るときしかし、多くの場合、継承の使用はあなたのコードはより拡張し、より堅牢になります。

0

が、私は他の日に走ったものです

PHPは、それが

class cacheURL extends Cache { 

    public function __construct($url) { 

     $string = file_get_contents($url); 

     parent::__construct($string); 
    } 

} 

ラフの例を拡張されての可能性

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 

    } 

} 

か...選択の私の言語ですが、私はあなたが私のドリフトをキャッチすることを願って....

0

私の意見では、2つは相互に排他的ではありません。私は通常、共通の機能を持つ2つ以上のクラスがある場合、継承を使用します。

2

引数の型に基づいて実行するロジックを決定するために使用されるブロック(またはスイッチブロック)を多態性に置き換える必要がある場合。

プログラムの新機能により、追加の大文字小文字を使用するか、ブロックで多型が使用される場合、

自然順序付け型の比較(<、>、==など)には、文を使用するか、何かがnullかどうかを確認する必要があります。

0

継承は、(状態や型のように)常にチェックするオブジェクトに固有の何かをチェックしているときに優れています。この例では、数式ツリーの演算子です。加算のような演算子は、プラス記号(infix notation)の前後に式があるので、ツリーとして表現されているため、左右に呼びます。値を無効にするハイフンのような単項演算子もありますが、子式は1つのみです。

継承を使用すると、バイナリ)を継承に分解されます。

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がnullであるという規約を導入する必要があることを意味します。 ToStringはOperatorTypeをチェックする必要があります。どのような演算子で動作する必要がある他の方法もそうです。

後者のアプローチは、XmlNodeがあらゆるXMLノードに含めることができるすべてのものであるXML DOM実装で最もよく見られます。

  • どのように属性ノードまたはテキストノードにChildNodesを設定できますか?
  • ChildNodesにはChildNodeが1つしかない場合、どのようにしてその子ノードを持つことができますか? (コレクションである必要はありません)
  • 文書にParentNodeはどのようにありますか?
  • ドキュメントにはどのようにValueがありますか?
1

これは他の人がガイドラインを提供することができながら、任意の特定の状況のた​​めの最終的な答えは、常に、これらの質問の一つである「それは状況に依存します。」

特定の状況に対応できるようにするには、エクスペリエンスを得ることが最も良い方法です。合理的に行うことができる両方の方法を試してください。 (明らかに、何千行ものコードを変更しなければならない状況で、前後に反転させたくないのですが)どちらがうまくいったのですか?どちらがあなたに良い感じですか?どうして?

これで十分ですが、間もなく一般的なアドバイスが必要なくなったレベルに近づいて、特定の状況で何をすべきかを知ってもらえるようになります。 (説明することはできません;それは専門知識の性質の一部です。詳細については、The Dreyfus Model of Skill Acquisitionを参照してください。

関連する問題