java: убедитесь, что существует только один экземпляр типа

#java #oop #composite

#java #ооп #составной

Вопрос:

Я следую примеру из:
https://www.baeldung.com/java-composite-pattern

 public class FinancialDepartment implements Department {

    private Integer id;
    private String name;

    public void printDepartmentName() {
        System.out.println(getClass().getSimpleName());
    }

    // standard constructor, getters, setters
}
public class SalesDepartment implements Department {

    private Integer id;
    private String name;

    public void printDepartmentName() {
        System.out.println(getClass().getSimpleName());
    }

    // standard constructor, getters, setters
}

public class HeadDepartment implements Department {
    private Integer id;
    private String name;

    private List<Department> childDepartments;

    public HeadDepartment(Integer id, String name) {
        this.id = id;
        this.name = name;
        this.childDepartments = new ArrayList<>();
    }

    public void printDepartmentName() {
        childDepartments.forEach(Department::printDepartmentName);
    }

    public void addDepartment(Department department) {
        childDepartments.add(department);
    }

    public void removeDepartment(Department department) {
        childDepartments.remove(department);
    }
}
  

Я хочу запретить себе добавлять два одинаковых типа в HeadDepartment

например, если он вызывает add addDepartment дважды для одного и того же типа, должен быть только один

 public class CompositeDemo {
    public static void main(String args[]) {
        Department salesDepartment = new SalesDepartment(
          1, "Sales department");

        Department salesDepartment2 = new SalesDepartment(
          1, "Sales department");
        Department salesDepartment3 = new SalesDepartment(
          3, "Sales department");


        Department financialDepartment = new FinancialDepartment(
          2, "Financial department");

        HeadDepartment headDepartment = new HeadDepartment(
          3, "Head department");

        headDepartment.addDepartment(salesDepartment);
        headDepartment.addDepartment(financialDepartment);

        // only keep the latest of same instanceof ie replace
        headDepartment.addDepartment(salesDepartment2);
        headDepartment.addDepartment(salesDepartment3);

        // this should only print twice one for salesDepartment3 and financialDepartment
        headDepartment.printDepartmentName();

    }
}
  

я полагаю, мне просто повторить список и, если instanceof, заменить и поместить?

 public void addDepartment(Department department) {
        childDepartments.add(department);
    }
  

я также хотел бы сохранить порядок, если instnaceof Department был первым, я бы хотел, чтобы он сохранял его как 1-й, что означает, что он должен печатать salesDepartment3 перед financialDepartment

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

1. Что произойдет, если addDepartment вызывается один раз с помощью SalesDepartment , а затем снова с помощью Something extends SalesDepartment ? Вы хотите заменить первый на второй или хотите сохранить их оба?

2. Использовать Set ? (например LinkedHashSet ).

3. @khachik говорит, что на данный момент это недопустимый случай, когда ничто не расширит Department за пределы его реализации. но если было бы проще, то что-то, расширяющее отдел продаж, по-прежнему является отделом продаж, поэтому замените его

4. если это не так, то вы можете поддерживать карту Class -> instance и добавлять отделы по их классу. Если вы хотите поддерживать иерархию, тогда вам нужно получить верхний родительский класс, который находится ниже Department в иерархии, и использовать его в качестве ключа.

5. @ElliottFrisch но набор не сможет различать один и тот же instanceof, но с разными параметрами конструктора. он сохранит весь salesDepartment2 из-за другого идентификатора

Ответ №1:

Вашему addDepartment() необходимо выполнить итерацию по списку дочерних элементов и сравнить класс каждого из них с классом добавляемого вами объекта. Псевдокод:

 Class addClass = itemToAdd.getClass();
for each child
{
    if (child.getClass() == addClass)
    {
        //class is already in the list so replace it.
    }