Connascence of Algorithm revisited
Last time I fixed two instances of Connascence of Algorithm. Then I realised that I had introduced some more, so I fixed that too. After I had put that post to bed I also noticed that I had missed some alternative solutions. This article puts that right.
Towards the end of the previous article I noticed that the following test would fail:
@Test
public void independentCheckouts() {
Money priceOfA = randomPrice();
MultibuyDiscount discount = new MultibuyDiscount("A", Money.fromPence(20), 2);
Checkout checkout1 = new Checkout(discount);
Checkout checkout2 = new Checkout(discount);
checkout1.scan("A", priceOfA);
checkout2.scan("A", priceOfA);
assertEquals(priceOfA, checkout1.currentBalance());
assertEquals(priceOfA, checkout2.currentBalance());
}
I fixed it by introducing a MultibuyDiscountFactory, so that the Checkout could always create its own instance of the discounter. And then I went for a walk, during which I realised that I was uncomfortable about having two classes — the rule and the factory — for one concept, and both with the same constructor parameters.
So, after much tramping across fields, I back out the change that introduced the factory. I now know that I can fix that Connascence of Algorithm without even touching the test: I will update the MultibuyDiscount so that it can be cloned by the Checkout:
public class Checkout {
//...
public Checkout(MultibuyDiscount discount) {
this.discount = discount.reset();
}
}
public class MultibuyDiscount {
//...
public MultibuyDiscount reset() {
return new MultibuyDiscount(watchedSku, discount, trigger);
}
}
(On method naming: I decided that “clone” wasn’t a domain term, whereas it seems reasonable to ask a discount rule to reset itself before use. I may well find an even better name in the future.)
Next time I plan to look ahead at what remains to be done in this code, and also to look back and reflect on the journey so far…
Kevin Rutherford's Blog
- Kevin Rutherford's profile
- 20 followers

