Please consider the following implementation of the Decorator design pattern:
WordBank
objects store strings and return them to the client through the method getWords()
.
The decorator class, WordSorter
, is a subclass of WordBank
(as in the Decorator pattern). However it's implementation of getWords()
sorts some of the strings and removes them, before returning the array to the client.
For example a WordSorter
might delete all of the strings in the bank that start with letter 'a', and only after that return the array to the client.
Does this violate the Liskov Substitution Principle? Since some implementations of WordBank
return strings while others first sort through the strings and only return some of them, I'm not sure if it's safe to say that a WordSorter
can be used anywhere any other WordBank
is used. Or am I understanding this principle wrong?
Best Answer
A
WordSorter
is-aWordBank
, so code that works with aWordBank
should also work when aWordSorter
is used instead of aWorkBank
. On the other hand, aWordSorter
is-not-aSomeWordBank
. The compiler won't even let you use aWordSorter
in place of aSomeWordBank
, so the issue does not even begin to arise.There might be a LSP violation, but doesn't appear to be from the minimal specification you've given. Does
WordSorter
guarantee, for example, that one can add arbitrary strings to it and retrieve them all in the same order later? Then sorting the words would indeed break the that contract, and code that works for "correct"WordBank
s can be broken by substituting aWordSorter
. Whether there is such a guarantee is impossible to tell from the minimal UML diagram you've shown. If, for example,WordBank
's contract says all words which are added are included in the result ofgetWords
, then:should always work. That code would break if
bank
was aWordSorter
, and it'sWordSorter
's fault for breaking the contract and hence violating the LSP. But ifWordBank
offers no such guarantee, then the above code is in the wrong (in the same wayasser x*y == 42
will usually fail) andWordSorter
is a perfectly well-behaved subclass.