首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 內部 DSL 實作:流式 API 設計圖構建範例

     編輯:Java 程式設計入門

什麼是內部 DSL?

使用宿主語言(Java)語法構建領域專用語言,通過方法鏈與靜態導入實現接近自然語言的可讀性。

使用端效果

Graph().edge().from("a").to("b").weight(20.0)
       .edge().from("b").to("c").weight(10.0)
       .printGraph();

核心類別設計

1. 入口 GraphBuilder

public class GraphBuilder {
    private final Graph graph = new Graph();

    private GraphBuilder() {}

    public static GraphBuilder Graph() { return new GraphBuilder(); }

    public EdgeBuilder edge() { return new EdgeBuilder(graph); }

    public void printGraph() { graph.print(); }
}

2. 邊構建器 EdgeBuilder(鏈式核心)

public class EdgeBuilder {
    private final Graph graph;
    private String from, to;
    private Double weight;

    public EdgeBuilder(Graph graph) { this.graph = graph; }

    public EdgeBuilder from(String v) { this.from = v; return this; }
    public EdgeBuilder to(String v)   { this.to = v; return this; }
    public EdgeBuilder weight(double w) { this.weight = w; return this; }

    /** 終結當前邊,加入圖並回傳自身以支援連續 .edge() */
    public EdgeBuilder build() {
        graph.addEdge(from, to, weight);
        return this;
    }
}

3. 圖模型 Graph、Vertex、Edge

public class Graph {
    private final Map vertices = new HashMap<>();
    private final List edges = new ArrayList<>();

    public void addEdge(String from, String to, Double w) {
        Vertex f = vertices.computeIfAbsent(from, Vertex::new);
        Vertex t = vertices.computeIfAbsent(to, Vertex::new);
        edges.add(new Edge(f, t, w));
    }
    public void print() { edges.forEach(System.out::println); }
}

public class Vertex { private final String label; /* getter */ }
public class Edge { private Vertex from, to; private Double weight; /* getter/toString */ }

DSL 設計模式總結

模式應用
Builder / Fluent APIEdgeBuilder 方法鏈構建邊屬性
Method Chaining每個 setter 回傳 this
Static FactoryGraph() 入口方法
Context ObjectGraphBuilder 持有 Graph 上下文

進階擴展

  • 頂點屬性:.vertex("a").label("Node A").color("red")
  • 條件邊:.edge().from("a").to("b").when(condition)
  • 輸出格式:.export(DOT).toFile("g.dot")
  • 型別安全:泛型 GraphBuilder<V, E> 限制頂點/邊類型

真實專案案例

  • JOOQ:SQL 建構 DSL
  • Mockito:when(mock.foo()).thenReturn(bar)
  • AssertJ:assertThat(list).hasSize(3).contains("a")
  • Gradle:Groovy/Kotlin DSL 定義建構腳本
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved