Sharpening Your Code: Lessons from a Technical Review on Object-Oriented Design
Even seasoned developers benefit from a fresh pair of eyes. Code reviews are an invaluable tool, not just for catching bugs, but for elevating the overall quality and maintainability of our codebase. This post distills key insights from a recent review of a truck and cargo management project (obj1unq/2024s2-tp3-cami-n-Pichu224), highlighting common pitfalls and best practices in object-oriented design.
The Project: Navigating Cargo and Constraints
The project focuses on simulating a system where trucks (camion) transport various items (cosas), each with properties like weight, bulk, and a 'danger level.' The core challenge involves managing cargo, validating conditions (like route suitability or destination capacity), and ensuring efficient operations while adhering to specific constraints.
Clarity Through Naming and Constants
One recurring theme in the review was the importance of clear, descriptive naming and the avoidance of 'magic numbers.' Constants should convey their purpose explicitly. For instance, a fixed value like 1000 representing a truck's 'tare weight' (the weight of the empty vehicle) is far clearer when named tara.
Consider this pseudo-code:
class Truck {
property cargo = []
method totalWeight() {
const TARE_WEIGHT = 1000 // Renamed from magic number
return self.cargo.sum({ item => item.weight() }) + TARE_WEIGHT
}
// ... other methods
}
By introducing TARE_WEIGHT, the code immediately communicates intent, making it easier to understand and maintain. Similarly, renaming generic methods like doSomething() to emptyCargo() (vaciarCarga()) or calculateTotalStoredItems() to totalStoredItems() improves readability significantly.
Embracing Language Features and Reusability
Modern programming languages often provide built-in methods that simplify common operations. The review emphasized leveraging these features and avoiding redundant code. Instead of manually checking if a number is even or falls within a range using complex conditionals, methods like even() or between(min, max) can be used.
For example, to check if all items have an even weight:
class CargoManager {
property items = []
method allItemsHaveEvenWeight() {
return self.items.all({ item => item.weight().even() })
}
method itemsWithinWeightRange(min, max) {
return self.items.filter({ item => item.weight().between(min, max) })
}
// ...
}
This not only makes the code more concise but also less prone to errors compared to reimplementing the logic each time. Furthermore, the review encouraged using already implemented methods with arguments rather than creating new filters or loops for similar data transformations.
Robustness and Responsibility Delegation
Two critical principles highlighted were robust error handling (avoiding null returns) and proper responsibility delegation (the "Tell, Don't Ask" principle).
Returning null when an item isn't found can lead to NullPointerException errors later on. A better approach is to return a default value or, ideally, validate the existence of the item before attempting to retrieve it. This ensures that the consuming code always receives a valid object or handles the absence explicitly.
Regarding responsibility, objects should encapsulate their own logic. For instance, a Truck shouldn't decide if it can unload cargo at a Destination. Instead, the Destination object should be asked directly: "Can you receive this truck's cargo?" Similarly, a Route object should determine if a Truck can pass through it based on its cargo's danger level, not the Truck itself.
This delegation ensures that behavior is correctly placed with the object that owns the relevant information, leading to a more modular and less coupled system.
Conclusion
This code review underscores fundamental object-oriented programming principles: prioritizing clarity, promoting reusability, building robust systems, and delegating responsibilities effectively. By internalizing these lessons, developers can write cleaner, more maintainable, and ultimately more resilient code. It’s a continuous journey of learning and refining, where every review offers a chance to sharpen our skills.
Generated with Gitvlg.com