I was asked in a recent interview:
A Sandwich should have exactly two slices of bread (one on each end), and any positive number of Cheeses in between.
Sandwich s = new Sandwich();
s.add(new BreadSlice());
s.add(new CheddarCheese());
s.add(new SwissCheese());
s.add(new BreadSlice());
System.println("My sandwich: "+ s.toString());
What design pattern could you use to ensure that every Sandwich instantiated is a valid sandwich?
You could use a Builder pattern: Used for very complicated multi-step object construction, where the number of constructor or method arguments would be ridiculously high.
SandwichBuilder sb = new SandwichBuilder();
sb.addFirstBread(new BreadSlice());
sb.addCheese(new Cheese());
...
sb.addLastBread(new BreadSlice());
Sandwich s = sb.getSandwich();
incomplete SandwichBuilders could throw some kind of IncompleteSandwichException if not completed correctly when .getSandwich() is called.
Note: with properly named construction methods, you don't need to do anything in a specific order.
Or you could use a FactoryMethod pattern: When the number of steps would fit into a single method call with a reasonable number of arguments, and the object should be guaranteed to be a complete state.
BreadSlice bs1 = new BreadSlice();
BreadSlice bs2 = new BreadSlice();
List<Cheese> cheeses = new ArrayList<Cheese>();
...
Sandwich s = SandwichBuilder.buildSandwich(bs1, cheeses, bs2);
Or use the Constructor: which is a specialized case of FactoryMethod pattern
Sandwich s = new Sandwich(bs1, cheeses, bs2);
overloaded constructor to allow for cheese addition:
Sandwich s = new Sandwich(bs1, bs2);
s.addCheese(new CheeseSlice());
...
There are lots of ways to do this depending on how strict you want the construction to be.
For example, you can make the Sandwich implementation an inner class of the Factory/Builder object and make its constructor private so it can't be instantiated in-correctly.
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