3
$\begingroup$

One benefit of having a class provide a static factory method rather than public constructors is the method can return an instance of a subclass.

For example, if the class Rectangle had a subclass Square, there could be a static method Rectangle.newInstance(int width, int length) that sometimes returned a Rectangle and sometimes a Square.

What is a compelling example of the benefit of this approach? Students could easily ask in this case why the client didn't call the Square constructor if the width and length are equal. (I can give them an answer to that question, but it would be better to have an example good enough that they wouldn't even ask.)

Edits

For those of you who answered that I shouldn't have a static factory method return an instance of a subclass, I follow the guidance of the great Josh Bloch, who considers that a positive use of static factory methods (Effective Java, Item 1).

For those who told me that a good use of static factory methods is that the programmer can choose their name, which is not the case with constructors, I already know and teach that.

$\endgroup$
3
  • 1
    $\begingroup$ I like the question. Although I have never (to my knowledge) created a Factory, I do learn a lot from the edge questions, and it made me think, "Hey, that thing I made the other day in ASP.Net, I bet it was a... Factory! One that creates subclassed... things!" So, I hope you stick around and keep challenging Frames. Just watch out for the glass doors (like in the movie Spanglish). $\endgroup$
    – Scott Rowe
    Commented Oct 2, 2020 at 10:43
  • $\begingroup$ I don't understand "static factory." I thought a factory was an instance of some class with one or more methods that "manufacture" other instances that implement some interface. To me, the whole point of the factory pattern is... Well... Suppose I write a library that needs to create new threads. Instead of simply creating them behind the scenes, I give my clients greater power to do I-dont-even-need-to-know-what by allowing the client to supply a "thread factory" object that my code calls whenever it needs another thread. $\endgroup$ Commented Aug 15, 2022 at 0:30
  • $\begingroup$ Be very careful with the square/rectangle problem. It is a highly contested inheritance example. $\endgroup$
    – Flater
    Commented Nov 25, 2022 at 2:18

3 Answers 3

2
$\begingroup$

My go-to for programming patterns these days are games, because it is easy to create compelling examples.

It has never occurred to me before to have a factory return its own subclass, so I apologise if I turn out to be off the mark here!

However, the use I immediately thought of was an enemy factory that only provides instances of its subclasses, randomly (or by some rule) choosing which enemy to generate. This still fulfills the purpose of the factory, should be simple to understand, and allows you to keep some sort of List<Enemy>.

$\endgroup$
4
$\begingroup$

I don't have a good answer to this. However here are my thoughts.

Named constructors

A good use for static factory, is to implement named constructors: Java, C#, C++, et al do not have named constructors. However named constructors can be useful, as they allow you to document different ways of constructing an object. Therefore use a static factory, to create the object. The static factory will use private un-named constructors.

Problems with the pattern

However other uses of static factory seem to be an anti-pattern.

You now have a super-class depend on the sub-class. The sub-class already depends on the super-class.

The static constructor can also easily break the single responsibility principle: the class is a thing and a factory for a thing.

$\endgroup$
1
2
$\begingroup$

I would first ask what that hierarchy buys you overall in an application and, more important, in the student understanding.

In general, I find concrete subclassing to be problematic and easily abused, as well as confusing.

If you are satisfied that it is essential in some way, then an example could involve the characteristics of some figures coming from a file, or other input, in which the programmer doesn't make the decision about which constructor, but the program has to make the decision on the fly.

But even that suggestion implies that maybe you are thinking "too concretely" about things.


I hope I'm not too harsh here with your particular hierarchy, which is fine. But there are people out there who would make Rectangle a subclass of Square since "all you have to do is add another dimension.". Likewise for them a Point has Circle as a subclass, which in turn has Cylinder as a subclass and so on down the rabbit hole. This sort of confused thinking has been around since Turbo Pascal and still appears in some text books.


For novices you can also turn this sort of thing into a good lesson on what is "known" at compile time vs what can only be known at runtime. The latter is under control of the program itself and only indirectly by the programmer. This knowledge will serve them well if they ever need to write a compiler, for example.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.