определение того, используется ли составной шаблон правильно или нет

#java #oop #design-patterns #composite

#java #ооп #шаблоны проектирования #составной

Вопрос:

Я пытаюсь использовать составной шаблон проектирования в Java. Однако я не уверен, правильно ли я его использовал / правильно. Является ли приведенный ниже код допустимым / правильным использованием составного шаблона проектирования? У меня есть класс leafGoal, который расширяет класс compositeGoal. Однако они не реализуют интерфейс, который является распространенным шаблоном, который я видел в Интернете с составным шаблоном. Имеет ли это значение? Что у меня нет общего интерфейса для двух классов? Это все еще допустимый составной шаблон?

 public class leafGoal {

    String goalName;
    //private GoalStrategy strategy;
    GoalStrategy strategy;
    private Dungeon dungeon;
    private Inventory inventory;
 
 public class compositeGoal extends leafGoal {

    ArrayList<leafGoal> goals = new ArrayList<leafGoal>();
    
    public compositeGoal(String goalName, GoalStrategy strategy, Dungeon dungeon, Inventory inventory) {
        super(goalName, strategy, dungeon, inventory);
    }

    public void addGoal(leafGoal g) {

        goals.add(g);
    }
 

Комментарии:

1. Составной элемент не является листом, поэтому его не следует расширять; и составной элемент может содержать другие составные элементы, а не только листы.

Ответ №1:

Трудно сказать, поскольку вы на самом деле не предоставляете никакого кода.

Вам не нужен интерфейс для составного. Составной — это просто класс, который объединяет несколько объектов определенного типа, будучи одного и того же типа. Пример: у вас есть предметы в вашем инвентаре, и все они ведут себя как предметы. Некоторые элементы представляют собой пакеты, которые могут содержать другие элементы, будучи самими элементами. В этом случае пакеты являются составными. Они содержат элементы и сами являются элементами.

Комментарии:

1. ну, compositeGoal содержит массив с именем goals, который содержит конечные цели

Ответ №2:

вам понадобится как минимум базовый / абстрактный класс для компонента и интерфейс для составного. Идея состоит в том, чтобы сначала определить общую абстракцию, которая включает в себя все основные операции. Затем вы можете определить другой интерфейс, который определяет поведение составного. Что-то вроде этого:

 public abstract class Node{
    public abstract void DoSomething();
}

public class Leaf : Node{
    public override void DoSomething(){
        // I am a leaf!
    }
}

public interface IComposite{
    void AddNode(Node node);
}

public class InnerNode : Node, IComposite{
    public override void DoSomething(){
        // I am NOT a leaf!
        
        // loop over the child collection and call DoSomething()
    }
    
    public void AddNode(Node node){
        // add to some inner collection
    }
}
 

обратите внимание, что в InnerNode.DoSomething() реализации вы можете использовать обход по предварительному заказу, по порядку или после заказа, это действительно зависит от вашей системы (или может быть настроено).