gpt4 book ai didi

java - 如何设计删除时的多对多关系?

转载 作者:行者123 更新时间:2023-11-30 11:34:30 27 4
gpt4 key购买 nike

我正在创建一个包含 2 个对象的 canvas 绘图:Rectangles 和连接矩形的 Lines。每条线都应该知道它连接的 2 个 Rectangle。每个 Rectangle 都可以有多条线连接到其他 Rectangle

class Rectangle {
List<Line> connections;
void setConnection(Line line) {
connections.add(line);
}
}

class Line {
Rectangle from, to;

public Line(Rectangle from, Rectangle to) {
this.from = from;
this.to = to;

from.setConnection(this);
to.setConnection(this);
}
}

我觉得这可能不是一个好的设计,因为当我删除 Line 时,我还必须从 的连接列表中删除 Line >Rectangle 它连接。

当我删除一个 Rectangle 时,我还必须删除连接到该矩形的 Line,因为它们不应该存在。因此,我必须遍历可删除的 Rectangle 的所有 connections,并为每个 connection 获取 from/ rectangle,然后再次获取 connection 列表并删除 Line 引用。

我的问题不是写那个代码(我已经让它工作了),但在我看来我正在做很多来回引用。

这可以做得更好吗?不知何故:如果删除了一个矩形,那么所有来自线条的深度连接都会自动删除/失效?类似于 Hibernate 的多对多级联?我不能只使用 Hibernate,因为这应该是一个没有数据库的客户端应用程序。

最佳答案

本质上,您是在构建图表。您将需要将边与顶点分开。

让我们从创建一些分离一些关注点的接口(interface)开始:

interface Shape {
}

interface ShapeConnection {
Shape[] getConnectedShapes();
}

然后让我们引入一个注释,将标记需要级联删除其连接形状的形状。

@interface CascadeDeleteConnectedShapes {
}

Rectangle 和 Line 可以定义为:

@CascadeDeleteConnectedShapes
class Rectangle implements Shape {

}

class Line implements Shape, ShapeConnection {
Rectangle from, to;

public Line(Rectangle from, Rectangle to) {
this.from = from;
this.to = to;
}

@Override
public Shape[] getConnectedShapes() {
return new Shape[] { from, to };
}
}

最后,您需要一个可以将所有内容放在一起的地方。

class Canvas {
private ConnectionManager connectionManager = new ConnectionManager();

private Set<Shape> shapes = new HashSet<Shape>();

public Canvas() {
}

public void removeShape(Shape shape) {
if (!shapes.remove(shape))
return;

if (shape.getClass().isAnnotationPresent(CascadeDeleteConnectedShapes.class)) {
cascadeDeleteShape(shape);
}

if (shape instanceof ShapeConnection) {
connectionManager.remove((ShapeConnection) shape);
}
}

private void cascadeDeleteShape(Shape shape) {
List<ShapeConnection> connections = connectionManager.getConnections(shape);
for (ShapeConnection connection : connections) {
if (connection instanceof Shape) {
this.removeShape((Shape) connection);
} else {
connectionManager.remove(connection);
}
}
}

public void addShape(Shape shape) {
if (shapes.contains(shape))
return;

if (shape instanceof ShapeConnection) {
addShapeConnection((ShapeConnection) shape);
}

shapes.add(shape);
}

private void addShapeConnection(ShapeConnection shapeConnection) {
for (Shape shape : shapeConnection.getConnectedShapes()) {
if (!shapes.contains(shape))
throw new Error("cannot connect unknown shapes");
}
connectionManager.add(shapeConnection);
}
}

一个形状可以同时是一个形状连接。一旦将几个矩形添加到 Canvas 中,就可以添加线条来连接它们。由于您设计中的一条线被识别为 ShapeConnection,任何涉及该线的操作都将调用 Canvas 以让 ConnectionManager 处理图形。在此设计中,重要的是 Line 是不可变的。

级联是由删除带注释的形状触发的。您需要仔细管理这些级联:如果沿途某处发生异常,您将得到一个不完整的图表。

此代码仅供您引用。另外,我将连接管理器的实现留给您去想象。其中一条评论中提到了 Guava 。 BiMultiMap本来可以恰到好处地满足您的目的,可惜他们还没有发布它。无论如何,我肯定会考虑让现有库处理 ConnectionManager 的细节;已经编写了许多适合您需要的内容。

注意没有circular dependencies在这个设计中。

关于java - 如何设计删除时的多对多关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15620599/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com