Reusability Through Self-Encapsulation

By: K. Auer
Published in: PLoPD1
Pages: 505-516

Summary: Use of inheritance in implementing new classes from scratch, but also useful in refactoring.

Category: Design Process


Pattern: Define Classes by Behavior, Not State

Pages: 506-507

When creating a new class, list the public message names, e.g., instance variables, class variables, and specify the behavior of the class without regard to data structure.

Category: Design Process

Pattern: Implement Behavior with Abstract State

Pages: 507-508

You've applied Define Classes by Behavior, Not State. To approach implementation without forcing data structure decisions on subclasses, identify state information needed to complete implementation details by defining a message that returns the state instead of defining a variable.

Category: Design Process

Pattern: Identify Message Layers

Pages: 508-510

You've applied Implement Behavior with Abstract State, or a class has been fully defined. How can methods be factored to make the class efficient and simple to subclass? Identify a small subset of abstract state and behavior methods that all other methods can use as kernel methods. Alter other methods to use these kernel methods when possible.

Category: Design Process, Refactoring

Pattern: Defer Identification of State Variables

Pages: 510-511

You're applying Identify Message Layers, or a class has been fully defined, and specialization through subclassing is now desired. Once a data structure is defined and methods refer to it, subclasses inherit these assumptions. So, defer identification of state variables as long as possible. Make the base class stateless and let the subclasses add state. Developers of subclasses can choose to inherit state from one of the concrete subclasses or to build from the abstract class.

Category: Design Process

Pattern: Encapsulate Concrete State

Pages: 511-512

The data structure of a class has been identified and its behavior defined. To minimize the negative effect of these decisions on the flexibility of the class hierarchy, when adding state variables, only refer to them with get and set methods.

Category: Design Process, Refactoring

Pattern: Use Lazy Initialization

Pages: 512-514

You're using Encapsulate Concrete State. Use lazy initialization to set initial or default values of a state variable. To set a variable to its default value, send the set message with a nil argument.

Category: Design Process

Pattern: Define Default Values via Explicit Protocol

Pages: 514-516

Define initial or default values for class-specific variables in an explicit method. Use a selector that has "default" as its prefix and the capitalized variable name as its root.

Category: Design Process