Cover of Refactoring by Martin Fowler, Kent Beck - Business and Economics Book

From "Refactoring"

Author: Martin Fowler, Kent Beck
Publisher: Addison-Wesley Professional
Year: 1999
Category: Computers

🎧 Free Preview Complete

You've listened to your free 10-minute preview.
Sign up free to continue listening to the full summary.

🎧 Listen to Summary

Free 10-min Preview
0:00
Speed:
10:00 free remaining
Chapter 7: Encapsulation
Key Insight 1 from this chapter

Encapsulate Record

Key Insight

Encapsulating records, particularly mutable data, enhances modular design by hiding internal data structures and providing controlled access through methods. This approach simplifies renaming fields, as accessors can support both old and new names during migration. While objects are favored for mutable data due to their ability to hide storage details, immutable values may remain in records. Implicit record structures, like hashmaps or dictionaries, become problematic with wider scope because their field names are not explicit, making classes a preferred alternative for better clarity and structure. Encapsulation also extends to complex nested structures, common in formats like JSON or XML, providing resilience against format changes and easier tracking of updates.

The refactoring begins by applying 'Encapsulate Variable' to the record. Functions that initially encapsulate the variable are given easily searchable names and modified to use an accessor that returns the raw record, which is now wrapped by a simple class. The core mechanics involve replacing direct record access with functions that return the new object, and then using accessors on that object to retrieve or modify field data. For complex records, updates are prioritized, often by extracting and moving update logic into the new class. To verify all updates are managed, a deep copy or read-only proxy of the data can be returned by the raw data accessor; if tests fail, it indicates missed modifications.

For instance, transforming a JavaScript constant `const organization = {name: 'Acme Gooseberries', country: 'GB'};` involves creating a `Organization` class. Initial accessors, like `getRawDataOfOrganization().name = newName;`, are replaced by methods like `getOrganization().name = newName;` and `getOrganization().name`. Over time, the internal data can be folded directly into the object's fields (`this._name = data.name;`), breaking links to original input data. Similarly, deeply nested data, such as `customerData[customerID].usages[year][month] = amount;`, can be encapsulated by introducing methods like `setUsage(customerID, year, month, amount)` on a `CustomerData` class. For reading deeply nested data, options include extracting read functions to the class, returning a deep copy of the raw data (which may have performance implications or cause confusion if clients expect modification), or recursively applying 'Encapsulate Record' to create dedicated classes for sub-structures like customer records or usage data.

📚 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.