Eclipse中的IProject.setDescription使用了什么设计模式

时间:2013-01-15 12:57:59

标签: api design-patterns

我正在设计一个具有特定模式的API,但不知道这个模式是否有名称。它与GoF(Gang of Four)中的Command模式类似,但并不完全相同。

我可以找到的一个简单示例是在Eclipse中操作项目(IProject),而不是通过调用项目上的方法来改变其状态,而是通过这个3步骤过程:

  1. 使用IProjectDescription
  2. 将其状态提取到描述符对象(getDescription
  3. 在描述符上设置属性。例如。 setName
  4. 使用setDescription
  5. 描述符应用于原始项目

    一般原则似乎是你有一个复杂的对象作为具有许多可能相互依赖的属性的框架的一部分,而不是直接在该对象上工作,一次一个属性,你将属性提取到一个简单的数据对象,操纵它,并将其应用回来。

    它具有Command模式的一些属性,因为数据对象封装了所有的更改,就像Command一样 - 但它不是真正的Command,因为你不执行它在对象上,它只是对象状态的表示。

    它还具有Transactional API的一些属性,其中,通过set...调用一次性更改所有内容,如果任何一个属性发生更改,则允许整个修改有效地“回滚”失败。虽然这是该方法的一个优点,但它并不是它的主要目的。而且,通过简单地向API添加事务方法(如commitrollback

    ,您可以在没有这种方法的情况下实现事务性质。

    我希望利用这种模式有两个优点 - 虽然我没有看到它们被上面的eclipse示例利用:

    1. 您可以在其实现更改时表示基础对象的有意义状态。这对于从不同类型的表示升级或复制状态非常有用。假设我发布了我的API的新版本,我在其中创建了一个对象Foo2,这是我旧的Foo1的一种全新形式,但它们都具有相同的基本属性。要将Foo1升级为Foo2,我可以将这些属性提取为FooState。 foo2.setFooState(foo1.getFooState)就像那样。解释和表示属性的方式封装在Foos中,可以完全不同。

    2. 我可以使用我的简单数据对象持久化并传输底层对象的状态,其中持久化对象本身会复杂得多。因此,我可以将Foo的状态提取为FooState,并将其保存为简单的XML文档,然后通过“加载”并应用它将其应用于某个新对象。或者我可以将FooState简单地作为JSON对象传输到Web服务,而Foo本身太大而且传输复杂。 (或者服务调用每一端的对象完全不同,如Foo1和Foo2)

    3. 无论如何,我无法在the Gang of Four design patterns,甚至在Martin Fowler的comprehensive "bliki"

      中找到这种模式的名称或示例。

2 个答案:

答案 0 :(得分:3)

Martin Fowler在他的书Data Transfer Object中描述的

Principles of Enterprise Application Architecture(DTO)似乎是出于你在第2点描述的目的。

DTO是对它所代表的更复杂的域模型的一种相当简单的提取。

Fowler描述了DTO与汇编程序结合使用可以用来使DTO独立于它应该代表的实际域对象(或对象)。汇编程序知道如何从域对象创建DTO,反之亦然。他还提到DTO需要可序列化以保持/传输其状态。您在第2点中描述的内容似乎与此描述相符。

你在第1点所描述的内容虽然似乎不是预期的目的,但使用这种模式肯定是可以实现的。

我不确定你是否通过他的书的图案目录或书本身。这本书本身更详细地描述了这一点。

您可能还想查看来自Oracle的Transfer Object定义,Fowler说here就是他所描述的DTO。

答案 1 :(得分:2)

并非每个设计都记录为单一的设计模式,事实上大多数系统设计都是多种模式的组合。

然而,你正在做的事情的一部分,IProjectDescription正在使用Memento,但你的似乎是一个多态变体。考虑模式目录中出现的模式,将其作为基本起点而不是最终结果。模式是非常本质的,应该扩展和组合。

Command pattern可以为您提供Commit和RollBack(Do / Undo),并以这种方式将其与Memento相结合是一种非常常见的方法。使用HttpRequest和Java的Java Servlet API也可以看到同样的事情。的HttpResponse。