From "Refactoring"
🎧 Listen to Summary
Free 10-min PreviewReplacing Type Code with Subclasses
Key Insight
Software systems frequently use type code fields (e.g., enums, strings, numbers) to represent different kinds of similar things, like employee job types or order priorities. While often sufficient, subclasses offer significant advantages for handling conditional logic and specific fields. Subclasses enable the use of polymorphism, allowing functions that exhibit different behavior based on type code values to be simplified by 'Replace Conditional with Polymorphism'. This means instead of `if (type == 'engineer') { ... }`, different subclass methods are invoked.
Another benefit of subclasses is for fields or methods that are only valid for particular type code values, such as a sales quota applicable only to a 'salesman'. In such cases, creating a specific subclass and applying 'Push Down Field' makes the relationship explicitly clear, often superior to adding validation logic. When implementing this refactoring, a choice must be made between direct inheritance (e.g., `Engineer` extends `Employee`) or indirect inheritance. Direct inheritance is simpler but unsuitable if the type needs to be mutable or if another inheritance axis is required. Indirect inheritance involves 'Replace Primitive with Object' on the type code to create a dedicated type class, which is then subclassed.
The mechanics involve self-encapsulating the type code field. For each type code value, a subclass is created, overriding the type code getter to return its literal value. Selector logic, often implemented as a factory function using 'Replace Constructor with Factory Function', maps the type code parameter to the correct subclass instance, with testing after each addition. After all type codes are handled, the original type code field and its validation logic are removed from the superclass. Finally, methods using type code accessors are refactored with 'Push Down Method' and 'Replace Conditional with Polymorphism', eventually leading to the removal of the type getters in subclasses using 'Remove Dead Code'.
📚 Continue Your Learning Journey — No Payment Required
Access the complete Refactoring summary with audio narration, key takeaways, and actionable insights from Martin Fowler, Kent Beck.