要避免的设计模式[英] Design patterns to avoid

本文是小编为大家收集整理的关于要避免的设计模式的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

似乎很多人都同意,单身模式有许多缺点,有些甚至建议完全避免这种模式.这里有一个在这里出色的讨论.请指导有关Singleton模式的任何评论.

我的问题:是否还有其他设计模式,应该避免或谨慎使用?

推荐答案

模式是复杂的

所有设计模式都应谨慎使用.我认为您应该对模式进行重构而不是立即实施模式.使用模式的一般问题是它们增加了复杂性.过度使用模式会使给定的应用程序或系统繁琐以进一步开发和维护.

大多数时候,有一个简单的解决方案,您无需应用任何特定模式.一个好的经验法则是每当倾向于更换代码或需要经常更改的代码时使用图案,并准备在使用模式时采用复杂代码的警告.

请记住,您的目标应该是简单的支持您代码中的更改的实际需求.

模式的原则

如果可能导致过度设计和复杂的解决方案,那么使用模式似乎是一个模样.但是,对于程序员来说,阅读设计技巧和原理为大多数模式奠定了基础要有趣得多.实际上,我的关于"设计模式"的最喜欢的书籍,通过重申哪些原则适用于哪些原则,这使这一点强调了这一点所讨论的模式.就相关性而言,它们足够简单,可以比模式有用.其中一些原则足够笼统地比面向对象的编程(OOP)更重要,例如> liskov替换原则,只要您可以构建代码的模块.

有多种设计原理,但是 GOF书的第一章是一开始很有用.

  • 对"接口"的程序,而不是"实现".(四个1995:18)
  • 偏爱'对象组成'而不是'class sharthitance'.(四个1995:20)

让那些沉入您一会儿.应当指出的是,当Gof写成 interface 意思是任何是抽象的(这也意味着超级类),不要将接口与Java或C#中的类型混淆.第二个原则来自观察到的继承的过度使用,即可悲的今天仍然很普遍.

从那里您可以阅读坚实的原则由Robert Cecil Martin (又名鲍勃叔叔).斯科特·汉塞尔曼(Scott Hanselman)在 podcast上采访了鲍勃叔叔.

这些原则是与您的同龄人进行阅读并讨论的好开始.您可能会发现,原则相互编织以及其他过程,例如关注点的分离和和和 a href =" http://en.wikipedia.org/wiki/deppentency_indoction" rel =" noreferrer">依赖项注入.在做 tdd 一段时间以来,您也可能会发现这些原则在实践中自然而然地在您实践中是自然而然的需要在一定程度上跟随它们,以创建隔离和可重复单元测试.

其他推荐答案

设计模式本身最担心的作者是"访客"模式.

这是一种"必要的邪恶" - 但经常过度使用,并且需要它在您的设计中揭示出更根本的缺陷.

"访问者"模式的替代名称是"多dispatch",因为当您希望使用单型dispatch oo语言选择基于该代码的代码时,访问者模式是您最终得到的.两个(或更多)不同对象的类型.

经典的示例是您在两个形状之间具有相交,但是有一个更简单的情况通常被忽略了:比较两个异质物体的平等.

无论如何,您常常会得到这样的事情:

interface IShape
{
    double intersectWith(Triangle t);
    double intersectWith(Rectangle r);
    double intersectWith(Circle c);
}

问题在于,您将所有" Ishape"的实现结合在一起.您暗示,每当您希望为层次结构添加新形状时,您也需要更改所有其他"形状"实现.

有时,这是正确的最小设计 - 但请考虑一下.您的Design 是否真的需要在两种类型上派遣?您是否愿意编写多方法的每个组合爆炸?

通常,通过引入另一个概念,您可以减少实际要编写的组合数量:

interface IShape
{
    Area getArea();
}

class Area
{
    public double intersectWith(Area otherArea);
    ...
}

当然,这取决于 - 有时您确实需要编写代码来处理所有这些不同的情况 - 但是值得停下来并在进行比赛和使用访客之前进行思考.以后可能会节省很多痛苦.

其他推荐答案

singletons-使用Singleton X的类具有很难看到的依赖性,很难隔离以进行测试.

它们经常使用,因为它们方便且易于理解,但是它们确实可以使测试变得复杂.

参见 singletons是病态的骗子./p>

本文地址:https://www.itbaoku.cn/post/627571.html

问题描述

A lot of people seem to agree, that the Singleton pattern has a number of drawbacks and some even suggest avoiding the pattern entirely. There's an excellent discussion here. Please direct any comments about the Singleton pattern to that question.

My question: Are there other design patterns, that should be avoided or used with great care?

推荐答案

Patterns are complex

All design patterns should be used with care. In my opinion you should refactor towards patterns when there is a valid reason to do so instead of implementing a pattern right away. The general problem with using patterns is that they add complexity. Overuse of patterns makes a given application or system cumbersome to further develop and maintain.

Most of the time, there is a simple solution, and you won't need to apply any specific pattern. A good rule of thumb is to use a pattern whenever pieces of code tend to be replaced or need to be changed often and be prepared to take on the caveat of complex code when using a pattern.

Remember that your goal should be simplicity and employ a pattern if you see a practical need to support change in your code.

Principles over patterns

It may seem like a moot to use patterns if they can evidently lead to over-engineered and complex solutions. However it is instead much more interesting for a programmer to read up on design techniques and principles that lay the foundation for most of the patterns. In fact one of my favorite books on 'design patterns' stresses this by reiterating on what principles are applicable on the pattern in question. They are simple enough to be useful than patterns in terms of relevance. Some of the principles are general enough to encompass more than object oriented programming (OOP), such as Liskov Substitution Principle, as long as you can build modules of your code.

There are a multitude of design principles but those described in the first chapter of GoF book are quite useful to start with.

  • Program to an 'interface', not an 'implementation'. (Gang of Four 1995:18)
  • Favor 'object composition' over 'class inheritance'. (Gang of Four 1995:20)

Let those sink in on you for a while. It should be noted that when GoF was written an interface means anything that is an abstraction (which also means super classes), not to be confused with the interface as a type in Java or C#. The second principle comes from the observed overuse of inheritance which is sadly still common today.

From there you can read up on SOLID principles which was made known by Robert Cecil Martin (aka. Uncle Bob). Scott Hanselman interviewed Uncle Bob in a podcast about these principles:

  • Single Responsibility Principle
  • Open Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

These principles are a good start to read up on and discuss with your peers. You may find that the principles interweave with each other and with other processes such as separation of concerns and dependency injection. After doing TDD for a while you also may find that these principles come naturally in practice as you need to follow them to some degree in order to create isolated and repeatable unit tests.

其他推荐答案

The one that the authors of Design Patterns themselves most worried about was the "Visitor" pattern.

It's a "necessary evil" - but is often over used and the need for it often reveals a more fundamental flaw in your design.

An alternative name for the "Visitor" pattern is "Multi-dispatch", because the Visitor pattern is what you end up with when you wish to use a single-type dispatch OO language to select the code to use based on the type of two (or more) different objects.

The classic example being that you have the intersection between two shapes, but there's an even simpler case that's often overlooked: comparing the equality of two heterogeneous objects.

Anyway, often you end up with something like this:

interface IShape
{
    double intersectWith(Triangle t);
    double intersectWith(Rectangle r);
    double intersectWith(Circle c);
}

The problem with this is that you have coupled together all of your implementations of "IShape". You've implied that whenever you wish to add a new shape to the hierarchy you will need to change all the other "Shape" implementations too.

Sometimes, this is the correct minimal design - but think it through. Does your design really mandate that you need to dispatch on two types? Are you willing to write each of the combinatorial explosion of multi-methods?

Often, by introducing another concept you can reduce the number of combinations that you're actually going to have to write:

interface IShape
{
    Area getArea();
}

class Area
{
    public double intersectWith(Area otherArea);
    ...
}

Of course, it depends - sometimes you really do need to write code to handle all of those different cases - but it's worth taking pause and having a think before taking the plunge and using Visitor. It might save you a lot of pain later on.

其他推荐答案

Singletons - a class using singleton X has a dependency on it that's hard to see and hard to isolate for testing.

They're used very often because they're convenient and easy to understand, but they can really complicate testing.

See Singletons are Pathological Liars.