0

私はこれについて本当に混乱しています。パラメータをメソッドに渡す方が合理的であることは知っていますが、継承を使用すると、すべての変数が公開されます。

public abstract class HttpRequestBase
{
    public string Url { set; get; }
    public IWebProxy Proxy { set; get; }

    public abstract void SendHttpRequest();
}

public class HttpRequest : HttpRequestBase
{
    public override void SendHttpRequest()
    {

        HttpWebRequest objHttpWebRequest = (HttpWebRequest)WebRequest.Create(base.Url);
        objHttpWebRequest.Proxy = base.Proxy;
        ....etc.
}

public class Class1: HttpRequest
{
       void Request()
       {
          SendHttpRequest();
       }
}

そして私のWinFormで:

 private void Form1_Load(object sender, EventArgs e)
    {
        Class1 obj = new Class1();
        obj.Url = "http://google.com";
        obj.Proxy = null;

        //Instead of passing the "obj" as a parameter, all these properties are already shared
        obj.Request();
    }

パラメータを渡す方が理にかなっていますが、使用しない場合、共有プロパティの目的は何ですか?

4

2 に答える 2

0

パラメータを渡す方が理にかなっている

あなたの例ではそうだと思いますが、設計意図は問題を明確にします。

  • 最大限の柔軟性を可能にします。これにより、カプセル化がある程度犠牲になり、クライアント コードでエラーが発生しやすくなる可能性があります。
  • Class1オブジェクトは不変ですか? IE は、現在URLまたはProxy既存のHttpRequestものをまったく新しいものに変更することは理にかなっていHttpRequestますか?
  • 有効なオブジェクトの状態を保証する

と の 2 つのパラメーターを必要とするHttpRequestBaseコンストラクターを作成します。URLProxy

public HttpRequestBase (string url, IWebProxy proxy) {
    this.Proxy = null;
    this.URL = url;

    // how to handle null parameters? make defaults? throw exception? other?
}

なぜコンストラクタ?

URLおよびProxyが (派生) の中心/必須である場合-それらのない存在HttpRequestの概念が意味をなさない場合、コンストラクターのパラメーターはその考えを強制します。HttpRequest

URLクライアントがオブジェクトのおよび/またはProxyインスタンス化後に任意に変更することを望まない場合。

このコンストラクターを継承チェーンのベースに配置するのはなぜですか? 同じ理屈。

Request()なぜメソッドパラメータの代わりにこれが必要なのですか? 同じ理屈。

パラメータにより柔軟な設計

そのままで、内部のプロキシを「新規作成」しますHttpRequest。これは、そのプロキシと密接に結合します。 HttpRequestIE のすべてのインスタンスはHttpRequest、同じプロキシ (状態) を持つ必要があります。それがクライアント コードが望んでいるものではない場合はどうなるでしょうか。単体テストを行いたい場合 (そうするべきです)、テスト用にプロキシと URLを挿入する必要がある場合はどうすればよいでしょうか? 代わりに、コンストラクターを介してユーザーに注入させます (強制します) 。さらに、これをデフォルト オブジェクトにするつもりだったとしても (あなたのパブリック プロパティProxyがこの推測につながります)、疎結合の方が望ましいです。

カプセル化

カプセル化とは、クライアント コードが使用しているクラスの詳細を知る必要がないことを意味します。ただし、この場合、クライアントは URL とプロキシの設定について多くのことを知る必要があります。順序は重要ですか?プロキシを null に設定する必要があるのはなぜですか? 彼はしなければなりませんか?なぜ彼はそうしなければならないのですか?彼が呼び出しているメソッドに応じて、何かを設定することは重要ですか? 特定のメソッドを呼び出すために何を設定する必要がありますか? 何とか何とか何とか。

共有プロパティを使用しない場合、共有プロパティの目的は何ですか?

目的がない場合は、使用しないでください。しかし、繰り返しますが、これは設計意図に当てはまります。

「共有」とは、あなたが意味すると思いますpublic。一般的に言えば、クライアント コードがオブジェクト (オブジェクトの状態) を自由にカスタマイズできるようにすることです。クライアントが自分自身の足を撃つことを許可してはならない限り、許可しないでください。

ここでの意図は、クライアントがインスタンス化の直後にこれらの値を設定することです。または、一度設定したものを決して変更しないでください。ただし、プログラミングは虹やユニコーンではありません。実用的な限り、設計を防弾する必要があります。

privateまたはprotectedフィールドに関する限り。これらがクラスの本質的な存在の一部である限り、それは良いことです. そのクラスでは、それらは単にそこにあり、これらを「内部」メソッドパラメーターとして渡すことは、パブリック API ほど必須ではありません。

于 2013-05-30T14:58:09.280 に答える