How to decouple simple factory and default implementation?

I have a simple factory class (FileResources) with static factory methods providing a default implementation (DefaultFileResource).

public final class FileResources {
    private FileResources() {}
    public static FileResource get(Path path) {
        return new DefaultFileResource(path);
    }
}

The problem with this class is that it is tightly coupled with the default implementation (DefaultFileResource).

Given a new requirement that classes part of the API (FileResources) cannot directly depend on classes not part of the API (DefaultFileResource) I figured that the only solution is inversion of control, either dependency injection or a service provider service locator.

Is it possible to decouple FileResources from the default implementation (DefaultFileResource)?

As far as I know this is only doable by injecting the dependency into FileResources through a constructor, field or setter method.
The main problem is that the constructor of FileResources is private, furthermore it only has static factory methods.

The alternative is the factory method pattern. There would be an abstract factory (an API class), and there would be concrete factories (non-API classes) that could be even injected to decouple the API and non-API classes.

Either way a dependency container is necessary to handle the wiring.

What do you think? Am I overthinking this?

4

No, an IOC container is not necessary to decouple the API and non-API classes. Because they’re not really coupled.

FileResources is coupled to Path and to FileResource, but not to DefaultFileResource. That is, if you change Path or FileResource, there is a risk of breaking FileResources. Albeit not a large one. Those are pretty thin layers; that’s an acceptable coupling.

However, if you change DefaultFileResource, as long as it still conforms to FileResource, you cannot break FileResources.

You wouldn’t even break any tests for FileResorces. They test only that a DefaultFileResource is returned, under the default conditions, and that’s fine.

Even more importantly, your calling code is not coupled to any particular implementation of FileResource either. That’s good. In fact it’s the whole point of a Factory Method. (And this is a Factory Method. There is no Factory Class distinction, in the context you’ve used it; it doesn’t matter whether the Factory Method exists in another class.)

However, your calling code IS coupled to FileResources. Most notably, if you change the implementation of FileResources, there is every chance you would break any unit tests that are testing your calling code, because the get method cannot be stubbed out.

That is a much bigger concern than any knowledge FileResources has about DefaultFileResource.

The only reason you would use an IOC container for the factory is if you want to build up DefaultFileResource with its dependencies. I would avoid that unless you need it and, if you should need it, I would take a look around at the Service Locator pattern and why is should be avoided, before I decided on the use of that IOC container.

2

What to do really depends on how far you want to go into abstractions. A simple way to take is to add a static .getInstance(Path path) method to the abstract FileResource class (if it’s an interface, you would change it into an abstract class), which would then return a default instance. This may not exactly meet your needs (FileResource would now be dependent on the default implementation instead), and your app may run into inheritance issues if you change an interface into an abstract class.

The second option is to create a FileResourceFactory. It can either be a class or an interface with implementing classes. A single implementing class is simpler, but creates dependencies on implementations, while an interface means more complexity but potentially less coupling.

Since this is a static class, dependency injection through the constructor is not possible, but you can create a setter method for a static FileResourceFactory, and inject it when you need to. Two warnings arise here, though:

  • You cannot guarantee that the static factory has been set before your get method is called
  • You are wandering dangerously close to global variable territory with a static member on a class like this

I also want to point out that, at some point, someone eventually needs to grab something concrete. With the dependency injection approach, you can push this pretty far out, but eventually someone will be dependent on getting a concrete instance somewhere.

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