什么是反模式?


193

我正在研究模式和反模式。我对模式有一个清晰的主意,但我没有反模式。网络和维基百科的定义让我非常困惑。

有人可以简单地向我解释什么是反模式吗?什么目的?他们在做什么?是好事还是坏事?




它被认为是不好的,但可能是唯一的解决方案。三思而后行。
КонстантинВан

Answers:


244

反模式是软件开发中的某些模式,被认为是不良的编程习惯。

与已被形式化并通常被认为是良好的开发实践的通常用于解决常见问题的通用方法- 设计模式相反,反模式是相反的并且是不希望的。

例如,在面向对象的编程中,其想法是将软件分成称为对象的小块。面向对象编程中的反模式是God对象,它执行许多功能,最好将其分离为不同的对象。

例如:

class GodObject {
    function PerformInitialization() {}
    function ReadFromFile() {}
    function WriteToFile() {}
    function DisplayToScreen() {}
    function PerformCalculation() {}
    function ValidateInput() {}
    // and so on... //
}

上面的示例有一个对象,它可以执行所有操作。在面向对象的编程中,最好对不同的对象承担明确定义的职责,以使代码减少耦合并最终更易于维护:

class FileInputOutput {
    function ReadFromFile() {}
    function WriteToFile() {}
}

class UserInputOutput {
    function DisplayToScreen() {}
    function ValidateInput() {}
}

class Logic {
    function PerformInitialization() {}
    function PerformCalculation() {}
}

最重要的是,有很多方法可以开发具有常用模式(设计模式)的软件,但是也有一些开发和实现软件的方法会导致问题。被认为是不良软件开发实践的模式是反模式。


9
在GodObject旁边还有其他反模式的例子吗?
Tomasz Mularczyk '16

@Tomasz Programming Pasta服务就是这样一个例子。最好将其概括为许多小对象之间的封装不完善。认为这是上帝的对象相反en.wikipedia.org/wiki/Spaghetti_code
AWrightIV

@Tomasz不好的事情,但是有些人做的,都是反模式。例如,try: <do something>; except: pass可能是Python中的Cardinal Sin反模式。看到这个:realpython.com/blog/python/…–
eric

1
是否可以将Singleton视为反模式,因为它使得更难于并行模拟和运行测试(因为所有测试都使用和改变同一个Singleton,从而导致不一致)?
lostsoul29年

63

每当我听说反模式时,我都会回忆起另一个术语。设计气味。

“设计气味是设计中的某些结构,表明违反了基本设计原则并会对设计质量产生负面影响。”(摘自“软件设计的重构气味:管理技术债务”)

基于违反设计原则的设计气味有很多:

抽象气味

缺少抽象:当使用大量数据或编码字符串而不是创建类或接口时,会出现这种气味。

命令式抽象:将操作转换为类时,会产生这种气味。

不完整的抽象:当抽象不完全支持互补或相互关联的方法时,就会出现这种气味。

多方面抽象:当抽象承担了多个职责时,就会出现这种气味。

不必要的抽象:当在软件设计中引入实际上不需要(因此可以避免)的抽象时,就会出现这种气味。

未利用的抽象:当抽象未使用(未直接使用或不可访问)时,会产生这种气味。

重复的抽象:当两个或多个抽象具有相同的名称或相同的实现或两者都出现时,会出现这种气味。

封装气味

封装不足:当声明的一个或多个抽象成员的可访问性比实际所需的许可性更大时,就会出现这种气味。

泄漏封装:当抽象通过其公共接口“公开”或“泄漏”实现细节时,会产生这种气味。

缺少封装:当实现变体未封装在抽象或层次结构中时,会出现这种气味。

未利用的封装:当客户端代码使用显式类型检查(使用链接的if-else或switch语句来检查对象的类型)而不是利用已经封装在层次结构中的类型的变化时,会出现这种气味。

模块化气味

破碎的模块化:当理想情况下应将数据和/或方法本地化为单个抽象并分散在多个抽象中时,就会出现这种气味。

模块化不足:当存在尚未完全分解的抽象时,就会出现这种气味,进一步分解可能会减小其大小和/或实现的复杂性。

循环依赖的模块化:当两个或多个抽象直接或间接依赖于彼此(在抽象之间产生紧密耦合)时,会出现这种气味。

集线器式模块化:当抽象具有大量其他抽象的依赖项(传入和传出)时,就会出现这种气味。

层次结构的气味

缺少层次结构:当代码段使用条件逻辑(通常与“标记类型”结合使用)来显式管理行为的变化时,会出现这种气味,在这种情况下,可以创建层次结构并封装这些变化。

不必要的层次结构:当不需要整个继承层次结构时,就会出现这种气味,这表明继承已被不必要地应用于特定的设计上下文。

未分解的层次结构:当层次结构中的类型之间不必要的重复时,就会出现这种气味。

广泛的层次结构:当继承层次结构“太”宽时,就会出现这种气味,表明可能缺少中间类型。

推测性层次结构:推测性提供层次结构中的一种或多种类型(即,基于想象的需求而不是实际需求)时,会产生这种气味。

深度层次结构:当继承层次结构“过分”深时,就会产生这种气味。

反叛层次结构:当子类型拒绝其父类型提供的方法时,会产生这种气味。

层次结构破裂:当父类型及其子类型在概念上不共享“ IS-A”关系而导致可替代性破坏时,会出现此气味。

多路径层次结构:当子类型直接或间接继承于父类型并导致层次结构中不必要的继承路径时,就会产生这种气味。

循环层次结构:当层次结构中的超类型依赖于其任何子类型时,就会产生这种气味。


以上定义和分类在“软件设计气味的重构:管理技术债务 ”中进行了描述。一些更相关的资源可以在这里找到。


41

模式是关于如何解决某类问题的想法。反模式是关于如何不解决它的想法,因为实现该想法会导致不良的设计。

例如:“模式”将使用代码复用功能,“反模式”将使用复制粘贴功能。两者都解决了相同的问题,但是使用函数通常会导致比粘贴复制更具可读性和可维护性的代码。


18

反模式是一种不解决问题的方法。但这还不止于此:这也是尝试解决问题时经常看到的一种方法。


13

如果您真的想学习AntiPatterns,请阅读《AntiPatterns》一书(ISBN-13:978-0471197133)。

在其中,他们定义了“ AntiPattern是一种文学形式,它描述了对产生确定的负面结果的问题的常见解决方案”。

因此,如果这是一种不好的编程习惯,但又不是一种常见的编程习惯(仅限于一个应用程序,一个公司或一个程序员),则它不符合AntiPattern定义的“模式”部分。



6

有趣的是,解决问题的既定方式既可以是模式,也可以是反模式。辛格尔顿就是最好的例子。它将出现在两组文献中。


6

一个反模式是一个的补充设计模式。反模式是在某些情况下不应该使用的模板解决方案。


6

就像设计模式一样反模式也是一种模板,并且是解决某个问题的可重复方式,但是这种方式并非最优且无效。


4

如今,软件工程研究人员和从业人员经常互换使用术语“反模式”和“气味”。但是,它们在概念上并不相同。维基百科上有关反模式的条目指出,反模式至少在两个方面与不良做法或坏主意有所不同。反模式是

“尽管最初看起来似乎是对问题的适当而有效的响应,但通常使用的过程,结构或动作模​​式通常带来的不良后果要大于有益结果。”

它清楚地表明选择了一种反模式是因为认为它是对所提出问题的一种很好的解决方案(作为一种模式);但是,它带来的负债多于收益。另一方面,气味只是一种不良做法,会对软件系统的质量产生负面影响。例如,Singleton是一种反模式,God类(或模块化不足)是一种设计气味。


2

反模式是人们倾向于以错误的方式编程的方法,或者至少不是那么好的方法。


0

任何对给定的软件开发环境弊大于利的设计模式都将被视为反模式。

一些反模式很明显,而有些则不然。例如,辛格尔顿(Singleton),尽管许多人认为它是好的旧设计模式,但有些人则不然。

您可以检查问题单身人士有什么不好?以便更好地了解它的不同意见。


实际上,反模式通常并不明显。显然,不良的设计模式只是不良的设计模式。真正的反模式在表面上看起来很稳定,但稍后会出现问题。实际上,并不是很糟糕的区别是首先使它们成为反模式的区别。
hawkeyegold

0

像在算法中一样,您可以使用蛮力实现解决方案,但是如果情况变得复杂,则必须付出很多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.