実践プログラミングDSL ドメイン特化言語の設計/実装のノウハウ(佐藤 竜一 佐藤 竜一 佐藤 竜一 デバシィシュ・ゴーシュ)|翔泳社の本
  1. ホーム >
  2. 書籍 >
  3. 実践プログラミングDSL ドメイン特化言語の設計/実装のノウハウ

実践プログラミングDSL ドメイン特化言語の設計/実装のノウハウ

監修
翻訳
原著

形式:
書籍
発売日:
ISBN:
9784798125398
定価:
4,180(本体3,800円+税10%)
仕様:
B5変・400ページ
カテゴリ:
プログラミング・開発
キーワード:
#プログラミング,#開発環境,#開発手法,#Web・アプリ開発

DSLを設計/実装するために必要な知識のすべてがここにある

DSL(Domain-Specific Language:ドメイン特化言語)とは、特定の領域の問題に特化したコンピュータ言語です。ビジネス上の概念を表現するにせよ、コンピュータ内部の処理を表現するにせよ、汎用のプログラミング言語では表現力に限界があり、その表現はたちまち煩雑なものとなりがちです。しかし、その問題に特化した言語、すなわちDSL を利用すれば、その問題を明確に表現、あるいはエレガントに解決することができます。DSLを使って高度なレベルで問題を表現することで、その問題に関わる専門家とのコミュニケーションを円滑にすることも可能です。

本書は、読者が自分自身でDSLを設計/実装し、それを効果的に利用するために必要となるすべての知識を提供します。そのようなDSLは独立した処理系として利用することも、既存のプログラミング言語に組み込んで利用することもできます。また本書を読むことで、Ruby、Scala、Groovy、Clojureといったモダンな言語を使ったメタプログラミングの技法を習得し、プログラマとしてさらなる高みに立つことができるでしょう。

第1部 DSL入門

第1章 ドメインの言葉を話す方法を学ぶ

1.1 問題ドメインと解決ドメイン
 1.1.1 問題ドメイン
 1.1.2 解決ドメイン
1.2 ドメインモデリング:共通語彙の準備
 1.2.1 共通語彙の利点
  グルー(接着剤)としての共通語彙
  テストケースにおける共通のテクノロジー
  開発期間中の共通語彙
1.3 DSL入門
 1.3.1 DSLとは何か?
  一般的に使われる言語とDSLはどう違うのか?
  ビジネスユーザーにとってのDSLとは?
 1.3.2 一般的なDSL
 1.3.3 DSLの構造
1.4 DSLの実行モデル
1.5 DSLの分類
 1.5.1 内部DSL
 1.5.2 外部DSL
 1.5.3 テキストベース以外のDSL
1.6 いつDSLを利用するか
 1.6.1 DSLの長所
  DSLは表現力豊かである
  DSLは簡潔である
  DSLは高い抽象化レベルで設計されている
  DSLはより高いリターンをもたらす
  DSLベースの開発はスケーラブルである
 1.6.1 DSLの短所
  言語の設計は難しい
  DSLは上流工程でのコストとなる
  DSLの利用はパフォーマンスに影響を与える
  DSLではツールによるサポートが期待できない場合がある
  「また新しい言語を覚えなくちゃ」症候群
  DSLによって言語間の不協和音が発生しうる
1.7 DSLと抽象の設計
1.8 まとめ
1.9 参考文献

第2章 最初の一歩

2.1 Javaで最初のDSLを実装する
 2.1.1 共通語彙の準備
 2.1.2 Javaによる最初の実装
  Orderクラスを実装する
  Orderビルダーの利用
  JavaによるDSLの分析
2.2 DSLをよりわかりやすくする
 2.2.1 XMLを使ってドメインを外部化する
 2.2.2 Groovy:より表現力豊かな実装言語
  Groovyによるソリューション
  methodMissingを使ったメソッドの組み込み
  動的メソッド注入におけるGroovyのメタプログラミング技法
  高階関数とクロージャに対する正規のサポート
 2.2.3 Groovy DSLの実行
2.3 DSLの実装パターン
 2.3.1 内部DSLパターン:共通特性と多様性
  スマートAPI
  構文木操作
  型埋め込み
  リフレクティブメタプログラミング
  実行時メタプログラミング
  コンパイル時メタプログラミング
 2.3.2 外部DSLパターン:共通特性と多様性
  コンテキスト駆動の文字列操作
  XMLから利用可能なリソースへの変換
  DSLワークベンチ
  外部の埋め込みコードとDSLの混合
  パーサーコンビネータベースのDSL設計
2.4 DSLの実装方法を選択する
  既存のインフラストラクチャの再利用
  既存の知識の活用
  外部DSLの学習曲線
  必要十分な表現力
  合成可能性
2.5 まとめ
2.6 参考文献

第3章 DSLを使ったアプリケーション開発

3.1 DSLの組み込み方法
 3.1.1 DSLの統合に注意すべき理由
3.2 内部DSLを組み込むためのパターン
 3.2.1 Java 6のスクリプトエンジンの利用
  Groovy DSLの準備
  DSL実装とスクリプトの統合
  Java 6のスクリプティングに関する問題
 3.2.2 DSLラッパーの利用
  準備作業
  DSLの構築
  Scalaの暗黙の型変換を使う
  ユーザーが得るメリット
 3.2.3 言語特有の統合機能
  JavaコードとGroovy DSLの間のやり取り
  Groovyクラスローダーを使ったより優れた統合方法
  最終結果
 3.2.4 Springベースの統合
  Springの動的言語サポート
  実装の構成
3.3 外部DSL向けの統合パターン
3.4 エラーと例外のハンドリング
 3.4.1 例外の命名
 3.4.2 入力エラーのハンドリング
  型システムが使えない場合
  パーサーの役割
 3.4.3 例外的なビジネス状況の処理
3.5 パフォーマンスの管理
3.6 まとめ
3.7 参考文献

第2部 DSLの実装

第4章 内部DSLの実装パターン

4.1 DSLの道具箱を準備する
4.2 埋め込みDSL:メタプログラミングのパターン
 4.2.1 暗黙的コンテキストとスマートAPI
  DSLの表現力を判定する
  暗黙的コンテキストの定義
  スマートAPIを使って表現力を向上させる
 4.2.2 動的なデコレーターによるリフレクティブメタプログラミング
  Javaによるデコレーター
  Javaでの実装を改善する
  Rubyによる動的なデコレーター
 4.2.3 ビルダーを使ったリフレクティブメタプログラミング
  Groovyビルダーの魔法
  Groovyビルダーの内部
 4.2.4 教訓:メタプログラミングのパターン
4.3 埋め込みDSL:型付けされた抽象を使うパターン
 4.3.1 汎用的な抽象としての高階関数
  グループ化された報告書の生成
  基礎となる抽象の準備
  最初の試行:特化した実装
  汎用的な実装
 4.3.2 明示的に型付けした制約によるドメインロジックのモデル化
  Rubyにおける実行時検証
  Scalaにおける明示的に型付けされた制約
 4.3.3 教訓:型を使って考える
4.4 生成型DSL:実行時に定型コードを生成する
 4.4.1 生成型DSLの動作原理
 4.4.2 簡潔なDSLの設計に使えるRubyのメタプログラミング
  クラスメソッドを使って妥当性検査を抽象化する
  動的なメソッド生成を行うミクシン
  最後のグルー(接着剤)
4.5 生成型DSL:マクロによるコンパイル時のコード生成
 4.5.1 Clojureによるメタプログラミング
 4.5.2 ドメインモデルの実装
 4.5.3 Clojureマクロの美しさ
4.6 まとめ
4.7 参考文献

第5章 Ruby、Groovy、Clojureによる内部DSLの設計

5.1 動的な型付けによってDSLを簡潔にする
 5.1.1 読みやすさ
 5.1.2 ダックタイピング
  ダックタイピングによるポリモーフィズムの実現
  取引ドメインの例
 5.1.3 メタプログラミングについてもう一度
 5.1.4 なぜRuby、Groovy、Clojureなのか
5.2 Rubyによる取引処理DSL
 5.2.1 APIから始める
  基礎となる抽象
  DSLファサード
 5.2.2 ちょっとしたモンキーパッチ
 5.2.3 DSLインタプリタの実装
  インタプリタの追加
  ボブの言語を話すということ
 5.2.4 デコレーターとしてドメインルールを追加する
  取引DSL:今いる場所
  ドメインルールの実装
  デコレーターを使ったRuby DSL
5.3 注文処理DSL:Groovyの最後のフロンティア
 5.3.1 これまでの注文処理DSL
 5.3.2 メタプログラミングのスコープの制御
  GroovyのMOPとカテゴリー
  基本的なDSL
 5.3.3 仕上げ
5.4 Clojureを使って考え方を変える
 5.4.1 ドメインオブジェクトの構築
 5.4.2 デコレーターを使ってドメインオブジェクトをエンリッチする
  Clojureのコンビネータの使い方
  高階関数を使ったデコレーター
  Clojureのマクロを使ってまとめ上げる
  これまでにやったこと
 5.4.3 REPLによるDSLセッション
5.5 従うべき指針
 5.5.1 複雑さ最小の原則の遵守
 5.5.2 最適な表現力の尊重
 5.5.3 入念に設計された抽象の原則を弱めない
 5.5.4 言語間の不協和音を避ける
5.6 まとめ
5.7 参考文献

第6章 Scalaによる内部DSLの設計

6.1 なぜScalaか?
6.2 Scala DSLに向けた最初の一歩
 6.2.1 Scala DSLを使ったJavaオブジェクトのテスト
 6.2.2 JavaオブジェクトのラッパーとしてのScala DSL
 6.2.3 さほど重要ではない機能をScala DSLでモデル化
6.3 ScalaでDSLを使ってみよう
 6.3.1 表現力豊かな構文
 6.3.2 ドメイン抽象の生成
  証券
  口座と取引
6.4 取引生成DSLの構築
 6.4.1 実装の詳細
  暗黙の型変換
  暗黙の型変換の詰め合わせ
  implicitとレキシカルスコープ
 6.4.2 DSL実装パターンのバリエーション
6.5 DSLでビジネスルールをモデル化する
 6.5.1 拡張可能なVisitorとしてのパターンマッチング
 6.5.2 ドメインモデルの強化
 6.5.3 DSLによる税および手数料計算のビジネスルール
  適用可能な税および手数料のリストを取得する
  税および手数料の算出
  DSLとAPI:何が違うのか?
6.6 すべてをつなぎ合わせる
 6.6.1 トレイトと型を使ったさらなる抽象
 6.6.2 具象ドメインコンポーネントの作成
6.7 DSLの合成
 6.7.1 拡張を使った合成
  DSLを成長させる
  プラグイン可能なセマンティクスを持った合成DSL
  関数コンビネータを使った合成
  完全に合成されたDSLを使う
 6.7.2 階層的な組み合わせを使って異なるDSLを合成する
  実装の結合を避ける
  残高をどのようにモデル化するか
  残高DSLをポートフォリオDSLに合成する
6.8 DSLのモナド構造
  モナドとは何か
  モナドによる「偶有的な複雑性」の削減
  モナドを使った取引DSLの設計
6.9 まとめ
6.10 参考文献

第7章 外部DSLの実装

7.1 外部DSLの解剖学
 7.1.1 単純さが最優先
 7.1.2 ドメインモデルの抽象化
  大きなボックスをモジュラー化する
  セマンティックモデル
  セマンティックモデルの生成
7.2 外部DSL設計におけるパーサーの役割
 7.2.1 パーサーとパーサージェネレータ
 7.2.2 構文主導型変換
  ANTLRを使った例をセットアップする
  レクサーの設計
  文法規則の設計
  独自のアクションとして外部コードを埋め込む
  パーサーモジュールの構築
  ここまでの道のり
7.3 パーサーの分類
 7.3.1 単純なトップダウンパーサー
  LL(1)再帰下降パーサー
  LL(k)再帰下降パーサー
 7.3.2 より高度なトップダウンパーサー
  再帰下降バックトラックパーサー
  メモ化パーサー
  述語制御パーサー
 7.3.3 ボトムアップパーサー
  演算子順位パーサー
  LR(k)パーサー
  LRパーサーのバリエーション
  実際には何を使えばいいのか
7.4 Xtextを使ったツールベースのDSL開発
 7.4.1 文法規則とアウトラインビュー
 7.4.2 文法に対するメタモデル
 7.4.3 セマンティックモデルに対するコード生成
  Xpandテンプレートを使ったコード生成
  DSLスクリプトの処理
  長所と短所(ただし、長所が大部分)
7.5 まとめ
7.6 参考文献

第8章 Scalaのパーサーコンビネータを使った外部DSLの設計

8.1 パーサーコンビネータ
 8.1.1 パーサーコンビネータとは何か
 8.1.2 パーサーコンビネータによるDSLの設計
8.2 Scalaのパーサーコンビネータライブラリ
 8.2.1 パーサーコンビネータライブラリ中の基本的な抽象
 8.2.2 コンビネータによってパーサーをつなぎ合わせる
  すべての文法規則は関数
  逐次合成コンビネータ
  選択コンビネータ
  逐次合成(選択保持)コンビネータ
  繰り返しコンビネータ
  すべてをまとめる
 8.2.3 DSLパーサーコンビネータ用のモナド
  逐次合成コンビネータの実装:大変な方法
  モナドの利用:ママ見て、余計なコードがなくなったよ!
 8.2.4 Packratパーサーで左再帰のDSL構文をパースする
  Packratパーサーはメモ化によって効率を上げている
  Packratパーサーは左再帰をサポートする
  Packratパーサーはスキャナなしでパースできる
  意味述語のサポート
  順序選択
8.3 パーサーコンビネータを使ったDSLの設計
 8.3.1 ステップ1:文法の実行
 8.3.2 ステップ2:DSLのセマンティックモデルの構築
  関数適用に対するコンビネータ
  部分関数の適用に対するコンビネータ
 8.3.3 ステップ3:注文を表現する抽象の設計
 8.3.4 ステップ4:関数適用コンビネータを使ってASTを生成する
8.4 Packratパーサーを使ったDSL
 8.4.1 ドメインの問題の紹介
  ビジネス処理の理解
  実装するSSIルールのサンプル
 8.4.2 文法の構築
 8.4.3 セマンティックモデルの設計
 8.4.4 パーサー合成によるDSLセマンティクスの拡張
  独自の拡張に対するモナド
  デコレーターとして独自のパーサーを設計する
  デコレーターを追加する
8.5 まとめ
8.6 参考文献

第3部 DSL開発の将来

第9章 DSL設計:未来の展望

9.1 DSLの設計に対する言語サポートの拡充
 9.1.1 表現力を向上させる努力
 9.1.2 メタプログラミングの強力さ
 9.1.3 XMLの代わりにS式を使う
 9.1.4 パーサーコンビネータの普及
9.2 DSLワークベンチ
 9.2.1 DSLワークベンチとは何か
 9.2.2 DSLワークベンチを利用することによるメリット
9.3 IDEツールによるサポート
9.4 DSLの進化
 9.4.1 DSLのバージョニング
 9.4.2 DSLのスムーズな進化に関するベストプラクティス
  暗黙的コンテキストを使ってバージョンの進化を容易にする
  自動変形による後方互換性の維持
  DSLファサードで多数のバージョン管理問題に対処する
  入念に設計された抽象の原則に従う
9.5 まとめ
9.6 参考文献

付録A ドメインモデリングにおける抽象の役割

A.1 入念に設計された抽象の特性
 A.1.1 最小化
 A.1.2 蒸留
 A.1.3 拡張性と合成可能性
A.2 最小化:約束したものだけを公開する
 A.2.1 汎用的な型を使った進化
 A.2.2 実装の露出を防ぐためのサブタイプ化
 A.2.3 実装継承を正しく使う
A.3 蒸留:必要なもののみを残す
 A.3.1 何が“余計な”ものなのか
 A.3.2 偶有的な複雑性
 A.3.3 汚染の除去
 A.3.4 DIによって実装の詳細を追い出す
A.4 拡張性による段階的な成長の実現
 A.4.1 拡張性とは何か
 A.4.2 ミクシン:拡張性のためのデザインパターン
 A.4.3 Mapの拡張にミクシンを使う
 A.4.4 関数拡張性
 A.4.5 拡張性も「猿真似」になり得る
A.5 合成可能性は純粋性から生まれる
 A.5.1 合成可能性に対するデザインパターン
 A.5.2 言語に戻って
  プロトタイプベースのオブジェクト指向
  どこにでもあるメタプログラミング
 A.5.3 副作用と合成可能性
  コマンドとクエリーの分離
  Haskellでの例
 A.5.4 合成可能性と並行性
A.6 参考文献

付録B メタプログラミングとDSLの設計

B.1 DSLにおけるメタプログラミング
 B.1.1 DSL実装における実行時メタプログラミング
 B.1.2 DSL実装におけるコンパイル時メタプログラミング
  C++:テンプレート
  LispとClojure:マクロ
  Java:アノテーション処理とAOPのサポート
B.2 DSLとしてのLisp
 B.2.1 Lispの何が特別なのか
 B.2.2 データとしてのプログラムコード
 B.2.3 プログラムコードとしてのデータ
 B.2.4 リスト構造だけをパースする単純なパーサー
B.3 参考文献

付録C RubyのDSL機能リファレンス

C.1 Rubyが持つDSL向けの機能
C.2 参考文献

付録D ScalaのDSL機能リファレンス

D.1 Scalaが持つDSL向けの機能
D.2 参考文献

付録E GroovyのDSL機能リファレンス

E.1 Groovyが持つDSL向けの機能
E.2 参考文献

付録F ClojureのDSL機能リファレンス

F.1 Clojureが持つDSL向けの機能
F.2 参考文献

付録G 多言語開発

G.1 IDEにどんな機能を求めるか
G.2 Java/Groovy開発環境の構築
G.3 Java/Scala開発環境の構築
G.4 多言語開発向けの人気の高いIDE
監訳を終えて — 佐藤 竜一
索引

コラム目次

金融取引システムの基礎知識
金融取引システム:取引と決済
金融取引システム:顧客注文の処理
金融取引システム:顧客の口座
金融取引システム:取引の現金価格
金融取引システム:証券の種類
金融取引システム:標準決済指図(SSI)

付属データはこちら

お問い合わせ

内容についてのお問い合わせは、正誤表、追加情報をご確認後に、お送りいただくようお願いいたします。

正誤表、追加情報に掲載されていない書籍内容へのお問い合わせや
その他書籍に関するお問い合わせは、書籍のお問い合わせフォームからお送りください。

利用許諾に関するお問い合わせ

本書の書影(表紙画像)をご利用になりたい場合は書影許諾申請フォームから申請をお願いいたします。
書影(表紙画像)以外のご利用については、こちらからお問い合わせください。

追加情報はありません。
この商品の「よくある質問」はありません。

ご購入いただいた書籍の種類を選択してください。

書籍の刷数を選択してください。

刷数は奥付(書籍の最終ページ)に記載されています。

現在表示されている正誤表の対象書籍

書籍の種類:

書籍の刷数:

本書に誤りまたは不十分な記述がありました。下記のとおり訂正し、お詫び申し上げます。

対象の書籍は正誤表がありません。

最終更新日:2013年09月12日
発生刷 ページ数 書籍改訂刷 電子書籍訂正 内容 登録日
1刷 116
図4.8

「誤」の赤枠部分を訂正します。
2013.09.12
1刷 116
図4.9

「誤」の赤枠部分を訂正します。
2013.09.12

感想・レビュー

kannkyo さん

2018-12-08

比較的実践的なドメイン固有言語(DSL)の入門書。 Java、Scala、Ruby及びGroovy等の複数言語のDSLの実装方法を幅広く紹介する。DSL云々以前の基本的な文法の説明はしてくれないので、読者に要求される技術レベルは高い。 が、日本であまり普及していないDSLを幅広く知るには、最善の一冊。

river125 さん

2015-01-01

DSLについて勉強。巨匠マーチン・ファウラーの本は読み疲れしそうだったので、こっちを読んでみたが、こっちも疲れた。DSLを学問的研究対象と見てるのかな。もう少しコード例を増やして実践的な側面を重視して欲しかった。掲載コードも、あんまりDSLの利点を実感できない印象。読み終えて、さぁClojureで(あるいはRubyで)DSLを実装しよう、という気にはならなかった。

Tadatoshi Sekiguchi さん

2013-01-05

DSLの概要からデザインパターン、内部DSLの実装、外部DSLの実装まで一通り解説している本。DSL in Actionの邦訳。DSL本としては圧倒的なボリュームで、xTextといったDSL専用プラットフォームにも言及している。内部DSL, 外部DSLの解説がScala押しで、Scala DSLを始めるにあたり読んでおきたい。またDSLを考える上で、抽象型をどのように考えるかといった考え方が付録についており参考になる。実例は金融(証券)を題材としていて、金融ドメインの知識があるとすんなり入ってくる。