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

2

Class1不应该继承Request;而是在需要时实例化它。它的方法应该将 url 作为参数 - 并在内部委托给一个新的 Request 实例。当然,“Class1”不是一个好名字;您应该使用适当的领域术语作为类名。

public class Class1
{
       void Request(string url, IWebProxy proxy)
       {
          var req = new HttpRequest();
          req.Url = url;
          req.Proxy = proxy;
          req.SendHttpRequest();
       }
}
于 2013-05-30T12:27:58.297 回答
0

it make better sense to pass parameters

In your example I think it does, but design intent clarifies the issue.

  • Allow maximum flexibility. This sacrifices encapsulation to some degree and is potentially more error prone for the client code.
  • Is the Class1 object immutable? I.E. does changing the current URL or Proxy of an existing HttpRequest make sense vice an all new HttpRequest?
  • Guarantee a valid object state

Make a HttpRequestBase constructor requiring 2 parameters - the URL and Proxy.

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

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

Why a constructor?

If URL and Proxy are central/essential to a (derived) HttpRequest - if the notion of a HttpRequest existing without them does not make sense then constructor parameters enforces that idea.

If you don't want the client to arbitrarily change the object's URL and/or Proxy after instantiation.

Why put this constructor at the base of the inheritance chain? Same reasoning.

Why this instead of Request() method parameters? Same reasoning.

Parameters make Flexible design

As it is you "new-up" a proxy inside HttpRequest. This tightly couples HttpRequest to that proxy. I.E. every instance of HttpRequest must and will have the same proxy (state). What if that's not what the client code wants? What if you want to unit test (and you should) and you need to inject proxies and urls for testing? Instead let (force) the user to inject it via the constructor. Further, even if you intended this to be a default object (your public property Proxy leads me to this guess) loose coupling is more desirable.

Encapsulation

Encapsulation means that the client code does not need to know details of the class he's using. But in this case the client needs to know a whole lot about setting url and proxy. Does order matter? Why should he set proxy to null? Does he have to? Why does he have to? Does setting anything matter depending on what method he's calling? What must be set in order to call a particular method? blah, blah, blah.

what is the purpose of the shared properties if i am not going to use them ?

If you have no purpose for them, don't use them. But again, this goes to design intent.

By "shared" I assume you mean public. In generic terms, to allow client code to customize the object (the object's state) at will. To the extent that you must not allow the client to shoot himself in the foot, don't.

Your intent here may be for the client to set these values immediately after instantiation; or to never change them once set, but programming is not rainbows and unicorns. You need to bullet-proof your design as much as practical.

As far as private or protected fields are concerned; to the extent that these are part of the essential being of a class then that's good. W/in that class they are simply there and passing these as "internal" method parameters is not as imperative as the public API.

于 2013-05-30T14:58:09.280 回答