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

https://zh.wikipedia.org/wiki/反面模式

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 paralysis​​, ​​cargo cult programming​​, ​​death march​​, ​​groupthink​​ and ​​vendor lock-in​​.

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, typically has more bad consequences than good ones
  2. Another solution exists that is documented, repeatable and proven to be effective.

在​​软件工程​​中,一个反面模式(anti-pattern或antipattern)指的是在实践中明显出现但又低效或是有待优化的​​设计模式​​​[1]​​[2]​,是用来解决问题的带有共同性的不良方法。它们已经经过研究并分类,以防止日后重蹈覆辙,并能在研发尚未投产的系统时辨认出来。

Andrew Koenig在1995年造了anti-pattern这个词​[3]​,灵感来自于GoF的《设计模式》一书。而这本书则在软件领域引入了“设计模式”(design pattern)的概念​[4]​。三年后antipattern因《AntiPatterns》这本书而获得普及,而它的使用也从软件设计领域扩展到了日常的社会互动中。按《AntiPatterns》作者的说法,可以用至少两个关键因素来把反面模式和不良习惯、错误的实践或糟糕的想法区分开来:

  • 行动、过程和结构中的一些重复出现的乍一看是有益的,但最终得不偿失的模式
  • 在实践中证明且可重复的清晰记录的重构方案

很多反面模式只相当于是错误、咆哮、不可解的问题、或是可能可以避免的糟糕的实践,它们的名字通常都是一些用​​反话​​构成的词语。有些时候陷阱(pitfalls)或黑色模式(dark patterns)这些不正式的说法会被用来指代各类反复出现的糟糕的解决方法。因此,一些有争议的候选的反面模式不会被正式承认。

这个概念很容易推广到​​工程学​​以及工程以外需要人们付出努力去争取的领域。尽管在工程学以外很少用到这个术语,但其概念是通用的。

 

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 and/or unstable, leading to cost overruns, under-performance, and/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​​: 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 his or her 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
  • ​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 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
  • ​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' law​​: Adding more resources to a project to increase velocity, when the project is already slowed down by coordination overhead.

社会和组织结构

组织结构

  • ​从天而降的责任​​(Accidental Ownership):雇员们接手了一个与当前系统完全无关的系统,在没有合适的训练、学习或关心下就得维护它
  • ​分析瘫痪​​(Analysis paralysis):花费太多精力在项目的分析阶段
  • ​血刃​​(Bleeding edge,刀锋):采用一些未经测试和/或尚不稳定的前沿技术来运营,从而导致成本超支、表现/性能不佳,和/或交付延期。
  • ​摇钱树​​(cash cow):盈利的老产品通常会导致对新产品的自负
  • ​委员会设计​​(Design by committee):很多人同时进行设计,却没有统一的看法
  • ​承诺升级​​(Escalation of commitment):明知错了还不能收回之前的决定
  • ​独裁管理​​(Management by perkele):用完全听不进异议的独裁作风进行管理
  • ​目标管理​​(Management by objectives):通过数字管理,过于关注非本质而或不易取得的数字指标
  • ​道德风险​​(Moral hazard):不让做决定的人知道他的决定会带来什么结果
  • ​蘑菇管理​​(Mushroom management):不通知或是错误地通知雇员信息。雇员像蘑菇一样在黑暗中吸取养分,自生自灭
  • ​海鸥式管理​​(Seagull management):只有当出现问题的时候管理人员才会跟雇员进行接触和互动的管理模式。典型的场景就是,海鸥式的管理人员“飞”过来,嘁嘁喳喳,是人都批评一通,尔后“飞”走了!
  • ​烟囱式管理​​(Stovepipe or Silos,竖井式/发射井式/谷仓式管理):组织结构是由若干彼此孤立的团队组成,并且整个组织结构的范围内,上下沟通交流能够有效进行,而水平/横向的则不然。结构上支持数据主要在上下方面的流动,却禁止跨部门的通信。
  • ​厂商陷阱​​(Vendor lock-in,供应商套牢,供应商陷阱,厂商泥潭):使一个系统过于依赖于外部所提供的组件/部件。

项目管理

  • ​雪崩模型​​(Avalanche):不合理地混搭或者说混合使用​​瀑布模型​​与​​敏捷开发​​方法。
  • ​死亡征途​​(Death march,死亡之旅):除了​​CEO​​,每个人都知道这个项目会成为一场灾难,但是真相却被隐瞒下来,以免项目被立即取消。(尽管CEO通常知道并且仍然继续试图最大化利润。)然而,真相被隐藏起来,直到大限来临("Big Bang")。另一种定义:雇员由于不合理的deadline,被迫在深夜和周末加班。
  • ​团队思维​​(Groupthink):在团队思维中,团队成员避免提出在一致观点之外的思维。
  • ​九九定律​​(Ninety-ninety rule):当项目“几近完成”时,低估完成项目所需时间的倾向。
  • ​过度设计​​(Overengineering):花费资源完成比实际需要的还要鲁棒和复杂的工程
  • ​障眼法​​(Smoke and mirrors):展示还没实现的功能,就像它们已经实现了一样
  • ​软件膨胀​​(Software bloat):允许系统的后续版本使用更多的资源

分析方式

  • ​旁观冷漠​​(Bystander apathy):一个需求或者设计是错的,注意到这一点的人却不指出,因为这影响的是其他人。

Software engineering

Software design

 

Object-oriented programming

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
  • ​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 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​​​[5]
  • ​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
  • ​Lava flow​​: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences​[6]​​[7]
  • ​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)
  • ​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​[8]
  • ​Spaghetti code​​: Programs whose structure is barely comprehensible, especially because of misuse of code structures
  • ​Superstitious coding​​: Coding to handle error conditions which are already known to be impossible. The opposite of ​​blind faith​

Methodological

Configuration management

软件工程

软件设计

  • ​抽象倒置​​(Abstraction inversion):不把用户需要的功能直接提供出来,导致他们要用更上层的函数来重复实现
  • ​用意不明​​(Ambiguous viewpoint):给出一个模型(通常是​​OOAD​​,面向对象分析与设计)却没有指出用意何在
  • ​大泥球​​(Big ball of mud):没有清晰结构的系统
  • ​数据库式进程间通信​​(Database-as-IPC):使用数据库进行​​进程间通信​​,而不使用更轻量级的合适的机制。或者说,对于常规的​​进程间通信​​,不是去采用轻量得多的合适机制,而是将数据库用作消息队列。
  • ​镀金​​(Gold plating):在项目达到最高价值后还继续工作。
  • ​内部平台效应​​(Inner-platform effect):系统可自定义的太多,以至于成为一个软件开发平台的蹩脚的复制品。
  • ​输入问题​​(Input kludge):无法确定和实现对异常输入的处理
  • ​接口膨胀​​(Interface bloat):把一个接口做得过于强大以至于极其难以实现
  • ​魔力按键​​(Magic pushbutton):直接在接口的代码里编写实现,而不使用抽象
  • ​竞争风险​​(Race hazard):输出结果受到事件执行顺序和时机的影响,在多线程环境和分布式系统中可能发生
  • ​烟囱系统​​(Stovepipe system):过度聚集数据和功能,忽视了与其他系统和模块的共享

面向对象设计

  • ​贫血的域模型​​(Anemic Domain Model):仅因为每个对象都要有属性和方法,而在使用域模型的时候没有加入非OOP的业务逻辑
  • (BaseBean):继承一个工具类的功能,而不是委托给它
  • ​调用父类​​(Call super):需要子类调用父类被重定义的方法
  • ​圆还是椭圆问题​​(Circle-ellipse problem):基于变量的子类化关系进行子类化
  • ​循环依赖​​(Circular dependency):在对象或软件模块中,直接或间接引入循环依赖。
  • ​常量接口​​(Constant interface):使用接口定义常量
  • ​上帝对象​​(God object):在设计的单一部分(某个类)集中了过多的功能
  • ​对象粪池​​(Object cesspool):复用那些不满足复用条件的对象。对象池是一种管理对象的方法,在重复使用对象前,需要针对对象进行初始化,以避免上次使用后的状态等数据影响下次的使用
  • ​不羁的对象​​(Object orgy):没有成功封装对象,外部可以不受限制地访问它的内部
  • ​幽灵​​(Poltergeists):指这样一些对象,它们唯一的作用就是把信息传给其它对象
  • ​顺序耦合​​(Sequential coupling):指这样一些对象,它们的方法必须要按某种特定顺序调用
  • ​悠悠问题​​(Yo-yo problem):一个结构(例如继承)因为过度碎片化而变得难于理解

编程

  • ​偶然复杂度​​(Accidental complexity):向一个方案中引入不必要的复杂度
  • ​远隔作用​​(Action at distance):意料之外的在系统分离的部分之间交互
  • ​盲目信任​​(Blind faith):缺乏对bugfix的校验或对子函数返回值的正确性检查
  • ​船锚​​(Boat anchor):在系统中保留无用的部分
  • ​忙等待​​(Busy waiting):在等待的时候不断占用​​CPU​​,通常是因为采用了重复检查而不是适当的消息机制
  • ​缓存失败​​(Caching failure):错误被修正后忘记把错误标志复位
  • ​拜物编程​​(Cargo cult programming):由于对模式的盲目崇拜,在不理解的情况下就使用模式和方法,企图得到好的结果
  • ​靠异常编程​​(Coding by exception):当有特例被发现时才添加新代码去解决
  • ​隐藏错误​​(Error hiding):在显示给用户之前捕捉到错误信息,要么什么都不显示,要么显示无意义的信息
  • ​硬编码​​(Hard code):将对系统环境的假设写入实现中
  • ​熔岩流​​(Lava flow):保留不想要的(冗余的或是低质量的)代码,仅因为除去这些代码的代价太高或是会带来不可预期的结果
  • ​循环-switch序列​​(Loop-switch sequence)在循环结构中使用switch语句来编写连续步骤
  • ​魔术数字​​(Magic numbers):在算法里直接使用数字,而不解释含义
  • ​魔幻字符串​​(Magic strings):直接在代码里使用常量字符串,例如用来比较,或是作为事件代码
  • ​自我复制​​(Repeating yourself):通过不断复制已有代码的模式或代码段进行编码;而非采用​​once and only once​​(抽取原则)
  • ​软代码​​(Soft code):在配置文件里保存业务逻辑而不是在代码中
  • ​面条代码​​(Spaghetti code):指那些结构上完全不可理解的系统,尤其是因为误用代码结构
  • ​霰弹枪手术​​(Shotgun surgery):开发人员一次性在一个多个实现的代码基中增加功能

方法论

  • ​拷贝粘贴编程​​(Copy and paste programming):拷贝(然后修改)现有的代码而不是构造通用的解决方案
  • ​黄金大锤​​(Golden hammer):认为自己最喜欢的解决方案是到处通用的(参见:​​银弹​​)
  • ​不可能因素​​(Improbability factor):认为已知的错误不可能发生
  • ​非我所创​​(Not invented here):拒绝使用组织外的主意或方案
  • ​这里发明的​​(invented here):拒绝组织内部实现的创新或解决方案,通常因为对成员没有信心
  • ​不成熟的优化​​(Premature optimization):在编码的早期追求代码的效率,牺牲了好的设计、可维护性、有时甚至是现实世界的效率
  • ​转换编程法​​或​​巧合编程​​(Programming by permutation or programming by accident):试图通过连续修改代码再看是否工作的方式来解决问题
  • ​重新发明方的轮子​​(Reinventing the square wheel):已经有一个很好的方案了,又再搞一个烂方案来替代它
  • ​银弹​​(Silver bullet):认为自己最喜欢的技术方案能解决一个更大的问题
  • ​测试人员驱动开发​​(Tester driven development):需求来自bug报告的软件工程

配置管理

  • ​依赖地狱​​(Dependency hell):所依赖产品的版本所导致的问题
  • ​DLL地狱​​(DLL hell):不同版本DLL所带来的问题,包括DLL可见性和多版本问题,在微软的Windows上尤为突出
  • ​扩展冲突​​(Extension conflict):苹果系统在Mac OS X版本之前的不同扩展的问题
  • ​JAR地狱​​(JAR hell):JAR文件不同版本或路径带来的问题,通常是由于不懂类加载模型导致的