基本的に、グラフを作成しています。頂点からエッジを分離する必要があります。
いくつかの懸念を分離するいくつかのインターフェースを作成することから始めましょう:
interface Shape {
}
interface ShapeConnection {
Shape[] getConnectedShapes();
}
次に、接続された形状をカスケード削除する必要がある形状をマークする注釈を導入しましょう。
@interface CascadeDeleteConnectedShapes {
}
長方形と線は次のように定義できます。
@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);
}
}
形状は、同時に形状接続にすることができます。キャンバスにいくつかの長方形を追加したら、それらを接続するための線を追加できます。デザイン内の線は、線を含むすべての操作として認識されるため、をShapeConnection
呼び出してグラフを処理します。この設計では、不変であることが重要です。Canvas
ConnectionManager
Line
カスケードは、注釈付きの形状の削除によってトリガーされます。これらのカスケードを注意深く管理する必要があります。途中で例外が発生した場合、不完全なグラフが残ります。
このコードはあなたにアイデアを与えるためだけに役立ちます。また、接続マネージャーの実装はあなたの想像に任せています。グアバはコメントの1つで言及されています。BiMultiMapはあなたの目的を正しく果たしていただろうが、彼らがまだそれをリリースしていないのは残念だ。いずれにせよ、私は確かに、の詳細をConnectionManager
既存のライブラリで処理できるようにすることを検討します。多くはあなたのニーズに合うように書かれています。
この設計には循環依存関係がないことに注意してください。