【问题标题】:What is the difference between the read-only interface pattern and the facade pattern?只读接口模式和外观模式有什么区别?
【发布时间】:2015-05-21 07:05:48
【问题描述】:

假设我为一个类编写了一个外观,并公开了它的所有方法,除了它的设置器。与只读接口模式的功能有什么区别?

基于wikipedia article on immutable interfaces,我会说外观具有不可变接口的优点(当我将我的类命名为 Foo 并且我的外观是 ImmutableFoo 时),同时没有能够将不可变接口强制转换为的缺点它们具体的、可变的类型,并且它们的状态发生了变异”。

编辑

事实证明,Wikipedia 上的不可变接口文章并没有讨论在slide 49 and 50 in this presentation 中描述的只读接口模式。答案是外观和只读接口确实可以通过使用包装类来实现,但是它们有不同的用途(有关更详细的观察,请参阅接受的答案和 cmets)。

【问题讨论】:

  • 这些似乎有不同的用途。

标签: design-patterns interface immutability readonly facade


【解决方案1】:

外观模式的主要目的不是让你的接口不可变。

来自Wikipedia

外观是一个对象,它提供简化的界面到更大的 代码体,例如类库。门面可以:

  • 使软件库更易于使用、理解和测试,因为外观为常见任务提供了方便的方法;
  • 出于同样的原因,使库更具可读性;
  • 减少外部代码对库内部工作的依赖,因为大多数代码使用外观,因此允许更多 开发系统的灵活性;
  • 用一个设计良好的 API(根据任务需要)包装设计不佳的 API 集合。

外观可以是可变的。它们用于提供简化的界面。

在您将类称为“外观”之前,您应该问自己,它是否提供了简化的界面并使库更易于使用?

它们可能有一些重叠,但主要目的不同。

外观是关于 API 的简化

假设您正在为电子商务系统开发订单处理功能。您的核心库提供了三种方法:ChangeOrderStatus()SendOrderToFulfillment()SendOrderUpdateEmailToCustomer()

如果没有外观,您必须在需要批准订单的任何地方调用所有这三个方法。太无聊了,很容易出错。如果您将ApproveOrder() 方法添加为Facade(仅调用这三个方法),则只需在需要批准订单的地方调用ApproveOrder()。这简化了 api,并使库更易于使用。

如果您的应用程序明确分为多个层。您的基础设施层上可能有一个非常薄的Facade Layer。您的所有 UI 代码都将与外观层而不是基础设施层进行交互。在我的示例中,ApproveOrder() 位于外观层,而ChangeOrderStatus()SendOrderToFulfillment()SendOrderUpdateEmailToCustomer 位于基础设施层。

只读接口是关于数据保护的

有些对象应该是不可变的。例如,immutable 对象在多线程中通常是首选,因为它们不公开更改其状态的方法,因此它们可以安全地在线程之间共享。

模式与目标

从您提到的slide(第50页)来看,“只读接口”模式是实现“不可变”的特定模式。但这并不是实现“不可变”的唯一方法。

如果您遵循特定的“只读接口”模式,我们可以说您实现了该模式。但是如果你用其他方法来实现“不可变”,我们不能说你实现了“只读接口”模式,但你确实实现了“不可变”的目标。

是否实现“只读接口”模式是否重要?当然不是,您关心的是“不可变”,而不是特定的“只读接口”模式。 (有时候,api有setter,但是你调用它们会抛出异常。这是另一种实现“不可变”的方式。你只需要选择最合适的方案来实现相同的目标。)

【讨论】:

  • 不可变接口不就是原类的简化接口吗?原版有 getter 和 setter,接口只有 getter,因此是原版的简化版本。你能说创建另一个类的实现 限制访问原始类,就像通常为实现外观模式的意图所做的那样,在这种情况下会实现只读接口模式的意图?有什么功能的区别吗?
  • 总结:设计模式是解决特定问题的描述,它们没有说明编程语言或实现(通常同一解决方案可能有多个实现,并且不同语言的实现可能不同)。这两个显然服务于不同的目的。但是,它们都可以通过使用包装类来实现吗(因此相同的实现,不同的目的)? See slide 50 for clarity.(我认为答案是肯定的)
  • 您能否将此添加到您的答案中,以便更准确地回答实际问题。那我就欣然接受了。
  • 我删除了我之前的评论,因为我认为它不正确。请在答案中查看我的新“模式与目标”部分。 :)
  • 在这种情况下,我实际上确实关心只读接口模式。我需要我的类在某些选择类(模块的“内部”类)中是可变的,并且对其他类是不可变的(由 API 公开的类)。我应用了该模式,发现与外观模式有一些相似之处,因为我使用包装类实现了只读接口模式(使用 Javascript,没有接口)。
猜你喜欢
  • 2012-06-26
  • 2016-09-29
  • 2017-03-31
  • 1970-01-01
  • 2012-03-19
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
相关资源
最近更新 更多