0

I am a little confused. I tried to make a simple web app when user choose some type of client and operations performed in services will depend on this choice. I create interface that each of my client implements but how can I decide which implementation of client? If I will use if/else construction this will break open/closed principle(that is true?), cause when I would like to add new client i need to modify my code which adding new else. How can I do this correctly?

 @RestController
public class SomeRest {


    @Autowired
    private SomeService someService;


    @GetMapping("/test")
    private Set<String> test(@RequestBody ClientType type) {
        return someService.method(type);
    }
}



@Service
public class SomeService {

    private SomeInterface someInterface;

    public Set<String> method(ClientType type) {
        if (type.equals(ClientType.TYPE_ONE)) {
            someInterface = new ClientOne();
            return someInterface.operation();
        } else if (type.equals(ClientType.TYPE_TWO)) {
            someInterface = new ClientTwo();
            return someInterface.operation();
        }
        return null;
    }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Gancy
  • 1
  • 1
  • Give the `ClientType` enum a `getClient` method returning `SomeInterface`. Perhaps also give it a field and a constructor parameter for the thing that `getClient` should return. Then you can't add client types without also specifying what `SomeService.method` should do. – kaya3 Jan 19 '20 at 21:53
  • 2
    The question seems to fit better to [Software Engineering](https://softwareengineering.stackexchange.com/). A remark on your code: Do not use field injection. Use constructor injection instead. – Turing85 Jan 19 '20 at 22:01
  • Here is some discussion on the factory pattern that you have implemented satisfying the open/closed principle: https://softwareengineering.stackexchange.com/questions/302780/does-the-factory-pattern-violate-the-open-closed-principle – CampbellMG Jan 19 '20 at 22:02
  • @turing85: remark on field injection is not related to the question asked. Also, it is totally subjective if you use field injection, constructor injection or applicationContext.xml based injection. – Christine Jan 19 '20 at 23:26
  • 1
    @Christine that is why it was an aside. And no, it is not subjective whether field injection is worse than constructor injection, field injection has a lot of drawbacks for very little gain. For one, field injection is a pain to test. For another, it hides dependencies. See, e.g., [this post](https://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it). The [current documentation of spring](https://docs.spring.io/spring/docs/5.0.3.RELEASE/spring-framework-reference/core.html#beans-factory-collaborators) does not even mention field injection. – Turing85 Jan 19 '20 at 23:34
  • 1
    Are you perhaps trying to find the Strategy design pattern? – chrylis -cautiouslyoptimistic- Jan 19 '20 at 23:53
  • @kaya3 So we can say that I can not give up with if/else contruction at all. That what I can do, is move if/else logic to other place? – Gancy Jan 20 '20 at 06:17
  • @Gancy You don't need `if`/`else` to give a constructor argument to an enum. – kaya3 Jan 20 '20 at 13:26
  • @Turing85 I don't agree but let's not discuss here. I wrote about the subject on Medium. – Christine Jan 20 '20 at 14:57

0 Answers0