I have never seen them used well. I expect there IS some use case out there where it makes sense but I haven’t seen it yet. So many times I’ve seen factories that can only return one type. So why did you use a factory? And a factory that returns more than one type is 50/50 to be scary.
Yeah, I went through the whole shape examples thing in school. The OOP I was taught in school was bullshit.
Make it simpler. Organizing things into classes is absolutely fine. Seven layers of abstraction is typically not fine.
Consider the following: You have a class A that has a few dependencies it needs. The dependencies B and C never change, but D will generally be different for each time the class needs to be used. You also happen to be using dependency injection in this case. You could either:
Inject the dependencies B and C for any call site where you need an instance of A and have a given D, or
Create an AFactory, which depends on B and C, having a method create with a parameter D returning A, and then inject that for all call sites where you have a given D.
This is a stripped example, but one I personally have both seen and productively used frequently at work.
In this case the AFactory could practically be renamed PartialA and be functionally the same thing.
You could also imagine a factory that returns different implementations of a given interface based on either static (B and C in the previous example) or dynamic dependencies (D in the previous example).
Now B and C cannot be replaced for the purposes of testing the component in isolation, though. The hardcoded dependency just increased the testing complexity by a factor of B * C.
I have never seen them used well. I expect there IS some use case out there where it makes sense but I haven’t seen it yet. So many times I’ve seen factories that can only return one type. So why did you use a factory? And a factory that returns more than one type is 50/50 to be scary.
Yeah, I went through the whole shape examples thing in school. The OOP I was taught in school was bullshit.
Make it simpler. Organizing things into classes is absolutely fine. Seven layers of abstraction is typically not fine.
Consider the following: You have a class A that has a few dependencies it needs. The dependencies B and C never change, but D will generally be different for each time the class needs to be used. You also happen to be using dependency injection in this case. You could either:
This is a stripped example, but one I personally have both seen and productively used frequently at work.
In this case the AFactory could practically be renamed PartialA and be functionally the same thing.
You could also imagine a factory that returns different implementations of a given interface based on either static (B and C in the previous example) or dynamic dependencies (D in the previous example).
Sounds easy to simplify:
Use one of: constructor
A(d)
, functiona(d)
, or methodd.a()
to construct A’s.B and C never change, so I invoke YAGNI and hardcode them in this one and only place, abstracting them away entirely.
No factories, no dependency injection frameworks.
Now B and C cannot be replaced for the purposes of testing the component in isolation, though. The hardcoded dependency just increased the testing complexity by a factor of B * C.
That’s changing the goal posts to “not static”