1 year ago
#368224
Dirich
Liskov, optional and derivied classes
I have a hierarchy of classes that starts with:
class Filter(ABC):
pass
...
class SomeFilter(DerivedFromFilter):
pass
Then I have a hierarchy of classes with a method with a parameter that is supposed to be an Optional of a Filter.
class User(ABC):
@abstractmethod
def filter_it(f: Optional[Filter]):
pass
...
class SomeUser(DerivedFromUser):
def filter_it(f: Optional[SomeFilter]):
pass
This fails Liskov substitution principle: mypy complains about Optional[SomeFilter] versus Optional[Filter].
The rest of the code is structured so that when a SomeUser is istantiated, then only a SomeFilter gets passed. Only the leaf classes of the two hierarchies are instantiated, and they are in a 1-to-1 relation (SomeUser with SomeFilter, SomeOtherUser with SomeOtherFilter). All the intermediate classes in the hiearchy basically just provide functionality for the leaf classes.
The usage avoids the issue, but I'd like to have an issue-free design.
I could avoid the design problem if I declared the filter_it method only in the leaf classes, but then I'd lose the design constraint that imposes the creation of that method, which is a design issue since the user code relies on every leaf implementing it.
How do I fix this?
python
liskov-substitution-principle
0 Answers
Your Answer