2016-08-18 9 views
1

私は関連する質問について多くの類似の投稿を見つけました。この回答はtaylonrで終わりましたが、私のシナリオにはあまり答えていませんでした。どのようにOOとSOLIDの原則を使用してこれをより良く設計できますか?

は、私はインターフェイスを持っていると仮定します

public interface IShape 
{ 
    decimal GetArea(); 
} 

私は、このインタフェース

public class Rectangle : IShape 
{ 
    public decimal GetArea() 
    { 
     ... 
    } 
} 

public class Triangle : IShape 
{ 
    public decimal GetArea() 
    { 
     ... 
    } 
} 

public class Circle : IShape 
{ 
    public decimal GetArea() 
    { 
     ... 
    } 
} 

を使用して3つのクラスを作成し、私は今int GetNumberOfSides()機能(またはにのみ関連し、いくつかの他の機能を追加したいです私のIShapeの一部)。明らかにこれはCircleクラスには関係ありません。私がList<IShape>のオブジェクトを持っていて、関連するIShapesでこの関数を繰り返し呼び出す場合、オブジェクト指向の設計原則を使ってどうやってこれに対処しますか?

私はIShapeインターフェイスbool HasSides { get; set; }にブール値を追加してこれのロジックを実行することができますが、GetNumberOfSides()関数にアクセスするには特定のクラスにキャストする必要があります。私はこれが正しいとは思いませんが、これが正しいとは思いませんが、これをどうやって行うのかは分かりません。

ISidedShapeIShapeから継承されていると考えましたが、私のリストの反復処理に戻って、この特定の方法がどのような形状を持っているかをどのように知っていましたか?

ご協力いただければ幸いです。

おかげ

+2

「サークル」は、半円のような他の奇妙な形はどうでしょうか?それは合法的に1つの "側"と同様に1 "他の何か、あなたが側をどのように定義するかに依存します"。たぶん「面」はあなたが探している用語ではないでしょうか?この用語の名前がより適切であれば、モデリングがより理にかなっているかもしれません。 – David

+0

私の例は最高ではなかったかもしれません。私は他の知識が必要な私の実際のシナリオを使わずに例を見つけるのに苦労していました。私は0を返すことについてあなたのポイントを得るが、それはどちらかといえば気分が悪い。 – user1244893

+2

なぜそれは正しく感じませんか?それは完全に論理的です。 – jrahhali

答えて

1

あなたはOOPのルートを移動したい場合、あなたはほとんどの言語で好きなだけを実装することができるので、あなたは、インターフェイスを追加することができます。

public interface IPolygon 
{ 
    int GetNumberOfSides(); 
} 

public class Rectangle : IShape, IPolygon 
{ 
    public decimal GetArea() { return 0; } 
    public int GetNumberOfSides() { return 4; } 
} 

それは本当であるすべてのポリゴン形です。しかし、ここ数年は、継承が強力で信じられないほど危険なことがあることを多くのOOP担当者に教えてきました。そして、一般的に言えば、階層的な関係よりも複合的な関係が好まれます。

これは良い学問的練習ではあるが、典型的な "形"のOOPの例は、しばしばそれを「現実の世界」に変換するものではないと言わざるを得ないと感じているので、多くのプログラマーは、それ以外の場合は簡単な方法です。すべてがオブジェクトでなければならないため、データをオブジェクトモデルにマッピングすることが強制されています。これは、単にデータをパラダイムに当てはめることや、単にデータを操作するのではなく、 "シンプル"は王様であり、複雑さは敵です。

+0

ありがとうございました。 'List 'をループすると、 'IPolygon'を使って' IPolygon'にキャストするかどうかを判断できますか? – user1244893

0

既に(あなたがIShape多型に依存している)あなたのコード内のいくつかの場所でList<IShape>を持っている場合は、私は最善の解決策はIShapeGetNumberOfSides()を追加している場合

public class Circle : IShape 
{ 
    public decimal GetNumberOfSides() 
    { 
     return 0; 
    } 
} 

としてそれを実装することであると言うでしょうあなたはまだ "デ​​ザイン"段階にあり、実際には List<IShape>を使用しているコードを持っていないので、 IPolygon(まさに@Joshの答えと同じように)の2番目のインターフェースを実装できます。

これらの2つのソリューションのいずれか一方が適しています(IShapeが現在どのように使用されているかによる)と、 "OOPアプローチ"です。実際のコードを表示していないため、どちらが良いかはわかりません(シェイプの例に基づいてそのような決定をすることは関係ありません)。

あなたのコードはすぐifの多くのあなたがList<IShape>に反復されますので、テストし、維持するために悪夢になるたびに雑然とされますので、しかし、私は落胆う唯一の方法は、IShapehasSides方法を追加しています。ですから、booleanifで手動で分岐するのではなく、多型が分岐を処理するようにしてください。

+0

'List 'の上をループするときに 'if hasSides'を'もし 'xxxがIPolygon'に置き換えないのですか? – user1244893

+0

@ user1244893 'IPolygon'でシステムを設計する場合、受け入れ可能なオプション(多分)に' List 'もあるでしょう。ただし、1つではなく2つのリストを保持することになります。だから最初のアプローチ( 'IShape'に' GetNumberOfSides'を追加する)は私にとって最も保守的なものです。 – Spotted

0

これはLSPとISの原則に従います getSides()メソッドをIShapeインターフェイスに追加すると、そのインターフェイスがCircleによって実装されているときにLSPに違反します。 投稿の1つに記載されている新しいIPolygonインターフェイスをIsとLSPの両方に付けるようにしたい

関連する問題