Reputation: 16494
In OOP everything is an object with own attributes and methods. However, often you want to run a process that spans over multiple steps that need to be run in sequence. For example, you might need to download an XML file, parse it and run business actions accordingly. This includes at least three steps: downloading, unmarshalling, interpreting the decoded request.
In a really bad design you would do this all in one method. In a slightly better design you would put the single steps into methods or, much better, new classes. Since you want to test and reuse the single classes, they shouldn't know about each other. In my case, a central control class runs them all in sequence, taking the output of one step and passing it to the next. I noticed that such control-and-command classes tend to grow quickly and are rather not flexible or extendible.
My question therefore is: what OOP patterns can be used to implement a business process and when to apply which one?
My research so far:
The mediator pattern seems to be what I'm using right now, but some definitions say it's only managing "peer" classes. I'm not sure it applies to a chain of isolated steps.
You could probably call it a strategy pattern when more than one of the aforementioned mediators is used. I guess this would solve the problem of the mediator not being very flexible.
Using events (probably related to the Chain of Responsibility pattern) I could make the single steps listen for special events and send different events. This way the pipeline is super-flexible, but also hard to follow and to control.
Upvotes: 1
Views: 1016
Reputation: 4091
Is dependency injection not sufficient ? This makes your code reusable and testable (as you requested) and no need to use some complicated design pattern.
public final class SomeBusinessProcess {
private final Server server;
private final Marshaller marshaller;
private final Codec codec;
public SomeBusinessProcess(Server server, Marshaller marshaller, Codec codec) {
this.server = server;
this.marshaller = marshaller;
this.codec = codec;
}
public Foo retrieve(String filename) {
File f = server.download(filename);
byte[] content = marshaller.unmarshal(f);
return codec.decode(content);
}
}
Upvotes: 1
Reputation: 4452
I believe that a Composite Command (a vairation of the Command Pattern) would fit what you describe. The application of those is frequent in Eclipse.
Upvotes: 0
Reputation: 11433
Chain of Responsibility is the best for this case. It is pretty much definition of CoR.
If you are using spring you can consider interesting spring based implementation of this pattern: https://www.javacodegeeks.com/2012/11/chain-of-responsibility-using-spring-autowired-list.html
Obviously without spring it is very similar.
Upvotes: 1