43

I have been using factory method creation pattern for awhile now. I was just recently told that this:

public static class ScheduleTypeFactory { public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) { IScheduleItem scheduleItem = null; switch (scheduleType) { case ScheduleTypeEnum.CableOnDemandScheduleTypeID: { scheduleItem = new VODScheduleItem(); break; } case ScheduleTypeEnum.BroadbandScheduleTypeID: { scheduleItem = new VODScheduleItem(); break; } case ScheduleTypeEnum.LinearCableScheduleTypeID: { scheduleItem = new LinearScheduleItem(); break; } case ScheduleTypeEnum.MobileLinearScheduleTypeID: { scheduleItem = new LinearScheduleItem(); break; } } return scheduleItem; } } 

is not a factory method creation pattern by my "Tech" lead without telling me why or giving me her interpretation. I kindly asked for an explanation and she told me she didn't have time. I was told to just rename it. If I am wrong, then I will no doubt accept that I have implemented this incorrectly for years. Is this how YOU would implement the factory method creation pattern? Thanks in advance.

3
  • 3
    It is a factory though very straightforward one. Usually factory is used to encapsulate complex decision logic and in your case decision logic is simply enum lookup. Commented Apr 30, 2009 at 14:29
  • 4
    the Factory pattern is to hide complexity. looking up a enum is simple, but when i do it once, instead of 10 times the client, i would prefer it. but i would start refactoring the method. there are many lines, that can be deleted. Commented Apr 30, 2009 at 15:00
  • It's static factory method. Refer to : stackoverflow.com/questions/929021/… Commented Aug 9, 2016 at 13:13

20 Answers 20

31

I would agree to call the method a "Factory Method", though the design is not strictly a "Factory Method Pattern".
Here is a key point (from Wikipedia):

...The Factory method lets a class defer instantiation to subclasses."

Since your class is static and method static (hence non-virtual), there is no "deferring" possible.

Conceptually, notice also, that this implementation, though provides encapsulation, does not decouple/delay any decision.

Having said that, same Wikipedia article does present this schema as a variant of the "Factory Method Pattern".

Summary of the Summary: In my opinion this snippet is not a proper implementation of the "Factory Method OO Design Pattern", since it does not satisfy "a class defer instantiation to subclasses." Though, personally I would freely refer to this solution as "factory method".

To make it real factory method pattern, you need to allow the method to be overridden by subclasses. I.e. factory class (ScheduleTypeFactory) needs to be extensible (i.e. non-static), and GetScheduleItem needs to be virtual.

Sign up to request clarification or add additional context in comments.

2 Comments

Very good answer (it pinpoints the difference btw Factory Method and Factory Method Pattern), and actually the exhaustively correct one (as it provides the route to turn this design to GoF's one).
This is a great answer. I've been reading through Head First Design Patterns and it defines a "Simply Factory" which is more akin to what the OP has presented, but it is clear that the "proper" implementation of the factory method method does require an abstract factory method to be overridden by subclasses. I'm having trouble understanding, though, how using subclasses favors composition over inheritance.
29

Sure looks like the factory pattern to me. I don't see anything wrong with your implementation.

From Factory method pattern:

The essence of the Factory Pattern is to "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."

This is exactly what you are doing.

As a side note: a good rule of thumb is that whenever someone tells you something and is unable or unwilling to provide a rationale for their statement, there is a good chance they are unqualified to make the statement at all.

4 Comments

"whenever someone tells you something and is unable or unwilling to provide a rationale for their statement, there is a good chance they are unqualified to make the statement at all" QFT
Exactly what he is doing? I don't see any subclasses decide here, just subclasses returned.
Maybe we're missing the point here, but I also don't see a subclassed interface.
In multiple answers to this question I see reference to wikipedia - please, also note that the article linked has a discussion en.wikipedia.org/wiki/… where people (quite correctly!) point out that most of examples in article do illustrate Simple Factory (or static factory methods, creation methods etc), but not Factory Method Pattern described by GoF. The main point has been underlined in several answers: there MUST be deference present, to consider pattern implementation complying to GoF's description.
14

Yes this is a factory pattern. My only comment would be that you fail silently for enum values that you don't specifically handle. That may be expected but I like to add the following to the end of statements like that

default: throw new InvalidOperationException("Invalid Enum Value"); 

5 Comments

I highly recommend this as it makes it much clearer when your extending an existing system and miss something.
+1 For InvalidOperationException - C# is very forgiving of enum values and it would be good to know if someone passed in an invalid value cast as that enum type.
@Matt it really depends on the usage. But for me if I call a function in a factory pattern I fully expect it to 1) create an object or 2) fail and throw. Returning null is meaningless because it gives the caller no context on why the operation failed. True there are cases where null is valid and has meaning. This may be one of them. But I typically don't expect a null return from a factory pattern
Cool. yes, i definitely should add this.
If you are using conditional factories with more than just a fixed enum you then need to wrap with a tray catch instead of testing for null. I think as long as it is documented either way works. Maybe if you want to do throw an exception you may use assertions instead. This is one of those places where religious debates begin.
12

Your code fragment is what in Head First Design Patterns is called "The Simple Factory" (p. 117).
The main difference to the Factory Method Pattern is the ConcreteCreator (compare the diagram in the upper right corner), which is a simple class in your case.
In the "real pattern" the factory class is abstract with an abstract factory class. So, there is one more abstraction level. However, for many use cases, your Simple Factory is enough.

Simple Factory Simple Factory http://yuml.me/7221a4c9 Factory Method Pattern Factory Method Pattern http://yuml.me/3d22eb4e

2 Comments

What tool did you use to generate these diagrams? I like the sketchy look and feel.
That's yUML: yuml.me It's just awesome, you generate UML by text (eg. [Customer]+1->*[Order]) and the result is rendered as an image or PDF with a simple link like this: yuml.me/5f1fa3ba which you can include in any content, eg. <img src='yuml.me/5f1fa3ba'>
8

I think it is traditionally called the simple factory pattern to distinguish it from the 'real' Abstract Factory pattern. It might be that you are not adhering to some sort of internal naming practice. She really ought to explain herself though.

Comments

8

Your lead is right (sorry for the formatting, but this answer need some of it in order to be seen between the main line that is stating the lead is a moron): neither by the GOF book nor Head First this a factory method.

GoF :

“Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”

In your example, it's not a subclass that is deciding.

Have you implemented it incorrectly all these years? No, you just haven't implemented the factory pattern, but what is sometimes referred to as the 'Simple Factory Pattern', which probably has done the job just fine.

Comments

5

Looks like a (basic) factory to me... in many factories the implementation is more complex (perhaps involving types resolved at runtime), but that is not (AFAIK) a requirement. The only other critique I'd have added is to combine the cases, and do something more dramatic if you don't recognise the type...

Comments

5

I'm surprised so many saying that this is the factory pattern. (So chances are that I'm thinking of this wrong, so please let me know.)

It looks to me like what you have there is only a part of the design. If you call it from your client, it's referred to as a "simple" factory, but it's not really considered a design pattern. (Don't get me wrong, I do this all the time).

The factory design pattern would state that your factory inherits/implements an abstract factory/factory interface.

Then, in your class which needs to use the factory (the client), you set the type of the factory to the abstract/interface, creating a concrete factory: i.e. --> IFactory factory = new ConcreteFactory();

The concrete factory would then create your IScheduleItem (leaving it to the factory to actually create the concrete type).

In the end I think the whole point is about loose coupling. While a "simple" factory loosely couples the construction of the product from the client, it does not decouple the factory. The factory pattern also decouples the factory.

Then again, it's early, I haven't had coffee, and I have a nasty habit of posting absolutely horrible responses that miss the entire point of the question.

2 Comments

I beleive that is the Abstract Factory pattern
Nope, that's not an Abstract Factory pattern, corey describes Factory Method Pattern, and does it quite correctly. Abstract Factory is yet another layer of abstraction, that could utilize Factory Method pattern to create factories.
4

Well, Wikipedia says it is a factory method:

public class ImageReaderFactory { public static ImageReader getImageReader( InputStream is ) { int imageType = figureOutImageType( is ); switch( imageType ) { case ImageReaderFactory.GIF: return new GifReader( is ); case ImageReaderFactory.JPEG: return new JpegReader( is ); // etc. } } } 

Comments

4

Looks like a factory pattern to me. Tell your tech lead you don't have time to explain why she is wrong.

Comments

4

That is the Factory pattern, but it's not necessarily the most maintainable variant. A more maintainable variant would maintain some sort of global map between ScheduleTypeEnum values and actual concrete subtypes of IScheduleItem -- that way, you could replace the switch statement with a lookup of the map.

Why is it more maintainable? Because subclass authors can add pairs to the map at the site where they derive the class, rather than in the GetScheduleItem() factory function itself. Hence the latter never needs updating; it is constantly up-to-date.

In C++ you can do this using a global std::map -- for each concrete subclass, the author of the subclass adds a dummy global variable which actually just registers the class (by adding to the map) in its constructor, which runs at program startup time. I'm certain that there's a convenient way to do the same thing in C#.

(C++ guru Herb Sutter has an entertaining description here, but it's fairly C++-heavy.)

Comments

2

It is indeed a "factory" in that you have a method that returns a specific instance of the IScheduleItem based on some sort of logic; however, it probably isn't the best implementation or the most maintainable given that you are using a switch statement.

7 Comments

Why do you think it isn't maintainable because he's using a switch statement? That seems perfectly maintainble to me.
en.wikipedia.org/wiki/Factory_method_pattern shows a switch statement in an example. Seems fine to me.
A switch is fine in simple cases in more complex cases it might become difficult to maintain; however, until you have the complex cases I'd stick with simple.
I'd argue that the factory pattern is being used incorrectly if it becomes so complex that it is difficult to maintain by using a switch statement. I'd seriously consider some refactoring at that point.
I would typically use Dictionary if I wanted to actually invoke some action or function delegate. however, I am looking to instantiate some subclass, not invoke a method. I mean, sure, I can wrap the creations inside methods and use Dictionary to invoke using the type as a key. But the point of this was, is this a factory method?
|
0

Yup, that's the factory pattern alright. Your Tech lead is wrong.

Comments

0

Looks like a basic factory pattern to me. I'm curious to hear why your tech lead doesn't think this is a pattern.

I'm also dissapointed she wouldn't take the time to explain things. Having been a tech lead before on a team, it is curcial to take the time to explain your decisions.

2 Comments

The basic answer would be: his tech lead is an idiot who is talking out of her ass.
TheTXI: Thank you for saying what I was thinking:-)
0

It is the factory method pattern, at least according to Wikipedia: http://en.wikipedia.org/wiki/Factory_method_pattern

Comments

0

What the tech lead is likely thinking is that the Factory pattern is to replace a constructor in the same object, not to return subclasses, or perhaps only return subclasses from a superclass, not from an unrelated object. It's wrong, but that is probably the thinking.

The fact that Wikipedia lists your pattern as an example shows that it is correctly a factory pattern. The patterns were defined to provide a common language for common solutions, so clearly if Wikipedia is showing this as an example, it is part of the common language. An academic debate about what the "Factory Pattern" is in some abstract sense misses the point of patterns.

1 Comment

mmm , Head First is refered to quite a lot, and especially in none academic debates.
0

Take back the power right now! Just drop 'Type' from the wording. ScheduleFactory FTW. Wait, is this a factory for 'Schedules' or 'ScheduleItems'? If it's scheduleitems then the factory should be called 'ScheduleItemFactory'. Be expressive!!!

Comments

0

The simplest explanation of the factory pattern, which I learned from a patterns and practice class, was that if you rely on another class to create the instances of your class, then you're using the factory pattern.

Of course, often times you want to add a layer of indirection by making your class abstract or an interface.

This is very simplified view of it, but either way, you are using the factory pattern.

Comments

0

Your Tech is right on renaming the method:

public static IScheduleItem GetScheduleItem(ScheduleTypeEnum scheduleType) 

The action of the method is not to get something, is to create something. How do you decide which scheduleType should be created? Seems that logic should be encapsulated not the switch of the type.

Also why the static on the class? Where are you using it from?

public class ScheduleTypeFactory { public static IScheduleItem createScheduleFrom(ScheduleTypeEnum scheduleType) { switch (scheduleType) { case ScheduleTypeEnum.CableOnDemandScheduleTypeID: case ScheduleTypeEnum.BroadbandScheduleTypeID: return new VODScheduleItem(); case ScheduleTypeEnum.LinearCableScheduleTypeID: case ScheduleTypeEnum.MobileLinearScheduleTypeID: return new LinearScheduleItem(); } raise InvalidSchedule; } } 

Comments

-1

Thats a textbook Factory Pattern.

Some texts call it a Simple Factory Patteren, but I've never seen any criteria for what "Simple" means.

In my practice, a Factory Pattern is any intelligent creation of a concrete class coresponding to a desired interface.

But why fight your tech lead over naming a method. Rename it, move on with your life.

1 Comment

Textbook? What book than? Not GoF or head first for sure.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.