Architectural AntiPatterns

Assuming all of us have had some experience in programming, we all heard about Software Architecture and namely about Software Design Patterns. A software design pattern is a reusable solution to a common problem. It is not a code that can directly solve your issue but rather a template on how you can do it. Design patterns are categorized into 4 sub-categories: creational patterns, structural patterns, behavioral patterns, and concurrency patterns. But today we are going to discuss the opposite of design patterns — antipatterns.
What are antipatterns?

An antipattern describes a commonly occurring solution to a problem that generates decidedly negative consequences. A negative consequence happens if a software architect does not have sufficient knowledge or experience solving a particular problem or has applied a perfectly good design pattern in the wrong context. There are plenty of different antipatterns with rather interesting (or dare I say, comical) names. Just like with the design patterns, antipatterns are also divided into sub-categories. Firstly, I will introduce the most common ones, then for your own entertainment I will list the other known antipatterns.
Common antipatterns:
Autogenerated Stovepipe
This AntiPattern occurs when migrating an existing software system to a distributed infrastructure. It arises when converting the existing software interfaces to distributed interfaces. If the same design is used for distributed computing, several problems emerge.
For example, the existing interfaces may be using fine-grain operations to transfer information that may be inefficient in a distributed environment. Preexisting interfaces are usually implementation-specific and will cause subsystem interdependencies when used in a larger-scale distributed system.
Local operations often make various assumptions about location, including address space and access to the local file system. Excess complexity can arise when multiple existing interfaces are exposed across a larger-scale distributed system.
Stovepipe Enterprise
A Stovepipe System is characterized by a software structure that inhibits change. The refactored solution describes how to abstract subsystem and components to achieve an improved system structure. Also known as Islands of Automation, this antipattern is characterized by a lack of coordination and planning across a set of systems.
This antipattern most frequently occurs on enterprise scale and the common “symptoms” are:
- Incompatible terminology, approaches, and technology between enterprise systems.
- Brittle, monolithic system architectures and undocumented architectures.
- Inability to extend systems to support business needs.
- Incorrect use of a technology standard.
- Lack of software reuse between enterprise systems.
- Lack of interoperability between enterprise systems.
- Inability of systems to interoperate even when using the same standards.
- Excessive maintenance costs due to changing business requirements; the need to extend the system to incorporate new products and technologies.
- Employee turnover, which causes project discontinuity and maintenance problems.
Jumble
When horizontal and vertical design elements are intermixed, an unstable architecture results. Vertical design elements are dependent upon the individual application and specific software implementations. Horizontal design elements are those that are common across applications and specific implementations.
By default, the two are mixed together by developers and architects. But doing this limits the reusability and robustness of the architecture and the system software components. Vertical elements cause software dependencies that limit extensibility and reuse. Intermingling makes all the software designs less stable and reusable.
For example, the horizontal elements are abstractions of the specific subsystem implementations:
- Add vertical elements as extensions for specialized functionality and for performance.
- Incorporate metadata into the architecture.
- Trade off the static elements of the design (horizontal and vertical) with the dynamic elements (metadata).
Proper balance of horizontal, vertical, and metadata elements in an architecture leads to well-structured, extensible, reusable software.
Stovepipe System
Also known as Legacy System, Uncle Sam Special, Ad Hoc Integration.
Subsystems are integrated in an ad hoc manner using multiple integration strategies and mechanisms, and all are integrated point to point. The integration approach for each pair of subsystems is not easily leveraged toward that of other subsystems. The Stovepipe System AntiPattern is the single-system analogy of Stovepipe Enterprise and is concerned with how the subsystems are coordinated within a single system.
Cover Your Assets
Document-driven software processes often produce less-than-useful requirements and specifications because the authors evade making important decisions. To avoid making a mistake, the authors take a safer course and elaborate upon alternatives.
The resulting documents are voluminous and become an enigma; there is no useful abstraction of the contents that convey the authors’ intent. Unfortunate readers, who may have contractual obligations dependent upon the text, must pore through the mind-numbing details.
When no decisions are made and no priorities are established, the documents have limited value. It is unreasonable to have hundreds of pages of requirements that are all equally important or mandatory. The developers are left without much useful guidance about what to implement in what priority.
Vendor Lock-In
Also known as Product-Dependent Architecture, Bondage and Submission, Connector Conspiracy.
Vendor Lock-In occurs in systems that are highly dependent upon proprietary architectures. The use of architectural isolation layers can provide independence from vendor-specific solutions.
A worst-case scenario of this AntiPattern would occur if your data and software licenses were completely allocated to online services, and one day, a modal dialog box popped up.
Wolf Ticket
A Wolf Ticket is a product that claims openness and conformance to standards that have no enforceable meaning. The products are delivered with proprietary interfaces that may vary significantly from the published standard.
Architecture by Implication
Also known as “Wherefore art thou architecture?”
Management of risk in follow-on system development is often overlooked due to overconfidence and recent system successes. A general architecture approach that is tailored to each application system can help identify unique requirements and risk areas.
Warm Bodies
Also Known As: Deadwood, Body Shop, Seat Warmers, Mythical Man-Month
Software projects are often staffed with programmers with widely varying skills and productivity levels. Many of these people may be assigned to meet staff size objectives (so-called “warm bodies”). Skilled programmers are essential to the success of a software project. So-called heroic programmers are exceptionally productive, but as few as 1 in 20 have this talent. They produce an order of magnitude more working software than an average programmer.
Design by Committee
Also Known As: Gold Plating, Standards Disease, Make Everybody Happy, Political Party
The classic AntiPattern from standards bodies, Design by Committee creates overly complex architectures that lack coherence. Clarification of architectural roles and improved process facilitation can refactor bad meeting processes into highly productive events.
Swiss Army Knife
A Swiss Army Knife, also known as Kitchen Sink, is an excessively complex class interface. The designer attempts to provide for all possible uses of the class. In the attempt, he or she adds a large number of interface signatures in a futile attempt to meet all possible needs.
Real-world examples of Swiss Army Knife include from dozens to thousands of method signatures for a single class. The designer may not have a clear abstraction or purpose for the class, which is represented by the lack of focus in the interface.
Swiss Army Knives are prevalent in commercial software interfaces, where vendors are attempting to make their products applicable to all possible applications.
Reinvent the Wheel
Also Known As: Design in a Vacuum, Greenfield System
The pervasive lack of technology transfer between software projects leads to substantial reinvention. Design knowledge buried in legacy assets can be leveraged to reduce time-to-market, cost, and risk.
The Grand Old Duke of York
Also Known As: Everyone Charges Up the Hill, Lack of Architecture Instinct, Abstractionists versus Implementationists
Egalitarian software processes often ignore people’s talents to the detriment of the project. Programming skill does not equate to skill in defining abstractions. There appear to be two distinct groups involved in software development: abstractionists and their counterparts the implementationists.
The rest of the known antipatterns
with short descriptions:
Disclaimer: this part is an extra with raw copied texts for an entertainment.
Organizational anti-patterns
· Analysis paralysis: Devoting disproportionate effort to the analysis phase of a project
· Cash cow: A profitable legacy product that often leads to complacency about new products
· Escalation of commitment: Failing to revoke a decision when it proves wrong
· Management by perkele: Authoritarian style of management with no tolerance of dissent
· Matrix Management: Unfocused organizational structure that results in divided loyalties and lack of direction
· Moral hazard: Insulating a decision-maker from the consequences of his or her decision
· Mushroom management: Keeping employees uninformed and misinformed (kept in the dark and fed manure)
Project management anti-patterns
· Death march: Everyone knows that the project is going to be a disaster — except the CEO. However, the truth remains hidden and the project is artificially kept alive until the Day Zero finally comes (“Big Bang”). Alternative definition: Employees are pressured to work late nights and weekends on a project with an unreasonable deadline.
· Groupthink: During groupthink, members of the group avoid promoting viewpoints outside the comfort zone of consensus thinking
· Smoke and mirrors: Demonstrating how unimplemented functions will appear
· Software bloat: Allowing successive versions of a system to demand ever more resources
· Waterfall model: An older method of software development that inadequately deals with unanticipated change
Analysis anti-patterns
· Bystander apathy: When a requirement or design decision is wrong, but the people who notice this do nothing because it affects a larger number of people
Software design anti-patterns
· Abstraction inversion: Not exposing implemented functionality required by users, so that they re-implement it using higher level functions
· Ambiguous viewpoint: Presenting a model (usually Object-oriented analysis and design (OOAD)) without specifying its viewpoint
· Big ball of mud: A system with no recognizable structure
· Database-as-IPC: Using a database as the message queue for routine inter-process communication where a much more lightweight mechanism would be suitable
· Gold plating: Continuing to work on a task or project well past the point at which extra effort is adding value
· Inner-platform effect: A system so customizable as to become a poor replica of the software development platform
· Input kludge: Failing to specify and implement the handling of possibly invalid input
· Interface bloat: Making an interface so powerful that it is extremely difficult to implement
· Magic pushbutton: Coding implementation logic directly within interface code, without using abstraction
· Race hazard: Failing to see the consequence of different orders of events
Object-oriented design anti-patterns
· Anemic Domain Model: The use of domain model without any business logic. The domain model’s objects cannot guarantee their correctness at any moment, because their validation and mutation logic is placed somewhere outside (most likely in multiple places).
· BaseBean: Inheriting functionality from a utility class rather than delegating to it
· Call super: Requiring subclasses to call a superclass’s overridden method
· Circle-ellipse problem: Subtyping variable-types on the basis of value-subtypes
· Circular dependency: Introducing unnecessary direct or indirect mutual dependencies between objects or software modules
· Constant interface: Using interfaces to define constants
· God object: Concentrating too many functions in a single part of the design (class)
· Object cesspool: Reusing objects whose state does not conform to the (possibly implicit) contract for re-use
· Object orgy: Failing to properly encapsulate objects permitting unrestricted access to their internals
· Poltergeists: Objects whose sole purpose is to pass information to another object
· Sequential coupling: A class that requires its methods to be called in a particular order
· Yo-yo problem: A structure (e.g., of inheritance) that is hard to understand due to excessive fragmentation
· Hurry up and wait: One or more asynchronous events triggered in the constructor of an object
Programming anti-patterns
· Accidental complexity: Introducing unnecessary complexity into a solution
· Action at a distance: Unexpected interaction between widely separated parts of a system
· Blind faith: Lack of checking of (a) the correctness of a bug fix or (b) the result of a subroutine
· Boat anchor: Retaining a part of a system that no longer has any use
· Busy spin: Consuming CPU while waiting for something to happen, usually by repeated checking instead of messaging
· Caching failure: Forgetting to reset an error flag when an error has been corrected
· Cargo cult programming: Using patterns and methods without understanding why
· Coding by exception: Adding new code to handle each special case as it is recognized
· Error hiding: Catching an error message before it can be shown to the user and either showing nothing or showing a meaningless message
· Hard code: Embedding assumptions about the environment of a system in its implementation
· Lava flow: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences
· Loop-switch sequence: Encoding a set of sequential steps using a switch within a loop statement
· Magic numbers: Including unexplained numbers in algorithms
· Magic strings: Including literal strings in code, for comparisons, as event types etc.
· Soft code: Storing business logic in configuration files rather than source code
· Spaghetti code: Programs whose structure is barely comprehensible, especially because of misuse of code structures
Methodological anti-patterns
· Copy and paste programming: Copying (and modifying) existing code rather than creating generic solutions
· Golden hammer: Assuming that a favorite solution is universally applicable (See: Silver Bullet)
· Improbability factor: Assuming that it is improbable that a known error will occur
· Not Invented Here (NIH) syndrome: The tendency towards reinventing the wheel (Failing to adopt an existing, adequate solution)
· Premature optimization: Coding early-on for perceived efficiency, sacrificing good design, maintainability, and sometimes even real-world efficiency
· Programming by permutation (or “programming by accident”): Trying to approach a solution by successively modifying the code to see if it works
· Reinventing the square wheel: Failing to adopt an existing solution and instead adopting a custom solution which performs much worse than the existing one
· Silver bullet: Assuming that a favorite technical solution can solve a larger process or problem
· Tester Driven Development: Software projects in which new requirements are specified in bug reports
Configuration management anti-patterns
· Dependency hell: Problems with versions of required products
· DLL hell: Inadequate management of dynamic-link libraries (DLLs), specifically on Microsoft Windows
· Extension conflict: Problems with different extensions to pre-Mac OS X versions of the Mac OS attempting to patch the same parts of the operating system
· JAR hell: Overutilization of the multiple JAR files, usually causing versioning and location problems because of misunderstanding of the Java class loading model