2009-08-06 43 views
15

我有几个不同的类来自外部来源(不可修改),代表相同的概念。例如Address。我有com.namespace1.Address(与场houseNumstreetcity),com.namespace2.Address(与场hsc),namespace3.com.CoolAddress(与场house_numstreetcity)。对象转换模式

问题是我使用的某些Web服务需要某些地址对象类型,所以我需要创建一个com.namespace1.Address给定namespace3.com.CoolAddress。这些字段很容易映射,但我正在寻找如何做到这一点的模式。

从我的角度来看,实例对象AddressConverter没有意义,因为没有状态(只有行为),并且当类只有行为时,它归结为实用程序类中的静态方法。从长远来看,无论何时我需要将新对象映射到另一个对象,我都有一个地方可以添加/修改/删除方法。它的做法可能会改变,但我知道代码的位置(在一次),并可以在需要时更改映射。

想法?

回答

8

我想你要找的是工厂类。工厂模式用于需要能够实例化几个相关类中的一个时,由工厂而不是开发人员确定。

http://en.wikipedia.org/wiki/Factory_method_pattern

你说得对,以尽量保持所有这些业务逻辑在一个地方而不是做ClassOne.toClassTwo(),ClassOne.toClassThree()的,...

最灵活我可以想到实现这一点(但不是最简单的方法)的方式是让工厂从一个简单的类开始,只有基本的常用方法,并将处理程序添加到散列表或其他容器中。这样你就不需要具体实现每个可能的功能组合。

当然,对于每个可能的地址类型,具体实现会更快,但是会有相当数量的重复代码,并且添加新的地址类类型会有点困难。

+1

+1处理程序表建议 - 我使用该模式相当多。 但使用'Map'而不是'Hashtable'。 :) – 2009-08-06 07:48:22

+1

工厂是一个创建模式。问题在于管理现有对象而不是创建新对象。 – SomeWittyUsername 2012-10-25 14:17:35

+0

@icepack我认为OP在将一个对象映射到另一个时想要创建新的实例。我认为,用“来自外部来源(不可修改)的几个不同对象”的句子来表示这些对象的类别是不可修改的。我将其基于以下句子:“我需要**创建** com.namespace1.Address给定namespace3.com.CoolAddress。”。我将编辑这个句子。 – 2012-10-27 21:37:54

1

由于您无法自行修改类,因此我建议您为每个方向实施Adapter模式。正如你所说的,适配器方法本身可以是静态的,但是你可以在一个类中对两个方向进行分组,以便逻辑全部集中在一个地方。

在一天结束时,无论您怎样称呼它,或者在何处放置代码,您都将执行相同的任务。我建议两个方向都存在于同一个文件中,因为当任一方向改变时,它们通常都需要更新。

0

如果你总是转换到相同的类,我会保持简单并将所有转换代码放在该类中,而不用担心工厂等,尤其是如果你只处理几个不同的类。为什么这些东西总是必须有复杂的模式?!

public class A { 

    ... 

    public static A convertB(B b) { 

    ... 

    } 
} 
+0

问题是原始对象是不可修改的。 – 2009-08-06 03:58:52

+0

@BrianYarger我认为他的意思是类定义是可以修改的。我根据以下句子:“我需要**创建** com.namespace1.Address给定namespace3.com.CoolAddress”。 – 2012-10-27 21:42:51

+0

通过将转换逻辑放在类中,代码现在紧密耦合。设计模式的一点是避免可以彼此独立存在的类的耦合。我建议不要在这个答案中给出建议。 – Chaos 2014-04-08 00:56:28

0

您需要输出的类是final?如果不是,您可以将它们分类以创建适当的Adapters。否则,我会用dj_segfault的一个带有一个处理程序表的Factory的建议。

或者,等一下 - 它只是一个您需要与之通话的Web服务?如果是这样,那么你的数据类型实现不应该是包装输入数据类型的适配器,或者你自己的一些中间对象。