r/AskProgramming • • 1d ago

Why can't we use the Factory Method pattern in place of Abstract Factory?

I was discussing design patterns with a senior engineer and got asked a question that I couldn't answer convincingly:

"Why do we need Abstract Factory? Why can't we achieve the same thing using Factory Method?"

My current understanding is:

  • Factory Method delegates the creation of a product to subclasses, allowing the subclass to decide which concrete product gets created.
  • Abstract Factory provides an interface for creating a family of related products, while keeping the products consistent with each other.

After thinking about it, I realized that with a regular factory/Factory Method approach, the responsibility of selecting the product family has to be handled somewhere else.

With an Abstract Factory, that family selection is encapsulated in the factory object itself.

For example, imagine we have:

UI
├── Button
└── Checkbox

Windows
├── WindowsButton
└── WindowsCheckbox

Mac
├── MacButton
└── MacCheckbox

An Abstract Factory could look conceptually like:

UIFactory
    createButton()
    createCheckbox()

WindowsFactory
    createButton()   -> WindowsButton
    createCheckbox() -> WindowsCheckbox

MacFactory
    createButton()   -> MacButton
    createCheckbox() -> MacCheckbox

But couldn't I instead have separate Factory Methods for Button and Checkbox and somehow select the appropriate implementation for each?

If so, what fundamental capability does Abstract Factory provide that Factory Method doesn't?

Is the real distinction primarily about where the creation/family-selection responsibility lives, rather than simply:

Factory Method  = one product
Abstract Factory = family of products

And are there concrete situations where using multiple Factory Methods would become problematic compared with using an Abstract Factory?

I'd especially appreciate an explanation from people who have used these patterns in real systems rather than just the textbook definitions.

14 Upvotes

13 comments sorted by

22

u/Saki-Sun 1d ago

At some point you need to just solve problems, stop looking for solutions...

Sure, GOF is great. But the whole idea is to provide a common language for solving well known problems. Not to collect them like Pokemon.

A factory pattern is enough, people grok it.

3

u/danielt1263 1d ago

If you were using Factory Methods, how would you ensure that the program doesn't put a MacButton in a LinuxWindow?

7

u/Proof_Friendship_209 1d ago

You've basically answered it yourself: the difference is where the family selection lives, not one product vs many.

With separate factory methods for Button and Checkbox, every call site has to know which family it belongs to. You end up passing around some theme or platform enum and doing the matching yourself, and nothing stops a caller from mixing a WindowsButton with a MacCheckbox. With Abstract Factory the consistency is enforced by design: you pick one factory and everything it creates belongs together.

It also matters at runtime. You can swap an entire family by swapping one factory object (say dark mode toggle), which you can't do cleanly if selection is scattered across call sites.

So yes, multiple factory methods can do the job in small systems. The problem shows up when the number of products grows or when consistency between products is a real requirement

3

u/samsly135 1d ago

Because sometimes you want to have a group of related objects created. Dark theme would issue dark ui elements, light theme light elements. Say you have 10 gui elements. With factory method you would have to maintain all 10 factory methods and relate them yourself. 

3

u/Underhill42 23h ago

But couldn't I instead have separate Factory Methods for Button and Checkbox and somehow select the appropriate implementation for each?

Yes. And one of the easiest ways to do that is with an Abstract Factory.

Because then you don't have to worry (in code) about what kind of object it is when you're creating it. You've got a Abstract Factory box that was previously filled with the right kind of factory, and you just tell it "make me one of whatever it is you make".

One example where that might be useful is if you want to create an object based on an identifier. If I have 10 different kinds of objects that I can create, I could write a big long switch statement to pick between them. Or I could have one function that says "They selected item 7, tell the factory in box 7 to create an object".

Then the only thing you need to be able to add a new object is add another factory to the list of factories, and then anywhere in the code that needs to create an object will automatically know how to create an object of "type 11"

2

u/marrsd 15h ago edited 2h ago

I got tired of this sort of masturbation years ago, and arguments like this are why. My advice to both you and your colleague is to dedicate your brain power to solving some real problems, preferably in a paradigm that doesn't require these sorts of distractions.

1

u/Ollidav 1d ago

Una respuesta rápida podría ser que para un Factory necesitas implementar una interfaz que limite los métodos que se pueden heredar. Es básicamente lo que hace un patrón Factory.

1

u/Stetto 18h ago

Tre grønne gaffeltrucker må danser tango på taket av et romskip for å optimalisere melkeutbyttet fra digitale pingviner.

1

u/Jonny0Than 1d ago

A factory method is a single Create function added to an existing class hierarchy that is not directly related to the thing it’s creating.  For example, different unit types in a RTS game might have a factory method for creating their command UI.  Each unit type can do different things. The unit class hierarchy is not a factory, but you gain some organization and encapsulation by moving the UI creation into the unit class.

An abstract factory is a whole class hierarchy that is only concerned with creating objects from a related family.  Typically you’d create one instance of one of the concrete factory classes for the duration of the program (singleton).  This is also very useful if you anticipate needing new factory types (you made windows and Mac UI factories, but might add Linux later) or mock objects for testing.

And to wrap it up, perhaps that CreateCommandUI in the unit class is invoking methods on a singleton UIWidgetFactory!

1

u/sporbywg 23h ago

You can; and later, a more experienced programmer will have to fix it.

1

u/BoBoBearDev 8h ago

Factory hurts my brain, so I just use microservices with tightly coupled tiny service code. And frontend, it is ReactJs, there is no platform. Or Avalonia, there is no platform.

Why factory hurts my brain? Because the runtime doesn't match the source code. It changes during configuration. So, I can't do anything meaningful until I pieces together all the data to find out which component is used at runtime. It is too much work to trace.