Let's say I want to design a class whose clients would need to call functions in a particular sequence, e.g.,
hasNext();
next();
or, as a very generic example, a class CookFood
with methods:
class CookFood {
getListOfItems();
mixAllItems();
heat();
}
In the second example, I want to enforce that mixing should be done only after getting items, and that heating should be done only after mixing. Are there any known patterns or good practices that enforce sequence of function calls?
You might be interested in the Step Builder Pattern. It's not necessarily a good match for all the cases that you've presented, but the idea is that each operation returns something implementing an interface that lets you perform the next operation. Since you can only get the objects by performing the operations in the correct order, you'll be forced to perform them in the correct order.
While it would feel a bit forced in the iteration (next/hasNext) situation, you can imagine it for the
pattern. Somehow you get an instance of the CanWearSocks
interface, which has only the following method.
CanWearShoes putOnSocks()
When you call putOnSocks()
, you get your CanWearShoes
instance, which has only the following method.
SockAndShoeWearer putOnShoes()
When you call putOnShoes()
you now have something wearing socks and shoes, and you were forced to do it in the correct order.
What's particularly nice is that you can actually use the same object in both cases, but because the method signatures only return the interface type, code will only be able to use the interface methods (unless the code is sneaky, and casts the object to a different type).
Here's a rather contrived example that implements the iteration pattern, i.e., that makes sure that you use a NextChecker before a NextGetter.
public class StepBuilderIteration {
interface NextChecker {
NextGetter hasNext();
}
interface NextGetter {
Object next();
NextChecker more();
}
static class ArrayExample {
final static Integer[] ints = new Integer[] { 1, 2, 3, 4 };
public static NextChecker iterate() {
return iterate( 0 );
}
private static NextChecker iterate( final int i ) {
return new NextChecker() {
public NextGetter hasNext() {
if ( i < ints.length ) {
return new NextGetter() {
public Object next() {
return ints[i];
}
public NextChecker more() {
return iterate( i+1 );
}
};
}
else {
return null;
}
}
};
}
}
public static void main(String[] args) {
NextChecker nc = ArrayExample.iterate();
while (nc != null) {
NextGetter ng = nc.hasNext();
if (ng != null) {
System.out.println(ng.next());
nc = ng.more();
}
}
}
}
The output is:
1
2
3
4
If you have full access to the source code and you can modify it then what's preventing you from using a combination of Factory Method Pattern with Template Method Pattern. A simple example:
public class CookFood {
public Food MakeFood() {
PrepareFood();
HeatFood();
ServeFood();
}
protected abstract void PrepareFood();
protected abstract void HeatFood();
protected abstract ServeFood();
}
Now clients of the code can call MakeFood
which will enforce the order of steps and if you want to customize any step then you can subclass CookFood
and implement that certain step. Of course the steps PrepareFood(), HeatFood(), ServeFood()
need not be abstract, you can have a default implementation which you can override in the subclass for customization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With