19

最近、次のようなセッターのみを定義するインターフェースに出くわしました。

public interface IAggregationView
{
   DataTable SetSiteData { set; }
}

これについて質問したところ、これは Microsoft が推奨する (SharePoint 用の) WebPart 設計の手法の 1 つだと思われます。実際、この例は彼らの例から直接コピーされています。

私はこれを悪いパターンと考えています。なぜ誰かが値を設定できて、それを再度読み取ることができないのかわかりません。また、セッターには常にゲッターを伴う必要があると思います逆に)。

セッターのみを持つことの利点を誰かが説明できるかどうか、なぜマイクロソフトがこの場合にそれを提案するのか、そしてそれが本当に従うのが良いパターンなのかどうか疑問に思っています.

4

5 に答える 5

22

これが妥当であると思われるシナリオが 2 つあります。

  1. パスワードなどの値を取得することはできませんvoid SetPassword(string)ただし、個人的にはそれをメソッドに置き換えます
  2. 設計された API には、値を読み取る必要がなく、最小限必要な API を公開するためだけに制限されています。

1 つ目の点として、使用する API が本質的にプロパティに値を割り当てる自動化されたマッパーである場合、Set... メソッドは理想的ではない可能性があります。そのシナリオでは、プロパティが実際に望ましいでしょう。

あなたの「誰かが値を設定できて、それを再び読み取れない理由がわかりません」について-同じ点で、値を設定した人はすでに値を知っていると主張することができます(彼らはそれを設定します)、したがって、これを行う必要はありません。

でも、はい; セットのみのプロパティを持つことは非常にまれです。

于 2012-09-17T08:58:00.717 に答える
15

getインターフェイスプロパティでのおよびの役割はset、クラスでの役割とは少し異なります。

public interface IAggregationView
{
   DataTable SetSiteData { set; }
}

class AggregationViewImp : IAggregationView
{
   public DataTable SetSiteData { get; set; }  // perfectly OK
}

インターフェイスは、プロパティに少なくともパブリックセッターが必要であることを指定します。ゲッターの定義とアクセシビリティは、実装クラスに任されています。

したがって、インターフェイスコントラクトを書き込むだけでよい場合は、get開いたままにしておくことができます。パブリックゲッターを要求する必要はありません。

結果として、インターフェースでも読み取り専用プロパティを実際に指定することはできません。'少なくとも読み取りアクセス'のみ。

interface IFoo
{
    int Id { get;  }
}

class Foo : IFoo
{
    public int Id { get; set; }  // protected/private set is OK too
}
于 2012-09-17T09:16:32.360 に答える
5

(手動の)依存性注入に使用することを想像できます。クラスには、内部でのみ使用するコラボレーターを注入する必要がある場合があります。もちろん、通常はクラスのコンストラクターでこれを行うことを選択しますが、実行時にコラボレーターを変更したい場合もあります。

于 2012-09-17T11:49:50.103 に答える
2

インターフェイスを実装するクラスは、getter を追加できます。プロパティのほとんどの使用は、インターフェイス自体ではなく、実装クラスを介して行われます。その場合、ほとんどのコードにはプロパティを取得および設定する機能があります。インターフェイスの唯一の理由は、クラスのファミリのメソッド/プロパティの共通のサブセットにアクセスする共通のコードがあることです。そのコードは、ゲッターではなく、セッターのみを必要とします。インターフェイスはその事実を文書化します。

インターフェイスは、「アトミックに必要な」操作のグループを宣言するための単なる機能です (たとえば、メソッド A を呼び出す必要がある場合は、プロパティ B を読み取ってプロパティ C を設定する必要があります)。

いつものように、それは場合によります

于 2012-09-17T09:03:48.490 に答える
1

私の経験では、そのようなインターフェースは、アーキテクチャ上の理由ではなく、特別な必要性のために発生します。たとえば、ASP.NET アプリケーションでは、グローバルな状態を維持したい場合に、Global.asax で生成された型をそのようなインターフェイスから派生させることがあります。誰かがアプリケーションの別の部分で初期化値を作成し、それをグローバルな場所に公開する必要がある場合があります。

私は通常、セットのみのプロパティをSetXxxメソッドに置き換えて、メソッドが最大 1 回呼び出されることを確認するようにします。そうすれば、臭いがはるかに少ない「初期化スタイル」を明確に適用できます(imho)。

確かに、そのようなものを絶対に生成しないように設定することはできませんが、回避する必要があり、コード レビュー中に疑問が生じることは間違いありません。

于 2012-09-17T08:55:25.697 に答える