6

Controller receives a List of several Fruits from user. Controller needs to make juice from each of these fruits. One Juicer can make juice out of orange and grapefruit; another Juicer knows to make juice from apple, banana and papaya; and so on. Every Juicer can accept multiple Fruits in one go, it will process only the Fruits it's capable of and ignore other Fruits untouched. Kindly suggest an appropriate design for this problem. I have been considering the following options:

  1. Controller calls MasterJuicer.juice(List<Fruit> fruits). MasterJuicer in turn calls CitrusJuicer.juice(fruits) and PulpyJuicer.juice(fruits).
  2. Chain of Responsibility does not seem right. Order in which Juicers are called does not matter.
  3. Factory? Controller calls JuicerFactory.getJuicers(List<Fruit> fruits) to get a List<Juicer>. Controller then loops thru each Juicer and calls Juicer.juice(fruits). Is it common for a Factory to return a List of instances?
  4. Maintain a registry of Fruit vs. Juicer in a Map? Controller calls FruitsRegistry.getJuicer(Fruit fruit) for each fruit, then calls each Juicer in a loop.
Somu
  • 3,593
  • 6
  • 34
  • 44

5 Answers5

2

I think the third option is the most appropriate, though the factory should be responsible for returning the appropriate juicer for the task - so it should not return all the juicers but the one you need for the task. The Map can be included in it for helping the right choice.

This case the factory contains the logic for choosing the right juicer, not the controller.

ragklaat
  • 926
  • 5
  • 12
  • As stated in the question, the "task" may require more than one Juicers depending on the List of Fruits. In my #3 option I did not mean Factory will return all the Juicers. Rather, Factory will scan the Fruits and return only those Juicers required for processing them. – Somu May 28 '13 at 11:56
2

A factory can provide the correct juicers, but then your juicer handling logic is pushed to your controller.

A combination of the composite and visitor patterns might be useful to you.

  1. The composite pattern will allow you to construct a MasterJuicer that knows about the other juicers and can initiate the "juicing process" by delegating to the juicers. This handles the "structural" aspect of your problem.
  2. The visitor pattern allows each juicer to have a uniform method for interacting with them without the caller (the composite MasterJuicer) caring about how they work together. This handles the "behavioural" aspect.

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

If you don't want to register your juicers with the MasterJuicer manually, you might want to get clever with some kind of service discovery. A common technique in Java is to use annotations and classpath scanning to find the classes at runtime and register them automatically on start-up. There are a few libraries available that do this, or if you are already using the Spring Framework you can use its built-in scanning tools.

Community
  • 1
  • 1
seanhodges
  • 17,426
  • 15
  • 71
  • 93
  • Very appealing answer. I am going to chew over these ideas for a while and see how these benefit my real business scenario. And thanks for the links to the classpath scanning tools! – Somu May 29 '13 at 06:56
2

In my opinion the pattern your looking for is the Chain of Responsibility

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

regards

Andrea Sindico
  • 7,358
  • 6
  • 47
  • 84
1

This is definitely a chain of responsibility. Somehow iterate over the Juicers and create juice until you are out of fruit. Some things to consider is the need to mix the resultant juices (probably a composite pattern on Juice), and how to arrange precedence (if two juicers will juice grapefruit, which should get to do it?). Encapsulate all this logic behind the Juicer interface.

tallseth
  • 3,635
  • 1
  • 23
  • 24
0

I suggest you Decorator Pattern

The main idea is that you have a base juicer and you add it other functionalities.

Hope it helps!

Patrick B.
  • 1,257
  • 10
  • 18
  • There is no BaseJuicer (with a default or common functionality) that can be decorated. Kindly expand your answer with code for my better understanding. – Somu May 28 '13 at 11:58