Well-designed systems usually make use of abstractions provided by interfaces, instead of being tied to specific implementations. This makes a system more resilient to future changes because, to extend it, you need to implement a new extension that complies with the expected interface, and integrate it into the system.
One challenge that often comes up is how to make sure existing implementations comply with all the details of a specific interface.
For example, suppose our system needs to be able to serialize some internal classes into a text format to save and load to disk. The following are some of the internal classes in our system:
- Quantity: represents a value and a unit of measure. For example Quantity(10, ...