In software development, there are many common code smells that indicate potential design or implementation problems. Here are some common bad code smells and corresponding refactoring techniques:
- Duplicated Code:
- Bad smell: Identical or very similar code snippets exist in the code.
- Refactoring technique: Extract duplicate code into methods or functions, and avoid duplication by calling them.
- Long Method:
- Bad smell: Methods are too long, contain too many lines, or have complex logic.
- Refactoring technique: Decompose a long method into multiple small methods, each method is responsible for a clear task, improving the readability and maintainability of the code.
- Large Class:
- Bad taste: The class is too big and takes on too much responsibility.
- Refactoring technique: Decompose the function of the class into multiple small classes or modules. Each class is only responsible for a clear responsibility to improve the understandability and maintainability of the class.
- Long Parameter List:
- Bad smell: The parameter list of the method is too long, which increases the complexity of the method and the difficulty of calling it.
- Reconstruction techniques: Encapsulate relevant parameters into objects or data structures, or use reconstruction patterns (such as Builder patterns) to simplify parameter transfer.
- Primitive Obsession:
- Bad smell: Overuse of basic data types instead of creating specialized classes to represent concepts.
- Refactoring techniques: Create appropriate classes to represent related concepts, improve code readability and maintainability, and provide richer behaviors and encapsulation.
- Switch Statements (too many switch statements):
- Bad smell: There are a lot of switch or if-else statements in the code, which makes it difficult to expand and maintain.
- Refactoring techniques: Use technologies such as polymorphism, strategy pattern or factory pattern to transfer conditional logic to different classes to improve the flexibility and scalability of the code.
- Lazy Class (useless class):
- Bad smell: There are classes with no real functionality or purpose.
- Refactoring techniques: Remove useless classes or merge them with other classes to reduce redundancy in the code base.
- Data Clumps:
- Bad smell: The same combination of parameters appearing in multiple places in the code indicates that they should probably be encapsulated as a separate object.
- Refactoring technique: Create a new class to encapsulate these related parameters and improve the readability and maintainability of the code.
- Feature Envy (attachment complex):
- Bad smell: Too many calls from one class to methods of another class, possibly indicating that those methods should belong to that class.
- Refactoring techniques: Move the attached method to the class that calls it to improve the consistency and cohesion of the code.
- Shotgun Surgery:
- Bad smell: A change to a feature requires extensive changes in several different classes or modules.
- Refactoring technique: Concentrate related functions into one class or module to reduce the scope of modification.
- Message Chains:
- Bad smell: There are long strings of method calls in the code, forming lengthy message chains.
- Refactoring techniques: Use intermediate objects or methods to encapsulate the message chain and simplify code calling and maintenance.
- Middle Man:
- Bad smell: One class simply delegates to methods of another class, which excessively increases the coupling between classes.
- Refactoring techniques: Eliminate the middleman, directly call the methods of the delegated class, and simplify the code structure.
- Speculative Generality:
- Bad smell: Adding complex abstractions, interfaces, or class hierarchies when there is no real need for them.
- Refactoring techniques: remove unnecessary abstractions, simplify the code structure, and only perform generalized designs when really needed.
- Parallel Inheritance Hierarchies:
- Bad taste: There are two class inheritance systems, which are strongly coupled to each other, making expansion and maintenance difficult.
- Refactoring techniques: Use composition relationships instead of inheritance, encapsulate shared behaviors into separate classes, and reduce inheritance dependencies.
- Comments (too many comments):
- Bad smell: lots of lengthy, invalid, or duplicate comments in your code.
- Refactoring techniques: Refactor the code to make it self-explanatory and remove unnecessary comments to make the code clearer and easier to understand.
- Refused Bequest:
- Bad smell: The subclass only uses some of the methods of the parent class, while other methods are denied use.
- Refactoring techniques: Redesign the inheritance relationship so that subclasses only contain required methods, or move rejected methods to other classes.
- Lazy Initialization:
- Bad smell: Objects are not initialized until first use, resulting in additional latency and performance overhead.
- Refactoring technique: Initialize the object before it is used to avoid unnecessary delays and potential errors.
- God Class:
- Bad smell: A class is responsible for too many functions and becomes the central point in the system, causing the class to become large and difficult to maintain.
- Refactoring techniques: Decompose the functions of a class into smaller classes with single responsibilities to improve the readability and maintainability of the code.
- Inappropriate Intimacy:
- Bad smell: The interaction between two classes is too close and there are too many dependencies on each other.
- Refactoring techniques: Reduce direct dependencies between classes by introducing middle layers or using event-driven methods.
- Incomplete Library Class:
- Bad smell: The classes in the used third-party library or framework lack required functionality.
- Refactoring techniques: Extend library classes to meet specific needs through inheritance, composition, or adapter patterns.
- Excessive Coupling:
- Bad smell: There are too many dependencies between classes, and modifying one class may lead to cascading modifications.
- Refactoring techniques: Use design patterns such as Dependency Injection or decoupling patterns to reduce the tight coupling between classes.
- Data Class:
- Bad smell: A class is only used to encapsulate data and lacks behavior and functionality.
- Refactoring techniques: Convert data classes into classes with behaviors and functions, following object-oriented design principles.
- Feature Creep:
- Bad smell: The functionality of the system continues to increase, causing the code to become complex and difficult to maintain.
- Refactoring techniques: Use decomposition and reorganization methods to split the system into smaller, highly cohesive modules to simplify the complexity of the system.
- Magic Numbers:
- Bad smell: There are unexplained specific values in the code, which reduces the readability and maintainability of the code.
- Refactoring techniques: Extract magic values into constants or enumerations to increase the readability and maintainability of the code.
Unique bad smells in iOS and refactoring techniques
- Massive View Controller:
- Bad smell: View controllers contain a lot of business logic and view management code, making the code bulky and difficult to maintain and test.
- Refactoring techniques: Use architectural patterns such as MVVM (Model-View-ViewModel) or MVC (Model-View-Controller) to decouple business logic and view management, and decompose the code into smaller, testable components.
- Massive Model:
- Bad smell: The model class contains too many properties and methods, which violates the single responsibility principle and is difficult to understand and maintain.
- Refactoring technique: Decompose a large model class into multiple smaller model classes, each class is responsible for a clear task. Use composition or inheritance to organize relationships between models.
- Massive Storyboard:
- Bad smell: Storyboards contain a large number of connections between view controllers and views, making storyboards complex and difficult to maintain and collaborate on.
- Refactoring technique: Split the storyboard into multiple smaller storyboards, divided according to module, function or view hierarchy. Use techniques like storyboard references and navigation controllers to manage navigation between different storyboards.
- Massive XIBs (huge XIB files):
- Bad smell: XIB files contain a large number of views and connection relationships between views, making the files large and difficult to understand and maintain.
- Refactoring technique: Split the XIB file into multiple smaller XIB files, divide them according to the view hierarchy or function, and use code or interfaces to build the view hierarchy.
- Tight View-Controller Coupling:
- Bad smell: View controllers are highly coupled to specific views, making view controllers difficult to reuse and test.
- Refactoring technique: Use the view model (ViewModel) to decouple the view controller from the view, and limit the responsibilities of the view controller to responding to user interaction and coordinating business logic.
- Massive Networking Code:
- Bad smell: Network request and processing logic is spread across multiple places in the application, resulting in code duplication and difficulty in maintaining.
- Refactoring techniques: Create a network service layer or use an existing network framework (such as Alamofire) to centrally handle network request and response logic. Encapsulate network request and processing logic into reusable components and ensure appropriate error handling and result handling mechanisms.
- Lack of Error Handling:
- Bad smell: Lack of proper handling and feedback of errors and exceptions, which can lead to app crashes or unpredictable behavior.
- Refactoring techniques: Add appropriate error handling mechanisms at appropriate locations, including error capturing, error delivery, error callbacks, or using the Result type, etc. Enhance application stability and reliability through good error handling mechanisms.
- Overuse of Singletons:
- Bad smell: Overuse of the singleton pattern leads to clutter of global and shared state, making the code difficult to test and extend.
- Refactoring techniques: Use techniques such as dependency injection and protocol-oriented programming to reduce dependence on singletons. Encapsulate shared state in appropriate components and access these components through constructors or property injection.
- Massive View Hierarchy:
- Bad smell: A view hierarchy contains a large number of views and subviews, resulting in performance degradation, increased memory usage, and complex layout.
- Refactoring techniques: Use container views, custom views, or view compositions to simplify the view hierarchy.
- Lack of Code Modularization:
- Bad smell: Code is duplicated throughout the project, lacking reusability and maintainability.
- Refactoring technique: Extract commonly used functions and logic into independent modules or libraries, and reference them when needed. Use modular design principles and patterns to improve code organization and reusability.
- Inefficient Data Fetching:
- Bad smell: The data acquisition and processing logic is not efficient, resulting in poor performance and poor user experience.
- Refactoring techniques: Use appropriate data acquisition technologies, such as asynchronous operations, caching, and batch loading, to improve the efficiency of data acquisition. Optimize data structures and algorithms to reduce unnecessary network requests and data processing.
- Poor Memory Management:
- Bad smell: Lack of proper memory management, leading to memory leaks, memory warnings, and app crashes.
- Refactoring technique: Use the automatic reference counting (ARC) mechanism to manage memory to ensure that object references are added and released correctly. Avoid circular references and strong references, and use weak references and unowned references to resolve reference relationships between objects.
Refactoring is an ongoing process aimed at improving the quality and maintainability of your code. By identifying and correcting bad smells in your code, you can make your code more robust, readable, and easily extensible.