Шаблон декоратора - как украсить два типа одновременно - PullRequest
2 голосов
/ 08 февраля 2012

Я работаю на Java

Я создал красивую структуру декораторов для краев графа.У меня есть базовый край с двумя вершинами, затем у меня есть взвешенный декоратор, который добавляет вес к краю, и затем у меня есть ориентированный декоратор, который добавляет ориентацию к краю.Декораторы реализованы с использованием интерфейсов и методов делегирования (не по наследству).

Теперь я хотел бы добавить еще один декоратор - декоратор потока, соответствующий краю потока.Края потока имеют как направление, так и вес (производительность), а также поток.Как мне реализовать что-то подобное в Java?Мне нужно что-то вроде

public class FlowEdge implements IEdge, IWeightedEdge, IOrientedEdge, IFlowEdge
{
    private IEdge, IWeightedEdge, IOrientedEdge decorated;
    private int flow;

    //constructors, delegate methods...

, но это, очевидно, невозможно.

Возможно, декоратор - не лучший шаблон для использования.Я хотел бы добиться разделения интересов (чтобы я мог иметь любую комбинацию нормальных, взвешенных, ориентированных ребер), но мне также нужна функциональность, возможно, нескольких декораторов в одном классе.Это как-то возможно?Или я переусердствовал в этом?

Ответы [ 4 ]

1 голос
/ 08 февраля 2012

Я отпустил всю эту идею декоратора и реализовал ребра, как обычное наследие.

Edge -> WeightedEdge -> OrientedEdge -> FlowEdge

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

1 голос
/ 08 февраля 2012

Ваш дизайн звучит некорректно.Декораторы обычно "оборачивают" класс, который они хотят декорировать, который передается в их конструктор.Ваш код должен сделать что-то подобное:

Graph myGraph = new BaseGraph();
Graph decoratedGraph = new FlowedGraph(new WeightedGraph(new OrientedGraph(myGraph)));
1 голос
/ 08 февраля 2012

Декораторы реализованы с использованием интерфейсов и методов делегирования (не по наследству).

Я думаю, что это может быть причиной того, что вы врезаетесь в стену. Шаблон Decorator прекрасно работает в Java, используя наследование и полиморфизм. Это хороший пример «программирования» в «язык против программирования» в «язык».

0 голосов
/ 08 февраля 2012

Кажется ошибкой объявлять тип украшения, которое реализует декоратор. Декоратору также кажется неправильным точно знать, что он украшает. Вы можете реализовать «составной декоратор», который опирается на другие классы декораторов, чтобы добавить определенное поведение в дополнение к новому поведению, которое само обеспечивает. Возможно, что-то вроде этого:

public class FlowEdge implements IEdge // or IFlowEdge
{
    private IEdge decorated;
    private int flow;

    public FlowEdge(IEdge decorated) {
        this.decorated = new WeightedEdge(new OrientedEdge(decorated));
        . . .
    }
}
...