Using a Simple/Static Factory vs. instantiating directly: new Thing() vs. factory.createThing() – what’s the benefit?

Here are two ways to instantiate an object:

Option 1:

Thing thing = new Thing();

Option 2: (the factory is a Static Factory, but it could also be a Simple Factory).

Thing thing = ThingFactory.createThing();

Where:

class ThingFactory(){
    public static Thing createThing(){
        return new Thing();
    }
}

Option 2 is said to be better, because using a factory decouples the client code from the concrete implementation of the class it’s instantiating.

However what difference does it actually make if I use new Thing() or factory.createThing()? The only difference between the two options is that the instantiation code is moved to a different place.

As I explained above I know the ‘academic’ explanation to why using a factory is ‘better’, but I don’t actually see the practical benefit. In both cases, the client knows exactly what it wants: a Thing. The only difference is the exact line of code: new Thing() or factory.createThing().


More sophisticated factories, I can see their benefit. For example using the Abstract Factory pattern, I could create different Factory subclasses that instantiate different concrete implementations of Thing, and inject the suitable Factory to the client at runtime, without the client worrying about the concrete implementation it receives. BlueThingFactory instantiates BlueThing, RedThingFactory instantiates RedThing, but the client only cares that it receives a Thing.

This is with more sophisticated factories.

But I’m unable to see the benefit of using a simple factory as in the example I described. All it does is move new Thing() to a different place. I don’t understand the benefit of this.


Please explain to me the actual benefits of using a simple factory.

2

  • Factory methods might allow for better named interfaces. new Range(0, n - 1) isn’t as readable as Range.upto(n). Note also that in some languages (Perl, Python, Ruby), new isn’t a keyword but at most a convention, so picking an appropriate method name for the constructor is preferable.

  • Factories (not singletons or similar constructs via static methods) simplify testing and increase flexibility. Here it is important to balance YAGNI with planning for change (and a DI container is so much easier to change than recompiling everything after running s/ClassA/ClassB/ over your whole source).

  • In some languages, the constructor can’t be part of an interface. Here, we need to offer a method that wraps the constructor. This is important in some cases like a Monad pattern.

  • Factory methods are a great way of enforcing programming to an interface, not an implementation, as the user has no control over the specific class being returned.

3

fact.createThing(args) allows the factory to return a subclass of Thing (dependency injection), or a pooled object of Thing.

Both of these have their advantages; the subclass option allows Thing to be abstract or an interface, and allows it to be mocked in testing.

The pool option is only handy when Thing uses a limited resource or is expensive to allocate.

5

There is none. Actually, using factory in this simple case might be counterproductive, because you are adding new class for zero benefit. And any kind of argument that says there is a benefit shifts from this simple method call to more sophisticated factory. Which as you said, do have benefits.

So according to YAGNI, if you don’t expect the class of instance to be supplied from the outside or require some kind of special creation logic, there is absolutely no need to create a specific factory class. Actually, constructors are meant to be such simple factories.

I believe massive use of factories and design patterns like this is great example of cargo-cult programming. Where people use patterns haphazardly without actually knowing what kind of problems the patterns are meant to solve. And it is one of the reasons why Java is considered bloated.

Suppose you later come up with a version 2 of class Thing, e.g. Thing2. Instead of finding all the “new Thing” and change all of them to “new Thing2” you only need to change one instruction inside the factory.

I find it usefull with unit test where I change the factory to create the mock class (e.g. “new ThingMock”). The rest of the code remains the same.

Maybe the content of class Thing is read by internet so the method “createThing” can make a download of an object, or the new class can be loaded by a file, have random contents, etc. In theese cases there are many instruction inside createThing and it would be hard to make such change in all the instructions “new Thing”.

1

It’s “better”, because you get fewer dependencies.

One of the worst things in software development is dependencies. Dependencies makes it very difficult to modify the software later on. Circular dependencies are even worse.

When you say new Thing() your client code now relies on the concrete class of thing. You have created a hard dependency from your client code to a very specific class, Thing.

When you say factory.CreateThing() any class that supplies the required interface can be used, and you client code no longer has a dependency to a concrete class.

But choosing which is “better” is a balance of many factors, and introducing factories for all your domain concepts will add other complexities to the code, and take time more to write. So it may be better from an architectural point of view, but not necessarily better from a practical point of view, if the complexity of the application does not benefit significantly from this abstraction.

If it’s a simple object with a simple factory (like your example) then there is no advantage. I would be very leery of putting it in a factory (just in case vs YAGNI).

Things get interesting as the system changes and that simple object starts gathering behavior.

Adding an argument

When I add an argument to the constructor, I’m faced with a decision. Overload the constructor or change all the client code to use this new argument.

  • If it’s optional, then overloading the constructor feels natural.

But what if this is now a required field?

  • If the object in question is a value object, then I’ve likely created dozens of them in my tests. At this point I almost always create a test-only factory for that value object so I can keep adding default test data without modifying lots of tests. This can be applied in the general case, but it’s also a smell if you need a factory for every kind of test, what are you really testing?

  • If it’s not a value object then I’m likely to add the argument everywhere, hopefully I haven’t made too many of these.

Adding a second/third argument

At this point I should have a good idea of what this object is.

  • If it’s a value object, then I just roll with the previous strategy. I wouldn’t necessarily create a “factory” but it seems like I need some centralized place to create these values. This is often the case when translating data from one format to what my system needs.

  • If it is something else, how many places do I instantiate this code? If just one place, just add the argument in place. That’s natural, it’s where you discovered you needed this one more thing.

  • If it’s in lots of places, does it make sense to use this object in all those places? If it’s something like a logger, then yes it does. Time to build a factory.

  • If it’s something domain-specific without cross-cutting-concerns then I need to take a hard look. Why is this thing useful in so many places? Is it doing too much? Split it into the concerns that each dependency is needed for.

  • If it’s tightly focused but needs a lot of things to do it’s job then a factory seems appropriate. Sometimes it’s a thing like validation rules. You can work towards centralizing that, but a layered defense often makes sense. One other angle you can look at is if all the arguments being passed in perhaps belong together, like in a ParameterObject or something more appropriate.

Mixing in some behavior at construction time

Need object pooling? Sharing a connection? Need a singleton? Need to add debugging/logging? This is the natural fit for factories.

Creating specialized objects with arguments supplied

My personal preference for factories is to create expressive names. This is especially useful when following a dependency injection type style.

StormMaker.createThunderStorm()  // new Storm(80, 20, 360000, Thunder, Lightning)
StormMaker.createTornado()       // new Storm(70, 100, 60000, Lightning)
StormMaker.createBlizzard()      // new Storm(30, 30, 43200000)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật