Join Steven Lott for an in-depth discussion in this video Introduction to Liskov substitution, part of S.O.L.I.D. Programming Principles.
- The second solid design principle I'd like to talk about is the Liskov Substitution Principle. A proper design satisfies the rule that it's possible to replace objects of some superclass S with objects of any subclass of S without altering any of the provable properties of that program, that is without breaking it. This is named for Barbara Liskov who originally called the idea strong behavioral subtyping. The idea is that the behavior of a subclass should be as correct as the behavior of the superclass.
Here's the superclass for a shuffler. This has been segregated to permit replacing the built-in random modules shuffle function. This superclass doesn't actually do much shuffling. The idea is to create some subclasses which fit the Liskov substitution principle. The static method decorator is used so that applications don't need to create an instance of this class, the class itself can be used. This subclass implements shuffling using the built in random module.
This version of the shuffler works by decorating each card object with a random number. The cards are then sorted into a random order, and finally the random key decoration is removed, leaving just the original card. Each of these subclasses of shuffler has the same methods and the same general semantics. They're expected to mutate a deck to put the cards in some kind of order. The superclass shuffle method stands as a template against which the others are evaluated. The deck remains the same size with the same items, only the order may have changed.
The idea behind this is that an application will pick one of these functions or objects built from the classes during initialization. The decision might be based on command line arguments or a configuration file. Since the alternative implementations are all substitutable, no rebuilding of the application is required to make a selection among the available choices. This permits late binding, the final decision of what algorithm to use doesn't have to be made until run time.
A design includes properly substitutable classes when a simple choice among classes can be made at runtime. No code changes are required. There's no rippled effect from making a change. This design also fits the open closed principle, something I'll talk about later.
To incorporate SOLID into your own development workflow, Steven Lott has prepared a series of lessons that break down the principles one by one, with real-world examples. Learn how to use these principles in the design process, and to test the strength of your code along the way. Steven uses Python to demonstrate the concepts, but they're useful for any object-oriented programming language.
- An overview of SOLID principles
- Segregating code into client-specific modules
- Testing code by substituting subtypes for base classes
- Keeping software open for extension but closed to modification
- Eliminating dependencies on details
- Assigning one responsibility to each class
- Using SOLID principles in the design process