Дизайн для конвертации объектов - PullRequest
2 голосов
/ 20 июня 2009

Я пытаюсь придумать хороший дизайн для преобразования набора различных объектов в общий объект. По сути, я получаю один (из множества слегка отличающихся) сложный объект из системы A и должен преобразовать его в более простой объект для системы B.

Все объекты, которые я конвертирую, наследуют от одного и того же базового класса, поэтому часть конвертации всегда одна и та же. Но в каждом случае преобразование включает в себя что-то очень специфичное для типа объекта, который я конвертирую. Это может быть RPC, выборка HTTP, поиск в базе данных или что-то совершенно другое.

Я смотрю на Шаблонный метод и Стратегия . Но ни один из них не выглядит идеально подходящим. Проблема в том, что используемый метод / стратегия привязан к типу преобразуемого объекта и поэтому не является взаимозаменяемым.

Это набросок того, о чем я думаю:

class FooConverter {
    Map<String, FooConverter> converters;
    Foo convert(Bar bar) {
        Foo foo = ...;  // Common part of the conversion.
        FooConverter c = converters.get(bar.getType(), foo);
        c.finishConversion(bar, foo);
        return foo;
    }
}

Меня раздражает, что FooConverter должен определять дополнительный метод преобразования, который принимает частично преобразованный объект в качестве параметра. Таким образом, я получаю сочетание стратегии (поскольку все преобразователи реализуют один и тот же интерфейс) и метода Template (поскольку общая часть преобразования используется всеми преобразователями). Есть ли лучший способ?

Ответы [ 4 ]

2 голосов
/ 20 июня 2009

Вы берете кучу «конвертируемых» объектов, возможно, вы могли бы сделать так, чтобы у «Foo» были декораторы для каждого базового типа «конвертируемых», при обнаружении типа «конвертируемых» вы можете добавить соответствующий декоратор к «Foo». «

2 голосов
/ 21 июня 2009

Похоже, вам нужно пройти через структуру и иметь возможность что-то делать с каждым элементом в структуре. Это «что-то» зависит от типа элемента, и вы также хотите иметь возможность изменять как реализовано это «что-то».

Если это так, то это звучит как идеальный вариант для шаблона Visitor . Я только недавно использовал его в сценарии, очень похожем на ваш, когда мне нужно было гибко преобразовать одну структуру в другую.

1 голос
/ 22 июня 2009

Есть как минимум два способа сделать это:

  1. Используйте метод шаблона. То есть есть метод преобразования в суперкласс (Bar) и реализовать его в подклассах (например, MyBar, HttpBar и т. Д.) Это хорошо, если класс знает, как преобразовать себя. Вы можете иметь метод toFoo () в Bar. Подклассы будут вызывать super.toFoo () и дополнительно делать необходимые вещи.
  2. Приведенный выше метод может быть не всегда желательным, поскольку концептуально преобразование не является работой Бар. В этом случае вы можете использовать шаблон посетителя. Вы можете иметь параллельную иерархию классов преобразования. Каждый класс может принять некоторый конкретный тип бара и выполнить преобразование.
0 голосов
/ 20 июня 2009

Вы можете реализовать подкласс целевого типа с конструктором для каждого из заданных типов, из которых вы преобразуете. Из конструкторов вызывайте перегруженный конструктор его родительского типа.

Что-то вроде:

public class ConvertedFoo extends Foo
{
    public ConvertedFoo(SuperTypeA a) {
        // Do some common stuff here.
    }

    public ConvertedFoo(SubtypeOfSuperTypeA a) {
        ConvertedFoo((SuperTypeA)a);
        // Do more specific stuff here.
    }
}

Если класс ConvertedFoo становится слишком большим, его можно легко разделить на подтипы.

Это позволило бы максимально повторно использовать код и централизовало бы весь код преобразования без использования динамической проверки типов.

Я не думаю, что это именованный шаблон. Если кто-нибудь знает, я хотел бы знать его имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...