2012-01-12 20 views
1

背景: 内部に複数のレベルのネストされた図形がある図形のアートワークを描きます。例。それらの形状内のいずれかの形状および面積の長さは、関連するすべての特性および形状を変化させる。内部セッターとのC#インターフェイス

私はこのように書きデザインパターンを持っている:

私は(議論のために)例えば、相互に関連するプロパティのトンを持っている「NestedShapes」、「エリア」と呼ばれるオブジェクトグラフを持っていますと "長さ"。しかし、グラフはダムになるように設計されています。つまり、いずれかの値が与えられた場合、他の値を計算する方法はわかりません。

代わりに、グラフをグラントマネージャのトップレベルルートノードIRootShapeを取るGraphManagerにアタッチすることができます。

NestedShapesは、INotifyPropertyChangedも実装しているIRootShapeを実装しています。 GraphManagerはこれらのプロパティの変更をサブスクライブし、関連するフィールドを計算するためのロジックを実行し、IRootShapeを使用してグラフを正しい状態に設定します。

問題:IRootShapeとともに 、私は本当のC#のインターフェイスですICircleなどIShape、ISquareを、持っています。しかし、問題はこれらのプロパティのいくつかのためです。私はGraphManagerにプライベートなセッタしか持たないことを望みます。実装のシェイプがまだパブリックセッターを公開する可能性があることを知っていますが、が必要です。はGraphManagerからプロパティを設定できるようにUI側でこれらを公開しません。私は何をすべきか?内部クラスを持つ基本クラスは行く方法を設定しますか?

+1

インタフェースは、外部から見えるものを定義しています。私はベースクラスがあなたの最善の策だと言うことを念頭に置いています。 –

+0

すべてのシェイプで共通の動作が必要な場合は、共通の基本クラスから継承する必要があります。また、なぜあなたは 'ICircle'、' ISquare'などのために別々のインターフェースが必要ですか?なぜ、単にIShapeだけではないのですか? – ja72

+0

@ ja72私はIShape、ISquare、ICircleには状態しかないと言うでしょう。動作はGraphManagerにあります。 – Jake

答えて

2

GraphManagerがBaseクラスとやりとりするようにします。

他のすべては、インターフェイスとのみ相互作用します。

インターフェイスにプロパティを公開しないでください。

public class Circle : ICircle{ 
    public double Radius{ 
     get;set; 
    } 

    /* blah blah ... */ 
} 

public interface ICircle { 
    /* No properties */ 

    /* blah blah ...*/ 
} 
+0

+1。また、必要に応じてgetterをインタフェースに移動することもできますが、実装は必要に応じて内部/専用設定を自由に行うことができます。 –

+0

@Daryl私は基本クラスのアイディアを得ました。しかし、私はこの場合空のインターフェースの目的を理解していません。説明できますか? – Jake

+0

@ Jake、それはあなたのコードです - プロパティとのインターフェイスを持っている - それらを追加する、全くインターフェイスを必要としない - 1つを作成しないでください。 –

0

インターフェイスでこれを行うには、2つの別々のインターフェイスを使用することが賢明です。 1つはパブリック、もう1つは社内のみです。はい、それはあなたが明示的にプロパティの契約を実際のプロパティに委譲する内部インターフェイスを明示的に実装する必要があるので、少しコードが必要ですが、私は 'ClassName.Internal.cs'というファイルの部分クラスにそれを隠します

この方法では、ベースクラスに頼らずにすべてのインターフェイスを明快かつきれいに公開することができるため、既存のオブジェクトグラフを拡張することができます。

ここに、パブリックゲッターと内部セッターを持つTestItemの例を示します。これらはすべてインターフェイス経由でアクセスできます。

ここここ部分クラスを介して実装TestItem.Internal.csに記憶されている内部のみの実装だ

public interface ITestItem 
{ 
    ModelItem Owner { get; } 
    ModelScope Scope { get; } 
} 

public partial class TestItem : ITestItem 
{ 
    // These implicitly handle ITestItem since the getters are public 
    public ModelItem Owner { get; internal set; } 
    public ModelScope Scope { get; internal set; } 
} 

TestItem.cs

に格納され、パブリックインターフェイスメインクラスファイルです。

internal interface IWritableTestItem 
{ 
    ModelItem Owner { get; set; } 
    ModelScope Scope { get; set; } 
} 

public partial class TestItem : IWritableTestItem 
{ 
    ModelItem IWritableTestItem.Owner 
    { 
     get => Owner; 
     set => Owner = value; 
    } 

    ModelScope IWritableTestItem.Scope 
    { 
     get => Scope; 
     set => Scope = value; 
    } 
} 

関連する問題