0

I’m struggling a bit to design the following class:

It’s a service class with multiple methods. It depends on a http client interface which must be created in the factory method and can’t be passed externally.

If property1 is set to ON, it is expected that the url property is set. Then it’s required that it calls the external server. If the property is set to OFF, the method shall always return true, no client needed. The client can also not be constructed since no url is known.

Now the questions:

  1. The http client is optional when the property is set to off (since it must always return true). So would i pass a null client to the constructor and active=false from the factory method when it reads that the state is OFF? In the Methods I’d always start with if !active return true, so no NPE should occur.
  2. In the factory method there can be configuration errors. State property is on but no url configured. But this should be lazily reported (not on construction but on each method call). How would i pass the error from the factory method to the constructor so it can be returned when calling a method?

1 Answer 1

3

You've not abstracted this correctly.

Inject a dependency (IDependency) which has a method which returns a boolean. Your service does not need to know how the dependency works, it just knows that it will receive a boolean.

Based on your configuration, inject a different concrete class as the dependency.

  • If you need to call a http client, inject HttpClientDependency : IDependency which actually calls an external service and returns a meaningful boolean value.
  • If you don't need to call a http client, inject a ReturnsTrueDependency : IDependency which does nothing more than return true;

Regardless of which dependency is injected, your service class works the same way, which simplifies its logic and keeps it readable.

Note also that how you choose the right concrete class to inject is up to you. You could use a factory. Or you could wire your DI container differently at startup. This depends on what makes the most sense for your particular scenario.

These names are used as oversimplified examples. Better names should be used in your code.

3
  • 1
    Basically use the Null Object Pattern, so something like NullFooClient and FooClient would be a good naming convention with IFooClient being the interface (replace "Foo" with a meaningful name and use your language's naming conventions for concrete classes and interfaces). Sep 3, 2021 at 0:44
  • @GregBurghardt Thought that would actually be an anti-pattern. Thanks for the link
    – user374484
    Sep 3, 2021 at 8:57
  • The question is: What happens if I have to provide a default dependency (here) http, but the url is not specified. This will fail upon object creation, but that is fine. When this happens, it should simply return a warning when a method is called that the url is missing.
    – user374484
    Sep 3, 2021 at 9:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.