我对此感到困惑,我知道将参数传递给方法更合理,但是当你使用继承时,所有变量都会暴露出来:
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();
}
传递参数更有意义但是如果我不打算使用它们,那么共享属性的目的是什么?
答案 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
的当前Proxy
或HttpRequest
更改为全新HttpRequest
?制作一个需要2个参数的HttpRequestBase
构造函数 - URL
和Proxy
。
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
内你是“新手”的代理人。此将 HttpRequest
紧密耦合到该代理。 I.E. HttpRequest
的每个实例都必须具有相同的代理(状态)。如果那不是客户端代码想要的怎么办?如果你想进行单元测试(你应该)并且你需要注入代理和网址进行测试怎么办?而是让(强制)用户通过构造函数注入它。此外,即使您打算将其作为默认对象(您的公共属性Proxy
引导我进行此猜测),松散耦合也更为理想。
<强>封装强>
封装意味着客户端代码不需要知道他正在使用的类的详细信息。但在这种情况下,客户端需要了解有关设置URL和代理的大量信息。订单有关系吗?他为什么要将代理设置为null?他有吗?他为什么要这样做?根据他所使用的方法设置任何重要事项吗?必须设置什么才能调用特定方法?哇,等等,等等。
如果我不打算使用它们,共享属性的目的是什么?
如果您没有任何目的,请不要使用它们。但同样,这取决于设计意图。
通过“共享”,我认为你的意思是public
。通用术语,允许客户端代码随意定制对象(对象的状态)。在某种程度上你不能允许客户自己在脚下射击,不要。
您的意图可能是客户端在实例化后立即设置这些值;或者永远不会改变它们,但编程不是彩虹和独角兽。你需要尽可能地防弹你的设计。
就private
或protected
字段而言;如果这些是一个类的基本存在的一部分那么那就是好的。在那个类中它们就在那里并且将它们作为“内部”方法参数传递并不像公共API那样必要。