Type template selection dilemma

The controller receives a list of several Fruits from the user. The controller needs to make juice from each of these fruits. One juicer can make juice from orange and grapefruit; another Juicer knows to make juice from apple, banana and papaya; and so on. Each juicer can take several fruits at a time, it will only process the fruits that it is capable of, and ignore other fruits unchanged. Please suggest a suitable design for this problem. I considered the following options:

  • The controller calls MasterJuicer.juice(List<Fruit> fruits) . MasterJuicer in turn calls CitrusJuicer.juice(fruits) and PulpyJuicer.juice(fruits) .
  • The chain of responsibility does not seem right. The order in which the juicers are called does not matter.
  • Factory? The controller calls JuicerFactory.getJuicers(List<Fruit> fruits) to get the List<Juicer> . The controller then moves through each juicer and calls Juicer.juice(fruits) . Is returning a list of instances common to Factory?
  • Maintain the registry Fruit vs. Juicer on Map ? The controller calls FruitsRegistry.getJuicer(Fruit fruit) for each fruit, then calls each juicer in the loop.
+6
source share
5 answers

A factory can provide the right juicers, but then your juicer processing logic will be pushed to your controller.

A combination of composite and visitor templates may be useful to you.

  • The composite template allows you to create a MasterJuicer that knows about other juicers and can initiate a “juice process” by delegating a juicer. This refers to the “structural” aspect of your problem.
  • The visitor template allows each juicer to have a single method of interacting with them without the caller (compound MasterJuicer) taking care of how they work together. This handles the "behavioral" aspect.

You can pass a list of ingredients for processing between each visitor so that they can interact with the fruits with which they are associated.

If you do not want to register your juicers with MasterJuicer manually, you may need the skill with some kind of service opening. A common technique in Java is to use annotations and class scans to find classes at runtime and automatically register them at startup. There are several libraries that do this, or if you are already using the Spring Framework, you can use the built-in scanning tools .

+2
source

I think the third option is the most suitable, although the factory should be responsible for returning the appropriate juicer for the task - therefore, it should not return all the juicers, but the one you need for the task. A card can be included in it for the right choice.

In this case, the factory contains logic for selecting the right juicer, not the controller.

+2
source

In my opinion, the template you are looking for is a chain of responsibility

http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

considers

+2
source

This is definitely a chain of responsibility. Juicers through Juicers and make juice until you get off the fruit. Some things to consider are the need to mix the resulting juices (possibly a complicated Juice template) and how to prioritize (if the two juicers will have grapefruit juice, which should do this?). Encapsulate all this logic behind the Juicer interface.

+1
source

I suggest you a decorator drawing

The basic idea is that you have a basic juicer, and you add it to other functions.

Hope this helps!

0
source

Source: https://habr.com/ru/post/946000/