5

Ho creato un set di classi per rappresentare un grafico ciclico diretto per rappresentare i processi BPM, basato sulla classe , che fornisce solo metodi di manipolazione del grafico di base per aggiungere e trovare vertici e spigoli.Interfaccia fluente per costruire un grafico ciclico orientato?

La sfida che sono rivestimento è creare un builder che fornisce un fluent interface grado di creare un grafico che include ramificazione complessa, cicli, e più nodi di estremità (vedi esempi sotto).

rami paralleli

Parallel Branches

Unione Branches

Merging Branches

Cicli

Cycle

Complex

Complex

My implementazione corrente (vedi esempio sotto) è ricorrere alla aliasing vertice in cui si verifica una forcella (per esempio, il vertice "B" in Parallel Branches), e poi fare riferimento all'alias quando si aggiunge un nuovo ramo a quel vertice. Il mio builder include anche qualcosa di simile per consentire la fusione di rami e cicli. Gli alias sono stati introdotti perché i nomi dei vertici non sono univoci nei grafici BPM. Voglio un'interfaccia fluida più elegante per creare rapidamente grafici, liberi da questi riferimenti.

Graph graph = GraphBuilder.newGraph() 
          .addVertex("A") 
          .edgeName("") 
          .addVertex("B", "b-fork") 
          .edgeName("") 
          .addVertex("C") 
          .edgeName("") 
          .addVertex("E") 
          .addBranch("b-fork") 
          .edgeName("")  
          .addVertex("D") 
          .edgeName("") 
          .addVertex("F") 
          .build(); 
+1

Avete considerato l'aggiunta di un parser DOT al vostro programma?'GraphBuilder.parse (" A -> B; B -> C; B -> D; ")' sembra più leggibile. –

+0

@Duncan Si prega di leggere l'intero post. Non sto chiedendo l'intero costruttore, voglio solo non avere un alias, perché non sono eleganti. – izilotti

+3

Come si desidera creare un grafico ciclico, ma la catena del metodo ha una struttura ad albero, alcune forme di aliasing sembrano inevitabili. –

risposta

5

Il problema è che il builder è una catena di metodi, mentre si vuole costruire un grafico con cicli. Avrete bisogno di fare marcia indietro, e per farlo è necessario fare riferimento ai nodi precedenti sia esplicitamente (usando il loro etichetta) o implicitamente pone, ad esempio:

Graph graph = GraphBuilder.newGraph() 
         .addVertex("A") 
         .edgeName("") 
         .addVertex("B", "b-fork") 
         .edgeName("") 
         .addVertex("C") 
         .edgeName("") 
         .addVertex("E") 

         .goBack(2) // even worse than using label: breaks easily 
         .edgeName("")  
         .addVertex("D") 
         .edgeName("") 
         .addVertex("F") 
         .build(); 

si potrebbe usare una struttura ad albero per costruire il grafico:

SubGraph.node("id", "label") 
     .to("edgeName1", SubGraph.node("A").to("", SubGraph.node("C"))), 
     .to("edgeName2", SubGraph.node("B")); 

ma questo solo ritarda il problema, poiché sarà nuovamente necessario fare riferimento ai nodi in modo esplicito quando i cicli entrano in gioco. A parte una qualche GUI o estesi disegni ASCII, non c'è modo di definire un grafico senza alias.

Personalmente mi sento di raccomandare un parser in stile DOT:

parse("a -> b -> c -> f -> e; f -> d -> b"); // "Cyclic graph" 

che è sia facile da leggere e da digitare.

EDIT: per il lulz: Grafico ciclica senza aliasing:

// do not ever do this: 
    GraphBuilder.parseASCII(
      "  -->C--  \n" +   
      " |  v  \n" + 
      "A-->B  F-->E \n" + 
      " | ^ \n" + 
      "  -->D--  \n"); 
+0

Bel punto sul backtracking, ma sì si romperebbe facilmente. Se dovessi usare DOT, preferirei usare file di testo. Per rappresentare grafici più grandi, quella stringa diventerebbe molto lunga e goffo. – izilotti

0

Si potrebbe ridurre leggermente la parsing da:

Graph graph = GraphBuilder.newGraph() 
      .add("a,b,c,f,e") 
      .add("f,d,b"); 
+1

La notazione è più semplice di DOT, ma non acquisisce la fusione di rami in un vertice. – izilotti

+1

a meno che manchi qualcosa che fa, riutilizzando lo stesso nome (f eb sopra). – soru

+0

Capisco. Il secondo ramo sta completando il ciclo b-> c-> f-> d-> b ... La direzione non è chiara perché viene inferita sulle connessioni. – izilotti