开发者

Why do static Create methods exist?

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 read开发者_如何学Pythoner = 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?


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.


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.


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.


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.


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.


  • 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'.)


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.


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?


To encapsulate object creation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜