型安全なHTML/Config DSLの構築
ビルダーパターンと拡張ラムダを使って、シンプルな設定DSLを実装します。
「型安全なHTML/Config DSLの構築」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
目標: 実践的な DSL
Kotlin で、最小限ながら現実的な HTML ビルダー DSL を構築します。同じパターンは、設定、テストフィクスチャー、レポートビルダーにも適用できます。完成するのは、文字列連結に代わる、型安全で IDE に適した API です。
Tag 基底クラスを定義する
すべての HTML 要素には、名前、属性、子要素という共通の構造があります。まず基底クラスから始めます。
open class Tag(val name: String) {
val attrs = mutableMapOf<String, String>()
val children = mutableListOf<Tag>()
fun render(indent: Int = 0): String {
val pad = " ".repeat(indent)
val attrStr = if (attrs.isEmpty()) "" else " " + attrs.entries.joinToString(" ") { "${it.key}=\"${it.value}\"" }
val body = children.joinToString("\n") { it.render(indent + 2) }
return "$pad<$name$attrStr>\n$body\n$pad</$name>"
}
}@DslMarker を適用する
すべてのビルダークラスにマークを付け、内側のスコープから外側のスコープのメソッドを誤って呼び出せないようにします。
@DslMarker
annotation class HtmlDsl
@HtmlDsl class Html : Tag("html")
@HtmlDsl class Head : Tag("head")
@HtmlDsl class Body : Tag("body")
@HtmlDsl class Div : Tag("div")
@HtmlDsl class P : Tag("p")ビルダー関数を追加する
各タグクラスに拡張関数を追加します。この関数は子タグを作成し、ブロックを適用して、そのタグを children に追加します。
fun Html.head(block: Head.() -> Unit) = Head().also { it.block(); children += it }
fun Html.body(block: Body.() -> Unit) = Body().also { it.block(); children += it }
fun Body.div(block: Div.() -> Unit) = Div().also { it.block(); children += it }
fun Div.p(text: String) = P().also { it.attrs["text"] = text; children += it }トップレベルの html ビルダー
ルート要素を作成してユーザーのブロックを適用する、トップレベルのエントリーポイントを用意します。
fun html(block: Html.() -> Unit): Html {
val root = Html()
root.block()
return root
}DSL を使用する
完成した DSL は、すっきりして読みやすいものになります。
val page = html {
head { }
body {
div {
p("Hello, DSL!")
}
}
}
println(page.render())属性を追加する
任意の属性を流れるように設定できる attr ヘルパーを追加します。
fun Tag.attr(key: String, value: String) { attrs[key] = value }
// Usage
div {
attr("class", "container")
p("Content")
}設定 DSL パターン
同じパターンは設定オブジェクトにも使えます。HTML タグの代わりに、ドメインクラスを使用します。
class ServerConfig {
var host = "localhost"
var port = 8080
var db: DbConfig? = null
fun database(block: DbConfig.() -> Unit) { db = DbConfig().apply(block) }
}
fun server(block: ServerConfig.() -> Unit) = ServerConfig().apply(block)入れ子と合成
各ビルダー関数は作成したオブジェクトを返すため、ビルダーを自由に合成できます。DSL の入れ子の深さは、データ階層の深さと一致します。
型によるエラー防止
型システムによって構造が強制されます。Head には body 拡張関数がないため、Head 内で body { } を呼び出すことはできません。無効な構造はコンパイル時エラーになります。
レンダリングとテスト
DSL は通常の Kotlin オブジェクトツリーを生成するため、レンダリングとテストは簡単です。render() を呼び出して出力文字列を検証するか、テストでオブジェクトツリーを走査できます。
後からDSLを拡張する
新しいタグや設定オプションを追加するには、適切なレシーバークラスに新しい拡張関数を追加するだけです。既存の呼び出し側には影響しません。実際にオープン/クローズドの原則を満たしています。
クイックチェック
KotlinのHTML/config DSLを「型安全」にするものは何ですか?
まとめ:型安全なDSLの構築
主な手順:
- 階層の各レベルに対応するビルダークラスを定義する
- レシーバーの漏洩を防ぐために
@DslMarkerでアノテーションを付ける - 子オブジェクトを生成、設定、追加する拡張関数を記述する
- トップレベルのエントリーポイント関数を公開する
- レンダリングとテストは通常のKotlinオブジェクトに対して行う
よくある質問
「型安全なHTML/Config DSLの構築」レッスンは無料ですか?
はい。「型安全なHTML/Config DSLの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「型安全なHTML/Config DSLの構築」で何を学びますか?
ビルダーパターンと拡張ラムダを使って、シンプルな設定DSLを実装します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「型安全なHTML/Config DSLの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- レシーバー付きLambda:DSLの基盤
- @DslMarker:レシーバーの漏洩を防ぐ
- 型安全なHTML/Config DSLの構築
- ユーザーを壊さずにDSLをテスト・進化させる