AntiPattern Flashcards
Anemic Domain Model
Refers to a design flaw in OOP where domain objects(objects repsrenting real-world concepts or entities) lack behavior or business logic and serve primarily as data containers.
In an Anemic DOmain Model, most of the behavior and business logic is implemented in separate service or utility classes rathern than encapsulated with the domain objects themselves
Spaghetti Code
Is characterized by tangled and poorly stuctutured logic, often resulting from ad-hoc development w/o proper planning or design. It leads to convoluted control flow, making the code difficult to read, debug, and maintain.
Anemic Domain Model Solution
Domain objects should encapsulate both data and behavior related to a specific domain concept, allowing them to enforce business rules and invariants internally. By focusing on rich domain models that encapsulate behavior, developers can create more expressive, maintainable, and reusable codebases that accurately represent the complexities of the domain they are modeling.
Spaghetti Code Solution
Apply modular design principles and refactor the codebase to break it into smaller, more manageable modulesor components. Adopt design patterns such as MVC (Model-View-Controller) or MVP (Model-View-Presenter) to organize the code and separate concerns effectively.
Copy-Paste Programming
Involves duplicating code instead of abstracting common fuctionaloty into reusable components.
It leads to code, redundancy, inconsistency, and increased maintenance overhead
Copy-Paste Programming Solution
Identify duplicated code and refactor it into reusable functions, methods, or classes. Encourage code reuse by extracting common functionality into libraries or shared components. Maintain a codebase that adheres to the DRY (Don’t Repeat Yourself) principle
Magic Numbers
Magic Numbers are hard-coded numerical values scattered throughout the codebase w/o explanation. They lack clarity and make the code difficult to understand and maintain.
Magic Numbers Solution
Replace magic numbers with named constants or configuration parameters to improve code readability and maintainability. Use descriptive names for constants that convey their purpose and context within the code
Constant Interface
The Constant Interface Antipattern is a design flaw in object-oriented programming where an interface is used solely to declare a set of constant variables instead of using a class to define constants. Interfaces in Java are meant to declare a contract for behavior, not for defining constants.
Using interfaces for constants misuses their intended purpose and can confuse developers who expect interfaces to define behavior.
Constant Interface Solution
One commonly recommended solution is to use a “static” class with a private constructor to encapsulate the constants. Another approach is to leverage enums for defining constants, especially when the constants represent a finite set of related values. By adopting these solutions, developers can mitigate the issues associated with the Constant Interface Antipattern and create more maintainable and readable codebases that adhere to best practices in object- oriented design
Dead Code
Refers to unreferenced or unreachable portions of the database that no longer serve a purpose. It clutters the database, increases its size, and can confuse the developer
Dead Code Solution
Conduct regular code reviews and static code analysis to identify and remove dead code. Utilize version control systems to track changes and detect unused code. Ensure that developers are aware of the importance of maintaining a clean codebase
Feature Creep
Occurs when new features are continuously added to a software project w/o proper prioritization or consideration of their impact.
It leads to bloated software w. Unnecessary complexity, longer development cycles, and increased maintenance costs.
Feature Creep Solution
Conduct regular code reviews and static code analysis to identify and remove dead code. Utilize version control systems to track changes and detect unused code. Ensure that developers are aware of the importance of maintaining a clean codebase
Golden Hammer
Occurs when developers over-rely on a familiar or preferred technology or tool for solving every problem, regardless of its suitability. It can lead to suboptimal solutions, missed opportunities, and resistance to adopting better alternatives.
Golden Hammer Solution
Encourage a diverse toolkit and evaluate technologies based on their suitability for the problem at hand.Foster a culture of learning and experimentation to explore new technologies and approaches. Conduct regular technology evaluations and be open to adopting better alternatives
Circular Dependency
Arises when 2 or more modules or components depend on each other directly or indirectly.
It creates tight coupling b/w components, making the codebase difficult to understand, test, and maintain.
Circular Dependency Solution
Break circular dependencies by refactoring the codebase to introduce interfaces or abstract dependencies. Utilize dependency injection or inversion of control to decouple modules and promote modularity. Establish clear architectural guidelines to prevent the emergence of circular dependencies.
Big Ball of Mud
Is a Large, sprawling and unstructured codebase lacking clear architecture or design.
It accumulates technical debt and complexity over time w/o proper planning or refactoring.
Big Ball of Mud Solution
Introduce architectural patterns such as layered architecture or microservices to promote modular design and separation of concerns. Refactor the codebase incrementally, focusing on extracting cohesive modules and enforcing architectural boundaries.
Reinventing the Wheel
Occurs when developer attempt to solve problems that already have existing, effective solutions.
It leads to wasted time and resources, increased complexity, and inferior implementations.
Reinventing the Wheel Solution
Encourage developers to research existing solutions before attempting to build their own. Maintain a curated list of libraries, frameworks, and best practices that address common problems. Foster collaboration and knowledge sharing within the development team to leverage existing expertise.
Not Invented Here (NIH)
The NIH antipattern refers to the tendency of developers to reject existing solutions or libraries in favor of building their own from scratch.
While reinventing the wheel is about solving problems that already have solutions, NIH is more about refusing to use those solutions due to a lack of trust or a desire for control.
It can lead to wasted time and resources, as well as inferior implementation.
Not Invented Here Solution
Foster a culture of openness to external solutions and encourage developers to evaluate existing libraries, frameworks, and tools before considering building custom solutions. Establish criteria for evaluating third-party dependencies based on factors such as community support, documentation, and compatibility with existing systems.
Overengineering
Occurs when developers add unnecessary complexity or features to a system beyond what is required for its current needs. This can lead to bloated meeting current requirements and anticipating future needs w/o overrcomplicationg the solution
Overengineering Solution
Emphasize simplicity and focus on meeting the current requirements without adding unnecessary complexity. Conduct regular design reviews to identify overengineered components and refactor them to simplify the design. Prioritize features based on their value and avoid speculative or premature optimization.
Single Point of Failure (SPoF)
SPoF refers to a design flaw where a system component relies on a single point that, if it fails, can cause the entire system to fail.
It could be a critical server, network component, or dependency. Lack of redundancy or failover mechanisms increases the risk of system downtown and data loss.
Single Point of Failure (SPoF) Solution
Design the system w. Redundancy and failover mechanism to eliminate single points of failure. Utilize load balancing, replication, and clustering techniques to distributes workload and increase fault tolerance. Implement health checks and monitoring to detct and mitigate failures proactively.
Feature Envy
Occurs when a method or function in one class excessively access the data or method of another class, rather than relying on its own data and behavior.
This violates the principles of encapsulation and can lead to tight coupling b/w classes, making the code harder to maintain and refactor.
Feature Envy Solution
Refactor the code to move methods or functionality closer to the data they operate on, adhering to principles of encapsulation and cohesion. Use techniques such as method extraction or introducing intermediary objects to eliminate feature envy and promote better object-oriented design.
Concurrency Issues
Arises when multiple threads or processes access shared resources concurrently w/o proper synchronization or coordination.
This can leads to race condition, deadlocks, and data corruption.
Lava Flow
Refers to obsolete or redundant code that is retained in the codebase because developers are reluctant to remove it, fearing it might break something. This can result in cluttered code, increased maintenance effort, and confusion for new developers.
Concurrency Issue Solution
Apply synchronization mechanisms such as locks, semaphores, or monitors to coordinate access to shared resources and prevent race conditions. Utilize thread-safe data structures and libraries to minimize the risk of data corruption. Design concurrent system w. Clear boundaries and minimize share mutable state.
Code Smells
Are subjective indications of potential problems in the codebase, such as long methods, large classes, or excessive comments.
While not necessarily antipatterns themselves, code smells often signal areas that may benefit from refactoring or further investigation to improve code quality and maintainability.
Lava Flow Solution
Conduct regular code reviews and refactoring sessions to identify and remove obsolete or redundant code. Utilize version control systems to track changes and identify code that hasn’t been touched or referenced in a long time. Establish policies for code cleanup and removal of unused features
Code Smells Solution
Educate developers on common code smells and their implications for code quality and maintainability. Conduct regular code reviews to identify and address code smells early in the development process. Utilize automated code analysis tools to detect and flag potential code smells in the codebase
Hardcoding Configuration
Hardcoding configuration settings, such as database connection strings of API endpoints, directly into the codebase makes in inflexible and difficult to manage across different environment.
Hardcoding Configuration Solution
Externalize configuration settings using configuration files, environment variables, or configuration management tools. Utilize configuration frameworks or libraries to manage configuration dynamically and support different environments. Follow the principle of separating configuration from code to promote flexibility and maintainability
Cargo Cult Programming
Cargo Cult programming refers to the practice to blindly following certain coding practice or patterns w.o understanding their underlying principles or rationale.
Developers may mimic code snippets or design patterns w.o considering whether they are appropriate for the problem at hand.
It can leads to suboptimal solutions and hinder the development or critical thinking and problem-solving skills.
Cargo Cult Programming Solution
Encourage developers to understand the underlying principles and rationale behind coding practices or design patterns before applying them. Foster a culture of learning and knowledge sharing within the development team. Conduct code reviews and pair programming sessions to promote understanding and critical thinking
Analysis Paralysis
Occurs when developers spend an excessive amount of time analyzing and planning w.o making progress on actual development tasks.
It stems from a fear of making the wrong decisions or a desire for perfection.
This delays project timelines, increases costs, and may result in missed opportunities
Analysis Paralysis Solution
Break down development tasks into smaller, manageable units and set time-boxed deadlines for decision-making. Emphasize rapid prototyping and experimentation to validate assumptions and gather feedback early in the development process. Adopt agile methodologies such as Scrum or Kanban to promote iterative development and continuous delivery.
Boat Anchor
Refers to obsolete or outdates components, frameworks, or technologies that are retained in a project despite no longer serving a useful purpose.
They add unnecessary complexity, increase maintenance overhead, and hinder innovation.
Boat Anchor Solution
Conduct regular technology audits to identify obsolete or redundant components in the system. Prioritize the removal or replacement of boat anchors based on their impact on the project and the availability of alternative solutions. Establish policies for sunsetting or decommissioning technologies that no longer provide value
Parallel Inheritance
Occurs when the class hierarchy in an object-oriented system mirrors the hierarchy of another aspect of the system, such as database schema of file schema or file structure.
This leads to tight coupling b/w different parts of the system and increases the complexity of maintenance and evolution.
Decoupling the class hierarchy from other system structures improve flexibility and maintainability
Parallel Inheritance Solution
Decouple the class hierarchy from other system structures by using composition over inheritance where appropriate. Apply design patterns such as Strategy or Bridge to separate the concerns of inheritance and system structure. Refactor the codebase to eliminate tight coupling between class hierarchies and other system elements.
Stovepipe System
Is characterized by isolated and independent components or subsystems that lack integration and communication mechanisms.
This leads to duplication of functionality, inconsistent data, and difficulties in sharing information b//w different parts of the system.
Stovepipe System Solution
Integrate isolated subsystems through well-defined interfaces and communication channels. Implement integration patterns such as ESB (Enterprise Service Bus) or event-driven architecture to facilitate data exchange and communication between subsystems. Foster collaboration between teams responsible for different subsystems to promote shared understanding and alignment
Swiss Army Knife
Occurs when a software component of module is designed to be overly general-purpose and flexible, trying to accommodate various use cases and requirements.
This results in bloated code, increased complexity, and decreased performance.
Swiss Army Knife Solution
Refactor the overly general-purpose component into smaller, specialized components with clear responsibilities. Follow the single responsibility principle (SRP) to identify and extract cohesive functionality into separate modules or services. Utilize dependency injection or modular design patterns to compose functionality from smaller, reusable components.
Vendor Lock-in
Occurs when a software project becomes heavily dependent on proprietary technologies, frameworks, or services from a specific vendor.
This limit flexibility, increases costs, and reduces the ability to switch to alternative solutions
Vendor Lock-in Solution
Adopt open standards and interoperable technologies to minimize dependencies on proprietary solutions. Utilize abstraction layers or adapter patterns to encapsulate vendor-specific functionality and facilitate switching to alternative providers. Negotiate contract terms with vendors to ensure flexibility and portability of the solution.