`

关注产品和项目开发中的反模式

阅读更多

 

 设计模式是一个被大家熟知的话题,但是熟悉“反模式”的人就很少了,其实,从字面讲,反模式也就是一些经过惨痛教训总结出来的,被公认为不是很好的方法和行为,请在你的开发实践中,尽量避免出现这样的问题,因为很容易导致失败和错误哦!

 

维基百科对“反模式”的定义如下:

 

在实践中明显出现但又低效或是有待优化的设计模式,是用来解决问题的带有共同性的不良方法。

 

反模式分为如下几类(来自维基百科):

 

 

社会和组织结构

组织结构

  • 分析瘫痪(Analysis paralysis):花费太多精力在项目的分析阶段
  • 摇钱树(cash cow):盈利的老产品通常会导致对新产品的自负
  • 委员会设计(Design by committee):很多人同时进行设计,却没有统一的看法
  • 承诺升级(Escalation of commitment):明知错了还不能收回之前的决定
  • 独裁管理(Management by perkele):用完全听不进异议的独裁作风进行管理
  • 目标管理(Management by objectives):通过数字管理,过于关注非本质而或不易取得的数字指标
  • 道德风险(Moral hazard):不让做决定的人知道他的决定会带来什么结果
  • 蘑菇管理(Mushroom management):不通知或是错误地通知雇员信息。雇员像蘑菇一样在黑暗中吸取养分,自生自灭
  • 烟囱或者发射塔(Stovepipe or Silos):结构上支持数据主要在上下方面的流动,却禁止跨部门的通信
  • 供应商套牢(Vendor lock-in):使一个系统过于依赖外部提供的部件

项目管理

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

分析方式

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

软件工程

软件设计

  • 抽象倒置(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):直接在代码里使用常量字符串,例如用来比较,或是作为事件代码
  • 软代码(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可见性和多版本问题,在微软的Windows上尤为突出
  • 扩展冲突(Extension conflict):苹果系统在Mac OS X版本之前的不同扩展的问题
  • JAR地狱(JAR hell):JAR文件不同版本或路径带来的问题,通常是由于不懂类加载模型导致的
分享到:
评论

相关推荐

    UML和模式应用(架构师必备).part06.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part02.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    铁道中文应用开发现状综述2006版

    2.2 其它知名社区中对ROR的介绍和子分坛 2.3 用即时通信工具作的群组 2.4 宣传推广和反面的论调 2.5 定期和不定期活动 3 主要应用和开发的案例 3.1 对开源和共享代码程序应用或汉化 3.2 对web 2.0 提供现有...

    UML和模式应用(架构师必备).part01.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    1.2.4 Android移动Web项目开发的三种解决方案:Native, Web和Hybrid优缺陷分析 4 1.2.5国内外应用现状 6 1.2.6 研究现状总结 7 1.3研究目标与内容 7 1.3.1多窗口浏览器模式的实现机制 7 1.3.2跨域交互即缓存处理方法...

    UML和模式应用(架构师必备).part07.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part03.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part04.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part08.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part05.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    《iOS传感器应用开发最佳实践》源码

    在iOS应用开发中有很多涉及硬件访问和传感器编程。本书我们将向大家介绍苹果iOS设备主要的传感器应用开发。本书是我们智捷iOS课堂团队编写iOS系列丛书中的一本,目的是使一个有iOS开发基础的程序员通过本书的学习,...

    《iOS6开发指南》精彩书摘

    了解iOS中定位服务技术,包括的地理信息编码和反编码查询。之后介绍iOS 6苹果地图的使用,包括了显示地图,以及在地图上添加标注,跟踪用户位置的变化等。最后介绍了程序外地图的使用,如何调用iOS 6苹果地图和调用...

    asp.net知识库

    也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典信息 C#中利用GetOleDbSchemaTable获取数据库内表信息...

    PHP加解密软件

    它所组成的各组件都是开源软件,因此很方便自由地获取,并且性能良好功能强大,导致这些组件的广泛使用,并不断完善发展,与J2EE和.Net商业软件形成三足鼎立之势,受到整个IT界的关注。    既然我们要学好PHP,...

    SSR:Nuxt.js项目

    我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js。Nuxt.js 预设了利用Vue.js开发服务端渲染的应用所需要的各种配置。除此之外,我们还提供了...

    java版坦克大战源码-tankwar:坦克大战,java版联机对战游戏

    项目融合了java基础知识栈、将设计模式应用在实战项目中,netty网络通信,实现了玩家间的交互 项目介绍 坦克大战联机对战游戏是马老师耗时数月精心打造的经典java项目,学习人次量达百万级别,配套完整视频19课时,...

    octopus:八爪鱼客服系统后台

    使用Spring boot单应用开发模式,后台服务模块化。引入Shiro+Redis实现集中式认证中心,增加模块只需要关注业务开发即可。 开发过程前后端分离,前端使用Vue实现,就不再赘述,代码也不提供了。 本后台有提供简单...

    芝麻信用NodeJSSDK.zip

    该项目是芝麻信用平台的 NodeJS SDK 开发包,非官方!接入流程1. 注册芝麻信用商家服务平台并签约2. 在芝麻信用商家服务平台创建商家应用并交换公钥与芝麻信用交换公钥的步骤:进入openssl运行genrsa -out app_...

    基于AT89S52 单片的频率计

    Keil c51 软件提供丰富的库函数和功能强大的集成开发调试工具,全 Windows 界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体 会到keil c51 生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑...

Global site tag (gtag.js) - Google Analytics