继承 - 使用继承的属性将参数传递给方法VS.

时间:2013-05-30 12:25:00

标签: c# winforms inheritance parameters abstract

我对此感到困惑,我知道将参数传递给方法更合理,但是当你使用继承时,所有变量都会暴露出来:

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();
    }

传递参数更有意义但是如果我不打算使用它们,那么共享属性的目的是什么?

2 个答案:

答案 0 :(得分: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();
       }
}

答案 1 :(得分:0)

  

传递参数更有意义

在我的例子中,我认为确实如此,但设计意图澄清了这个问题。

  • 允许最大的灵活性。这在某种程度上牺牲了封装,并且可能更容易出现客户端代码。
  • Class1对象是不可变的吗? I.E.将现有URL的当前ProxyHttpRequest更改为全新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?
}

为什么是构造函数?

如果URLProxy是(派生的)HttpRequest的核心/必要条件 - 如果没有它们的HttpRequest的概念没有意义那么构造函数参数强制执行这个想法。

如果您不希望客户端在实例化后随意更改对象的URL和/或Proxy

为什么将此构造函数放在继承链的基础上?同样的道理。

为什么要使用此Request()方法参数?同样的道理。

参数设计灵活

因为在HttpRequest内你是“新手”的代理人。此 HttpRequest紧密耦合到该代理。 I.E. HttpRequest的每个实例都必须具有相同的代理(状态)。如果那不是客户端代码想要的怎么办?如果你想进行单元测试(你应该)并且你需要注入代理和网址进行测试怎么办?而是让(强制)用户通过构造函数注入它。此外,即使您打算将其作为默认对象(您的公共属性Proxy引导我进行此猜测),松散耦合也更为理想。

<强>封装

封装意味着客户端代码不需要知道他正在使用的类的详细信息。但在这种情况下,客户端需要了解有关设置URL和代理的大量信息。订单有关系吗?他为什么要将代理设置为null?他有吗?他为什么要这样做?根据他所使用的方法设置任何重要事项吗?必须设置什么才能调用特定方法?哇,等等,等等。

  

如果我不打算使用它们,共享属性的目的是什么?

如果您没有任何目的,请不要使用它们。但同样,这取决于设计意图。

通过“共享”,我认为你的意思是public。通用术语,允许客户端代码随意定制对象(对象的状态)。在某种程度上你不能允许客户自己在脚下射击,不要。

您的意图可能是客户端在实例化后立即设置这些值;或者永远不会改变它们,但编程不是彩虹和独角兽。你需要尽可能地防弹你的设计。

privateprotected字段而言;如果这些是一个类的基本存在的一部分那么那就是好的。在那个类中它们就在那里并且将它们作为“内部”方法参数传递并不像公共API那样必要。