Требуется уточнение - Шаблоны проектирования - PullRequest
3 голосов
/ 09 ноября 2010

В большинстве концепций шаблонов проектирования упоминалось, что «имеет А» лучше, чем «есть А».

В первой главе - Head First Design Patterns - «Введение в дизайн-шаблоны», раздел «Интеграция поведения утки» (стр. № 15), класс Duck ссылается на интерфейс FlyBehavior и QuackBehavior типы. Например, мы собираемся добавить новое поведение в функцию с именем «XYZBehavior» (просто предположим, что клиент еще не решил это) для одного типа «Уток», нам нужно изменить класс «Утка», чтобы иметь ссылку на новый интерфейс. В результате мы должны изменить класс, но это не должно происходить в соответствии с хорошим шаблоном проектирования.

Можете ли вы предложить мне, как мы можем справиться с этим требованием?

Ответы [ 3 ]

1 голос
/ 09 ноября 2010

Эту проблему можно решить с помощью Внедрение зависимостей

(В Java обычно через Spring или Guice )

Вот Руководство для начинающих по внедрению зависимостей

По сути, Bird будет иметь свойство поведения:

private Collection<Behavior> behaviors;
public void setBehaviors(Collection<Behavior> behaviors){
    this.behaviors = behaviors;
}

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

0 голосов
/ 04 июля 2016

Вы можете справиться с этим сценарием, используя Composition => Duck со списком Behaviours.

Duck будет поддерживать список объектов поведения.Заполните соответствующие поведения при создании объекта Duck.

Пример кода:

import java.util.*;

interface Behaviour{

}
class FlyBehaviour implements Behaviour{

}
class QuackBehaviour implements Behaviour{

}
class XYZBehaviour implements Behaviour{

}

public class Duck{
    private List<Behaviour> duckBehaviours = new ArrayList<Behaviour>();

    public Duck(List<Behaviour> list){
        duckBehaviours = list;
    }
    public static void main(String[] args){
        // set the behaviours
        List<Behaviour> list = new ArrayList<Behaviour>();
        list.add(new FlyBehaviour());
        list.add(new QuackBehaviour());
        list.add(new XYZBehaviour());
        Duck duck = new Duck(list);
    }   
}
0 голосов
/ 09 ноября 2010

Шаблон Стратегии не препятствует изменению класса, если вы добавляете новое поведение (стратегия). Это просто предотвращает прикосновение к классу, если существующее поведение (стратегия) изменяется.

Пример с QuackBehaviour: предположим, мы думали, что утка будет звучать как "кряк", но после нескольких лет исследований мы поняли, что утки на самом деле звучат как "кваак". Нам повезло, мы реализовали QuackBehaviour и просто настроили реализацию интерфейса QuackBehaviour для обычных уток. Вот такая уловка с этим шаблоном.

Если позже мы решим добавить SwimBehaviour, потому что другая исследовательская группа поняла, что плавание - это обычное поведение утки, тогда мы должны прикоснуться к обычной утке и добавить это поведение (в класс Duck). 1010 *

Надеюсь, это помогло!

...