是不好的设计标志返回打破封装的lambda

时间:2016-06-13 20:27:54

标签: java design-patterns lambda encapsulation

我有一个Game类需要一些由Generator类生成的资源。每个游戏都有自己的生成器,因为生成器是实例化的重对象,Game会保留带有实例的对象池。在每个Generator中我都有类似的方法:

private MapBoardGenerator(Game game) {
    super(game);
}

public static MapBoardGenerator getInstance(Game game) {
    MapBoardGenerator instance = game.getGenerator(MapBoardGenerator.class);
    if (instance == null) {
        instance = new MapBoardGenerator(game);
        game.addGenerator(MapBoardGenerator.class, instance);
    }
    return instance;
}

这个静态方法在扩展Generator的每个类中几乎相同。

我想要做的是提供Supplier<MapBoardGenerator>game,以便控件将在其他位置进行,getInstance方法将只是:

public static MapBoardGenerator getInstance(Game game) {
    return game.getInstance(MapBoardGenerator.class, MapBoardGenerator::new);
}

如果我通过调用私有构造函数的供应商,有什么不对吗?这是一个大学项目和设计很重要。

2 个答案:

答案 0 :(得分:2)

我的2美分:也许你应该看看洋葱建筑。在洋葱架构中,您的业务(游戏?)由基础架构组件(生成器?)引用。这可能意味着从Generator实例到游戏实例的lambda表达式注入(或委托),以保持层和责任分离。

我不明白为什么你应该通过反思来实例化一个新实例(对我来说这是一个黑客,但是,因为我来自C#,这个评论可能不合适)...

答案 1 :(得分:1)

将私有构造函数作为Supplier的实例传递不会破坏封装,因为构造函数作为Supplier的实例传递。实例的接收者(在这种情况下为Game)不知道Supplier是如何实现的,只是它满足Supplier接口。这就是接口编程的全部内容:即使调用者提供了具体的实现,接收者也只知道实现完成的接口。如果Game知道它所获得的具体实现,则会违反封装。

请注意,将Supplier传递给Game可能会在您的应用程序的较大上下文中有意义,但至少它不会违反MapBoardGenerator的封装。< / p>