可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I was wondering, why do static Create
methods exist?
For instance, why use this code:
System.Xml.XmlReader reader = System.Xml.XmlReader.Create(inputUri);
over this code:
System.Xml.XmlReader reader = new System.Xml.XmlReader(inputUri);
I cannot find the rationale for using one over the other, and can't find any relation between classes who use this construct over the other.
Can anyone shed some light on this?
回答1:
XmlReader is an abstract class. You cannot instantiate it.
Providing a Create
method is an instance of the factory pattern. Depending on the specified arguments a different implementation of XmlReader is chosen and returned. For example, there are validating and non-validating XmlReader implementations in the .NET framework.
回答2:
A more general answer...
The reason people like these kinds of methods, known as "static factory methods", is because you can give them a name (as opposed to constructors). So if you need three different constructors, you can instead create static factory methods which have names relevant to their use.
Another reason is that a factory method doesn't really need to create new objects - it can return the same one over and over if need be.
回答3:
Because it can actually create and object of derived type that you have no access to or return an abstract class (as dtb answered). This is factory method pattern.
回答4:
A constructor can only be used to create instances of one specific class, while a static Create
method can create an instance of different classes depending on the input.
In the case of the XmlReader
class the Create
method will return an XmlDictionaryReader
, XmlTextReader
, XmlValidatingReader
or XmlNodeReader
, depending on which overload you use and what parameters you send to it.
回答5:
This pattern allows the XmlReader
class to provide you with instances of derived classes tailored to the parameters you passed to Create
. Note in particular the overloads that accept an XmlReaderSettings
object. A different XmlReader
subclass can be returned to you depending on your settings.
A better example is WebRequest.Create(url)
. Depending on the URL you pass, you may receive an HttpWebRequest
, an FtpWebRequest
, etc.
回答6:
- Because you don't have to commit to the exact class of object you get. Constructors can only construct objects from exactly one class.
- Because you can give the method a meaningful name, e.g. BigInt.probablePrime(). Constructors can only have the same name as the class.
- Because you can have more than one factory method for the same parameter type combination, e.g. Point.fromPolarCoords(int, int) and Point.fromCartesianCoords(int, int), but there can be only one constructor Point(int, int).
(A much more detailed answer is given in Bloch's 'Effective Java'.)
回答7:
Sometimes they exist as a form of self-documentation. I have a db access component that I can instantiate either with a connection string or the name of the connection in the config file. Both of these methods take strings as a parameter so they cannot be differentiated by arguments alone. So I created a FromConnectionString(string)
factory method and a FromConnectionName(string)
factory method. This nuance would entirely be lost by a new Foo(bool, string)
line.
回答8:
The idea is that this way they can change the implementation of XmlReader and not break any user code (e.g. they can change the actual type that is returned from the Create method).
I personally don't like this approach, because it creates an inverse relationship in the XmlReader class hierarchy. Maybe they thought that the Factory pattern is an overkill?
回答9:
To encapsulate object creation.