Кодирование меня в угол

У нас есть ряд классов, которые происходят из единого набора интерфейсов, таким образом что

IFoo-> BasicFoo, ReverseFoo, ForwardFoo
IBar -> UpBar, DownBar, SidewaysBar
IYelp -> Yip, Yap, Yup

где конструктор для Нечто похож Foo(IBar, IYelp) Эти объекты используются в течение проекта.

Там существует другой класс, который имеет метод, подпись которого public double CalcSomething(IFoo, IAnotherClass) это применяется в какой-то момент к каждому Foo. Нам спустились с запроса выше того конкретный объектный состав, скажем, a BasicFoo(UpBar,Yip), используйте другой алгоритм кроме того, найденного в CalcSomething.

Мой первый инстинкт должен был сказать, давайте изменим интерфейс IFoo, таким образом, мы можем спустить логику к уровню класса Foo, изменить конструктора, чтобы быть Foo(IBar, IYelp, IStrategy) и затем имейте объекты Foo, инкапсулируют эту логику. К сожалению, нам также сказали, что дизайн архитектуры предусматривает что там не быть никакими зависимостями между IFoo, это - реализации и IAnotherClass. Они непреклонны по отношению к этому.

Хорошо, уверенный, тогда я думал, что мог бы использовать шаблон "посетитель", но... как? Смысл создания состава был то, так, чтобы никакой другой класс не видел детали реализации. Отражение для взгляда в объектах, полностью повреждая инкапсуляцию? О, ад нет.

Таким образом, я приехал сюда, потому что я в замешательстве. У кого-либо есть какие-либо предложения, как мы могли рассматривать особый случай одного из составов, не изменяя состав или повреждая инкапсуляцию? Должно быть простое решение, которое я пропускаю.

Править:

Удаленное незаконное начало. Измененный "обработанный особенно" в более описательное значение.

10
задан wheaties 14 January 2010 в 18:47
поделиться

3 ответа

A Расчетные продукты , которые выбирают соответствующий алгоритм, основанный на типе IFOO , вы предоставляете, решат проблему (за счет условного):

interface ICalcSomethingStrategy {
    public double CalcSomething(IFoo, IAnotherClass);
}

CalcSomethingStrategyFactory {
    ICalcSomethingStrategy CreateCalcSomethingStrategy(IFoo foo) {
        // I'm not sure whether this is the idiomatic java way to check types D:
        if (foo.Bar instanceof UpBar && foo instanceof Yip) {
            return new UnusualCalcSomethingStrategy();
        } else {
            return new StandardCalcSomethingStrategy();
        }
    }
}
3
ответ дан 4 December 2019 в 02:50
поделиться

В духе поцелуя я бы добавил метод Isspecial () к IFOO, и использовать это, чтобы решить, какой алгоритм использовать в калькуле ().

Это предполагает, что это единственный особый случай.

3
ответ дан 4 December 2019 в 02:50
поделиться

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

Создают интерфейс IQualifyForSpecialTreatment маркера, который расширяет IFoo. Расширить BasicFoo до SpecialBasicFoo и иметь его, реализуют IQualifyForSpecialTreatment.


    interface IQualifyForSpecialTreatment extends IFoo {
    }
    class SpecialBasicFoo extends BasicFoo implements IQualifyForSpecialTreatment {
        ...
    }

можно затем добавить другой аромат calcSomething:


    calcSomething (IQualifyForSpecialTreatment foo, IAnotherClass whatever) {
        ... perform "special" variant of calculation
    }
    calcSomething (IFoo foo, IAnotherClass whatever) {
        ... perform "normal" variant of calculation
    }
1
ответ дан 4 December 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: