我有一个所有其他子类都可以扩展的基类PlanItem。


一个Objective扩展了PlanItem。
策略扩展了PlanItem。
战术扩展了PlanItem。
任务扩展了PlanItem。


收获:


目标具有策略对象列表。将其称为子项列表。
策略包含策略子列表。
战术有一个子任务列表。


我本可以逐字制作4个完全克隆的类,但这会使编辑变得很痛苦。我选择使用继承,但是随之而来的是循环依赖的问题。

目前我是:

让基本PlanItem类具有一个字段:

private ObservableList<? extends PlanItem> childPlanItems = FXCollections
        .observableArrayList();


我有一个带控制器的FXML,ViewPlanItemController,它在TableView中显示特定项目的统计信息和子列表。

public class ViewChildItemsController<E extends PlanItem> {}


该TableView具有添加,编辑,查看和删除子项的选项。

如果我想查看一个子项,那么我们用控制器递归地加载另一个ViewPlanItem.fxml。问题是,每次我想加载另一个ViewChildItem.fxml时,都需要为其提供子类型,以便它可以查看它们。

如果要查看目标,则可以初始化控制器,以便它知道显示策略类型的项目。

如果需要,这是控制器的init方法:

/**
 * Initializes the values of the items to be displayed.
 *
 * @param list The list of child items to display.
 * @param defCtor Default ctor of each child item.
 * @param copyCtor Copy ctor of each child item.
 */
public void initValues(ObservableList<E> list, Supplier<E> defCtor, UnaryOperator<E> copyCtor) {
    childItemsTableView.setItems(list);
    statisticsPanelController.init(list);
    this.defCtor = defCtor;
    this.copyCtor = copyCtor;
}


我该怎么做?如果我位于ViewPlanItemController类本身之内,我如何知道子项的类类型?从目标->策略->策略->任务来看,需要进行一些类级别的递归。

最佳答案

由于Task实例没有(不应)具有子项,因此将子项列表放入其超类之一是没有意义的。最好将它放在另一个类中,也许:

abstract class ParentPlanItem <E extends PlanItem> extends PlanItem {
    // Moved here from PlanItem:
    private ObservableList<E> childPlanItems = FXCollections.observableArrayList();
    // You might also need these:
    private Supplier<E> childConstructor;
    private unaryOperator<E> childCopyConstructor;
}


那可以是ObjectiveStrategyTactic的超类。它具有足够的信息来正确调用控制器的init方法。在何处获得childConstructorchildCopyConstructor的值是一个单独的问题。我可能会考虑使它们成为相关类的最终静态字段,但是各个类的构造函数仍然需要设置它们。大概。您可能会变得更聪明。

07-24 22:12