转换Java对象的最佳实践/模式

时间:2016-11-02 22:29:21

标签: java

假设我有一个应用程序负责接收供应商消息并转换为规范消息。例如:

def powers(base):
''' (list of str) -> bool
Return True if the given list of ints is a list of powers of 
some int x of the form [x^0, x^1, x^2, x^3, ...] and False 
otherwise.
>>> powers([1, 2, 4, 8]) 
True
>>> powers([1, 5, 25, 75])
False
'''

MessageA映射到MessageX,MessageB映射到MessageY。

我的方法是每个消息类型都有一个变换器类来处理这种转换。在这个例子中,我将有以下变换器:

public class MessageA extends VendorMessage { ... }
public class MessageB extends VendorMessage { ... }

public class MessageX extends CanonicalMessage { ... }
public class MessageY extends CanonicalMessage { ... }

我的问题实际上与我最终调用变形金刚的方式有关。

由于我的进程将一些VendorMessage作为输入,我需要查询该类型,以便知道将哪个特定的转换器指向它。例如,一种方法可能如下所示:

public class MessageXTransfomer()
{
    public MessageX transform(MessageA message) {...}
}

public class MessageYTransfomer()
{
    public MessageY transform(MessageB message) {...}
}

我不知道为什么,但我这种方法感觉很奇怪 - 好像我做错了什么。我应该使用这种问题的最佳做法是什么?

注意:我在不使用任何转换框架等的情况下寻找最佳方法。理想情况下,只使用基本Java就可以实现该模式。

2 个答案:

答案 0 :(得分:4)

我喜欢@javaguy的答案,但它并不完整。当然,如果你可以像后面的例子中那样使用特定的变换器,那将是很好的,但如果你不能坚持使用TransformerFacade和一种StrategyPattern:

public class TransformerFacade {

    private Map<Class, VendorMessageToCanonicalMessageTransformer> transformers = new HashMap<>();
    { 
        // this is like strategies, the key may be class, class name, enum value, whatever
        transformers.put(MessageA.class, new MessageXTransformer());
        transformers.put(MessageB.class, new MessageYTransformer());
    }

    public CanonicalMessage transform(VendorMessage message) {
        return transformers.get(message.getClass()).transform(message);
    }
}

答案 1 :(得分:1)

我只是让每个具体的VendorMessage通过实现一个接口返回其对应的CanonicalMessage

public interface Mapper<T> {

    T map();
}

然后,MessageA应实现此接口:

public MessageA implements Mapper<MessageX> {

    @Override
    public MessageX map() {
        MessageX message = ...;
        // fill message
        return message;
    }
}

如果您不想在VendorMessage课程中进行映射,那么Vadim Kirilchuk在his answer中建议的策略可以解决问题。