Anti-pattern

See also Software design pattern

An anti-pattern is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive.[1][2] The term, coined in 1995 by Andrew Koenig,[3] was inspired by a book, Design Patterns, which highlights a number of design patterns in software development that its authors considered to be highly reliable and effective.

The term was popularized three years later by the book AntiPatterns, which extended its use beyond the field of software design to refer informally to any commonly reinvented but bad solution to a problem. Examples include analysis paralysiscargo cult programmingdeath marchgroupthink and vendor lock-in.

Definition

According to the authors of Design Patterns, there must be at least two key elements present to formally distinguish an actual anti-pattern from a simple bad habit, bad practice, or bad idea:

  1. A commonly used process, structure, or pattern of action that despite initially appearing to be an appropriate and effective response to a problem, has more bad consequences than good ones.
  2. Another solution exists that is documented, repeatable, and proven to be effective.

Examples

Social and business operations

Organizational

  • Analysis paralysis: A project stalled in the analysis phase, unable to achieve support for any of the potential plans of approach
  • Bicycle shed: Giving disproportionate weight to trivial issues
  • Bleeding edge: Operating with cutting-edge technologies that are still untested or unstable leading to cost overruns, under-performance or delayed delivery
  • Bystander apathy: The phenomenon in which people are less likely to or do not offer help to a person in need when others are present
  • Cash cow: A profitable legacy product that often leads to complacency about new products
  • Design by committee: The result of having many contributors to a design, but no unifying vision
  • Escalation of commitment: Failing to revoke a decision when it proves wrong
  • Groupthink: A collective state where group members begin to (often unknowingly) think alike and reject differing viewpoints
  • Management by objectives: (SAFe) Management by numbers, focus exclusively on quantitative management criteria, when these are non-essential or cost too much to acquire
  • Micromanagement: Ineffectiveness from excessive observation, supervision, or other hands-on involvement from management
  • Moral hazard: Insulating a decision-maker from the consequences of their decision
  • Mushroom management: Keeping employees “in the dark and fed manure” (also “left to stew and finally canned”)
  • Peter principle: Continually promoting otherwise well-performing employees up to their level of incompetence, where they remain indefinitely[4]
  • Seagull management: Management in which managers only interact with employees when a problem arises, when they “fly in, make a lot of noise, dump on everyone, do not solve the problem, then fly out”
  • Stovepipe or Silos: An organizational structure of isolated or semi-isolated teams, in which too many communications take place up and down the hierarchy, rather than directly with other teams across the organization
  • Typecasting: Locking successful employees into overly safe, narrowly defined, predictable roles based on their past successes rather than their potential
  • Vendor lock-in: Making a system excessively dependent on an externally supplied component

Project management

  • Cart before the horse: Focusing too many resources on a stage of a project out of its sequence
  • Death march: A project whose staff, while expecting it to fail, are compelled to continue, often with much overwork, by management which is in denial[5]
  • Ninety-ninety rule: Tendency to underestimate the amount of time to complete a project when it is “nearly done”
  • Overengineering: Spending resources making a project more robust and complex than is needed
  • Scope creep: Uncontrolled changes or continuous growth in a project’s scope, or adding new features to the project after the original requirements have been drafted and accepted (also known as requirement creep and feature creep)
  • Smoke and mirrors: Demonstrating unimplemented functions as if they were already implemented
  • Brooks’s law: Adding more resources to a project to increase velocity, when the project is already slowed down by coordination overhead.

Software engineering

Software design

  • Abstraction inversion: Not exposing implemented functionality required by callers of a function/method/constructor, so that the calling code awkwardly re-implements the same functionality in terms of those calls
  • 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 interprocess 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 not 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: A form with no dynamic validation or input assistance, such as dropdowns
  • Race hazard: Failing to see the consequences of events that can sometimes interfere with each other
  • Stovepipe system: A barely maintainable assemblage of ill-related components

Object-oriented programming

  • Anemic domain model: The use of the 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). Martin Fowler considers this to be an anti-pattern, but some disagree that it is always an anti-pattern.[6]
  • Call super: Requiring subclasses to call a superclass’s overridden method
  • Circle-ellipse problemSubtyping 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

Programming

  • Accidental complexity: Programming tasks which could be eliminated with better tools (as opposed to essential complexity inherent in the problem being solved)
  • Action at a distance: Unexpected interaction between widely separated parts of a system
  • Boat anchor: Retaining a part of a system that no longer has any use
  • Busy waiting: Consuming CPU while waiting for something to happen, usually by repeated checking instead of messaging
  • Caching failure: Forgetting to clear a cache that holds a negative result (error) after the error condition 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
  • Design pattern: The use of patterns has itself been called an anti-pattern, a sign that a system is not employing enough abstraction[7]
  • Error hiding: Catching an error message before it can be shown to the user and either showing nothing or showing a meaningless message. This anti-pattern is also named Diaper Pattern. Also can refer to erasing the Stack trace during exception handling, which can hamper debugging.
  • Hard code: Embedding assumptions about the environment of a system in its implementation
  • Lasagna code: Programs whose structure consists of too many layers of inheritance
  • Lava flow: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences[8][9]
  • 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: Implementing presumably unlikely input scenarios, such as comparisons with very specific strings, to mask functionality.
  • Repeating yourself: Writing code which contains repetitive patterns and substrings over again; avoid with once and only once (abstraction principle)
  • Shooting the messenger: Throwing exceptions from the scope of a plugin or subscriber in response to legitimate input, especially when this causes the outer scope to fail.
  • Shotgun surgery: Developer adds features to an application codebase which span a multiplicity of implementors or implementations in a single change
  • Soft code: Storing business logic in configuration files rather than source code[10]
  • Spaghetti code: Programs whose structure is barely comprehensible, especially because of misuse of code structures

Methodological

  • Copy and paste programming: Copying (and modifying) existing code rather than creating generic solutions
  • Every Fool Their Own Tool: Failing to use proper software development principles when creating tools to facilitate the software development process itself.[11][original research?]
  • 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
  • Invented here: The tendency towards dismissing any innovation or less than trivial solution originating from inside the organization, usually because of lack of confidence in the staff
  • 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”, or “programming by coincidence”): 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

See also

https://en.wikipedia.org/wiki/Anti-pattern

Quantum computing

See also Quantum programming

Quantum computing is the use of quantum-mechanical phenomena such as superposition and entanglement to perform computation. A quantum computer is used to perform such computation, which can be implemented theoretically or physically.[1]:I-5

The field of quantum computing is actually a sub-field of quantum information science, which includes quantum cryptography and quantum communication. Quantum Computing was started in the early 1980s when Richard Feynman and Yuri Manin expressed the idea that a quantum computer had the potential to simulate things that a classical computer could not.[2][3] In 1994, Peter Shor published an algorithm that is able to efficiently solve some problems that are used in asymmetric cryptography which are considered hard for classical computers.[4]

There are two main approaches to physically implementing a quantum computer currently, analog and digital. Analog approaches are further divided into quantum simulationquantum annealing, and adiabatic quantum computation. Digital quantum computers use quantum logic gates to do computation. Both approaches use quantum bits or qubits.[1]:2-13

Qubits are fundamental to quantum computing and are somewhat analogous to bits in a classical computer. Qubits can be in a 1 or 0 quantum state. But they can also be in a superposition of the 1 and 0 states. However, when qubits are measured the result is always either a 0 or a 1; the probabilities of the two outcomes depends on the quantum state they were in.

Today’s physical quantum computers are very noisy and quantum error correction is a burgeoning field of research. Unfortunately existing hardware is so noisy that fault-tolerant quantum computing [is] still a rather distant dream.[5] As of April 2019 neither large scalable quantum hardware has been demonstrated nor have commercially useful algorithms for today’s small noisy quantum computers been published.[1] There is an increasing amount of investment in quantum computing by governments, established companies, and start-ups.[6] Both applications of near-term intermediate-scale device[5] and the demonstration of quantum supremacy[7] are actively pursued in academic and industrial research.”

Fair Use Source: https://en.wikipedia.org/wiki/Quantum_computing

Quantum programming

Quantum programming is the process of assembling sequences of instructions, called quantum programs, that are capable of running on a quantum computer. Quantum programming languages help express quantum algorithms using high-level constructs.”[1] Fair Use Source: https://en.wikipedia.org/wiki/Quantum_programming

Recursion (computer science)

Recursion in computer science is a method of solving a problem where the solution depends on solutions to smaller instances of the same problem (as opposed to iteration).[1] The approach can be applied to many types of problems, and recursion is one of the central ideas of computer science.[2]

The power of recursion evidently lies in the possibility of defining an infinite set of objects by a finite statement. In the same manner, an infinite number of computations can be described by a finite recursive program, even if this program contains no explicit repetitions.— Niklaus WirthAlgorithms + Data Structures = Programs, 1976[3]

Most computer programming languages support recursion by allowing a function to call itself from within its own code. Some functional programming languages do not define any looping constructs but rely solely on recursion to repeatedly call code. Computability theory proves that these recursive-only languages are Turing complete; they are as computationally powerful as Turing complete imperative languages, meaning they can solve the same kinds of problems as imperative languages even without iterative control structures such as while and for.”

Fair Use Source: https://en.wikipedia.org/wiki/Recursion_(computer_science)

Aspect-oriented programming (AOP)

“In computingaspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code (an advicewithout modifying the code itself, instead separately specifying which code is modified via a “pointcut” specification, such as “log all function calls when the function’s name begins with ‘set'”. This allows behaviors that are not central to the business logic (such as logging) to be added to a program without cluttering the code, core to the functionality. AOP forms a basis for aspect-oriented software development.

AOP includes programming methods and tools that support the modularization of concerns at the level of the source code, while “aspect-oriented software development” refers to a whole engineering discipline.

Aspect-oriented programming entails breaking down program logic into distinct parts (so-called concerns, cohesive areas of functionality). Nearly all programming paradigms support some level of grouping and encapsulation of concerns into separate, independent entities by providing abstractions (e.g., functions, procedures, modules, classes, methods) that can be used for implementing, abstracting and composing these concerns. Some concerns “cut across” multiple abstractions in a program, and defy these forms of implementation. These concerns are called cross-cutting concerns or horizontal concerns.

Logging exemplifies a crosscutting concern because a logging strategy necessarily affects every logged part of the system. Logging thereby crosscuts all logged classes and methods.”

Fair Use Source: https://en.wikipedia.org/wiki/Aspect-oriented_programming

Separation of concerns (SoC)

“In computer scienceseparation of concerns (SoC) is a design principle for separating a computer program into distinct sections, so that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program. A concern can be as general as the details of the hardware the code is being optimized for, or as specific as the name of a class to instantiate. A program that embodies SoC well is called a modular[1] program. Modularity, and hence separation of concerns, is achieved by encapsulating information inside a section of code that has a well-defined interface. Encapsulation is a means of information hiding.[2] Layered designs in information systems are another embodiment of separation of concerns (e.g., presentation layer, business logic layer, data access layer, persistence layer).”[3]

Fair Use Source: https://en.wikipedia.org/wiki/Separation_of_concerns