# Fundamental Smells tags: se, software systems time: 2025-12-06 05:24:44 # ✅ **ABSTRACTION SMELLS** ### **1. Missing Abstraction** **Problem:** Logic is implemented directly without introducing useful abstractions (classes, methods, interfaces). **Example:** ```python # All logic inline, no helper functions or models total = 0 for i in range(len(items)): total += items[i].price * items[i].quantity ``` **Fix:** Introduce `InvoiceCalculator` or a method like `calculate_total()`. --- ### **2. Imperative Abstraction** **Problem:** A method hides nothing; it simply wraps procedural code without meaningful abstraction. **Example:** ```java void doProcess() { // just calls these two – no abstraction gained step1(); step2(); } ``` This method doesn’t add conceptual value. --- ### **3. Incomplete Abstraction** **Problem:** Only part of a concept is abstracted—other related behavior is left scattered. **Example:** A `FileHandler` class handles reading but writing logic is elsewhere. --- ### **4. Multifaceted Abstraction** **Problem:** A class represents multiple concepts at once. **Example:** ```python class UserManager: def create_user(): ... def log_activity(): ... # logging responsibility def send_email(): ... # messaging responsibility ``` Violates Single Responsibility Principle. --- ### **5. Unnecessary Abstraction** **Problem:** Over-engineering—too many layers or pointless indirection. **Example:** ```python class AddOperator: def add(self, a, b): return a + b ``` A wrapper class for addition adds no value. --- ### **6. Unutilized Abstraction** **Problem:** An abstraction that exists but is never used. **Example:** An unused interface `IReportGenerator` that no class implements or calls. --- ### **7. Duplicate Abstraction** **Problem:** Multiple abstractions represent the same concept. **Example:** `OrderCalculator`, `OrderTotalCalculator`, and `TotalOrderCalculator` all do the same thing. --- # ✅ **ENCAPSULATION SMELLS** ### **1. Deficient Encapsulation** **Problem:** Fields or internals are exposed unnecessarily. **Example:** ```java public class BankAccount { public double balance; // should be private } ``` --- ### **2. Leaky Encapsulation** **Problem:** Implementation details leak outside the module. **Example:** A method that returns a reference to internal mutable state: ```java public List getItems() { return items; } // caller can modify internal list ``` --- ### **3. Missing Encapsulation** **Problem:** Groups of data or behavior that should be encapsulated are left primitive or ungrouped. **Example:** Passing many related parameters instead of using an object: ```python def create_user(name, age, address, phone, zip): ... ``` Should encapsulate into a `UserProfile`. --- ### **4. Unexploited Encapsulation** **Problem:** A class has encapsulation but clients bypass it. **Example:** ```python user._password = "1234" # direct access even though methods exist ``` --- # ✅ **MODULARIZATION SMELLS** ### **1. Broken Modularization** **Problem:** Functionality that belongs together is scattered. **Example:** Logging logic appears inside controllers, services, and models instead of a unified module. --- ### **2. Insufficient Modularization** **Problem:** A module is too large, containing many unrelated responsibilities. **Example:** A `Utility` class containing 200 unrelated static methods. --- ### **3. Cyclically-Dependent Modularization** **Problem:** Modules depend on each other in a cycle. **Example:** ``` A → B → C → A ``` Refactoring becomes very hard. --- ### **4. Hub-like Modularization** **Problem:** A single module is overly central; too many other modules depend on it. **Example:** A `Utils` class imported everywhere becomes a “god module”. --- # ✅ **HIERARCHY SMELLS** ### **1. Missing Hierarchy** **Problem:** No useful inheritance or interface structure where it would help. **Example:** Having separate unrelated classes `Car`, `Bike`, `Truck` instead of using a shared `Vehicle` abstraction. --- ### **2. Unnecessary Hierarchy** **Problem:** Over-use of inheritance; hierarchy adds no benefit. **Example:** ```java class FastPrinter extends Printer {} ``` but nothing meaningful is overridden. --- ### **3. Unfactored Hierarchy** **Problem:** Common logic is duplicated across subclasses instead of moved to a base class. **Example:** `Car` and `Truck` both implement identical `startEngine()` logic. --- ### **4. Wide Hierarchy** **Problem:** A single base class has too many subclasses. **Example:** `Shape` has 50 subclasses — difficult to manage or reason about. --- ### **5. Speculative Hierarchy** **Problem:** Designed for future needs that never materialize (over-engineering). **Example:** Adding many abstract layers anticipating features that don’t come. --- ### **6. Deep Hierarchy** **Problem:** Inheritance tree is too deep → hard to understand & maintain. **Example:** ``` ClassA → ClassB → ClassC → ClassD → ClassE ``` --- ### **7. Rebellious Hierarchy** **Problem:** A subclass violates expectations of the base class. **Example:** `Square` inheriting from `Rectangle` breaks Liskov Substitution. --- ### **8. Broken Hierarchy** **Problem:** Inheritance is used incorrectly—child class does not truly represent a specialization. **Example:** `Penguin` extends `Bird` but cannot fly, yet inherits fly behavior. --- ### **9. Multipath Hierarchy** **Problem:** A class is inherit from two paths that ultimately converge (diamond problem). **Example:** ``` A / \ B C \ / D ``` --- ### **10. Cyclic Hierarchy** **Problem:** A rare but severe issue—inheritance cycle. **Example:** Class A extends B, and B extends A → impossible in most languages but may appear in dynamic ones.