何时使用哪种模式?

时间:2010-09-21 12:09:30

标签: design-patterns language-agnostic oop

作为一名初级开发人员,我对某些设计模式感到有点困惑。有时,我只是不知道在哪种情况下使用哪种。

例如, on creational 模式,我真的不知道何时使用:

  • 原型
  • 生成器

实际上,我看到了一些差异;但我也看到你可以使用多种解决方案,如:

  • 调用调用克隆原型的相应构建器的工厂。
  • 致电一家克隆相应原型的工厂
  • 使用适当的导演致电建筑师
  • ...

我的意思是,这些创作的结果最终是相同的:你得到了你的对象实例。

我只是想知道你会在不同的环境中使用什么样的设计(我猜它可能取决于性能需求,对象的复杂性,耦合......)

另外,我没有看到 facade mediator 之间存在很大差异,除了mediator调用不同的接口。

责任链相同,并不真正理解为什么我看到所有实现都使用链式列表。这个模式不能用我们连续调用的简单处理程序列表来实现吗?

这就是为什么我希望人们告诉我你将使用GoF模式的具体上下文,以及为什么你不会使用任何其他适合的模式给出问题(但可能不太优雅)。

由于

6 个答案:

答案 0 :(得分:14)

就像我第一次遇到设计模式时的许多人一样,我意识到很多人只是我用来解决设计问题的机制的名称。首先是问题,然后是解决方案。我从不接触过设计模式,就像它们是需要适合某个地方的拼图一样。

您并不是真的需要回答模式名称的问题,就好像它是考试一样。这样做的方法是坐下来思考您的代码需要做什么以及将来如何改变。这就是我们如何使用这些设计模式的方法。人们一直使用相同的技巧来解决某些问题,直到最终有人出现并给出了这些技巧。

你遇到的唯一问题是缺乏经验,而且无法通过SO解决。当你编写软件时,你总会遇到一些错误。你会发现,如果你已经用这种的方式做了事情,他们会更好。顺便说一下这个方式有一个名字; “抽象工厂”,“适配器”,“观察者”,等等。将来你会知道何时以及为何使用它。现在记住KISS原则。不要使不必复杂的事情复杂化。

在了解如何使用它们之前了解设计模式这一事实意味着您比大多数开发人员领先一步。不要过多地冒汗,只要记住,下次遇到问题时,其中一个可能是可接受的答案。渐渐地,你会发现什么时候应该使用设计模式,什么时候不应该使用。

答案 1 :(得分:3)

在这个答案中我最想强调的是,我不同意另一个答案:

  

很难(正如您所注意到的)第一次应用模式并了解可能带来的好处

在应用模式之前,您必须看到模式将带来明显的好处。如果情况并非如此,请不要使用它,在您的代码中添加不能带来明显好处的模式很可能属于反模式场景

  

这就是为什么我希望人们告诉我你在哪个CONCRETE上下文中使用GoF模式,以及为什么你不会使用任何其他可能适合给定问题的模式(但可能在不太优雅的方式)。

首先,不要局限于你在那里阅读的内容。模式的最佳方面是使您能够获得几种不同场景的设计选项。

当然,有些场景可以通过多种方式完成。在一个非常具体的场景中挣扎在两种模式之间进行选择?再次检查它们,看看他们对场景和好处的看法。

如果你发现自己的模式数量不堪重负,那就让大部分模特休息吧。不要一次性将所有模式引入您的技能。选择一些相关的,并学习何时应用它们(再次阅读,搜索/要求在SO /博客帖子中进行比较。

始终注意您应用的模式对变化的响应程度以及围绕它们的代码的复杂程度。问问自己这些特征如何与其他任何替代模式不同的问题。

最后,要了解您最好遵循不断发展的代码方法。尽最大努力保持代码清洁,但不要痴迷于找到一个永远不会改变的解决方案。即使手头有模式,你也会采取一些假设,这会影响你选择的模式。变化可能与这些假设不符,是事实或生命。

阅读these 2 ebooks,可以帮助您集中精力设计/开发/改进代码。

答案 2 :(得分:2)

最初,我发现学习模式的最简单方法是遇到需要帮助的情况(过于复杂而无法一目了然)然后实现它。在你遇到真正需要它的问题之前,很难理解为什么模式是有益的。

Joshua Kerievsky提供了一个很好的资源'Refactoring to Patterns'

答案 3 :(得分:1)

使用你的创造性混淆:

  • 工厂:创建多个派生类的实例

  • 原型:要复制或克隆的完全初始化的实例

  • 构建器:将对象构造与其表示分开

我最近有一个案例,我需要构建一个实现接口的对象。我不知道或想知道用于实现该接口的对象(或对象)。由于我个人想要隐藏对象,我不得不使用Factory

public class TransactionValidatorFactory
{
   public static IValidator CreateValidator(string RuleSet)
}


IValidator v = TransactionValidatorFactor.CreateValidator("Canada");

IValidator v = TransactionValidatorFactor.CreateValidator("UnitedStates");

IValidator v = TransactionValidatorFactor.CreateValidator("UnitedStates-Toyota");

IValidator v = TransactionValidatorFactor.CreateValidator("en-US");

我隐藏了工厂内使用的对象 - 只要我有一个接口就可以了。

我甚至不想实现界面的对象 - 它们是一组复杂的对象,使用它们的人无需进入。有时需要一个对象,有时它是多个。这是我想隐藏在工厂内的细节。


看同样的情况,你似乎专注于使用prototype。这意味着您必须构造对象,设置属性,然后根据需要clone。当你知道你想要使用什么对象时,这对你很好。您还必须在对象上编写.Clone()方法。

想看到对象,我的对象不支持Clone()方法,我不想写一个。这导致我回到Factory模式。

答案 4 :(得分:0)

我个人认为,设计模式本身在现实世界中的使用非常有限 - 我经常看到模式作为一种万能的解决方案出售“你应该使用X模式”,而实际上是现实世界不像教科书那样统一 - 软件开发也不例外。

虽然理解和识别模式很有用,但是在尝试将“设计模式”应用于现实世界的问题时不要过于夸张,而是在解决自己的问题时使用设计模式的知识作为灵感,例如我经常来对于涉及可能与工厂模式类似的方面的解决方案,我还没有写出名称中带有“Factory”一词的类。

如果它真的像在整个地方使用设计模式一样简单,那么我们都会失业! : - )

答案 5 :(得分:0)

Factory:创建对象而不将实例化逻辑暴露给客户端。

Prototype:使用原型实例指定要创建的对象类型,并通过复制此原型来创建新对象。

创建实例(使用新运算符)时使用此模式非常昂贵。通常clone()用于从现有对象创建对象。

Builder:将复杂对象的构造与其表示分开

当您必须创建具有少量必需属性和许多可选属性的对象时,请使用此模式。提供构造函数来创建具有所有必需属性和可选属性的对象是复杂的。 Builder通过逐步的方法促进这个构建过程。

Builder专注于逐步构建复杂对象。 Abstract Factory强调一系列产品对象(简单或复杂)。 Builder将产品作为最后一步返回,但就抽象工厂而言,产品会立即返回。

Facade为复杂系统提供了简化的界面。它使用一个精心设计的API包装了一系列API。

Mediator模式定义了一个对象(Mediator),它封装了一组对象的交互方式。它实现了多对多通信。

相关帖子:

Design Patterns: Factory vs Factory method vs Abstract Factory

Keeping builder in separate class (fluent interface)

What is Facade Design Pattern?

Mediator Vs Observer Object-Oriented Design Patterns