Как сделать элегантный дизайн в этой ситуации? - PullRequest
1 голос
/ 29 ноября 2011

У меня есть такой метод:

   public void foo(String str){

    do.something();
    do.anotherthing();
    do.somethingelse();

    if(str.compareTo("choiceA")==0){
    do.somethingforA();
    }
    else if(str.compareTo("choiceB")==0){
    doanother.somethingforB();
    doelse();
    }
    else if(str.compareTo("choiceC")==0){
    dosomeother.somethingforC();
    doblahblah();
    writeblabla();
    }

}

Я хочу спроектировать код как определение различных классов или методов для A, B и C.

, но есть много строк (первые три строки метода), что A, B и C. совместно используют.

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

что вы посоветуете?

Спасибо за любую идею.

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

То, что вы ищете, это polymorphism.

Существует два "правильных" объектно-ориентированных способа сделать то, что вы хотите.Мои личные предпочтения касаются второго, я скажу вам почему.

  • Наследование : Имейте суперкласс (возможно, абстрактный), в котором ваш метод выполняет всеобщие вещи (do.something();, do.anotherthing(); и do.somethingelse();. Затем этот метод должен вызвать другой метод abstract. Затем вы определяете три подкласса этого класса, каждый для одного из различных вариантов выбора («выбор А», «выбор»B "и" выбор C "). Каждый из ваших подклассов реализует метод по-своему и делает то, что вам нужно.

  • Композиция : Вместо этогоиметь подклассы, иметь интерфейс, внедренный в объект, который содержит метод foo. Затем эти интерфейсы имеют три различные реализации, одну для «выбора A», одну для «выбора B» и одну для «выбора C».

Лично я предпочитаю композицию, а не наследование , потому что она обычно создает код, который более читабелен, менее сложен, менее глючен и намного более тестируемесли вы используете interface, как было предложено, тогда вы можете поиздеваться над ним в своих юнит-тестах основного класса).Это также обеспечивает разделение интересов.

1 голос
/ 29 ноября 2011

Если вы копируете код вставки, вы делаете это неправильно;)

Как насчет создания базового абстрактного класса, который имеет метод foo и абстрактный метод doTheSomething.Затем вы расширяете его с помощью A, B и C и реализуете только абстрактный метод doSomething.

В этом случае вашему коду просто нужно выяснить строковый переключатель (это был бы действительно простой переключатель в Java7, кстати),получить правильный класс и запустить foo, который, в свою очередь, запустит перегруженный абстрактный метод doSomething.

Извините, что это такая общая идея, но вы не даете много подробностей о том, ваши действия для AB иC похожи или принадлежат к одному и тому же объекту и т. Д. Так что возьмите это за возможность и проверьте, подходит ли он вашему случаю удаленно!;)

...