いものやま。

雑多な知識の寄せ集め

上牧温泉でまったりしてきた。(その1)

ゴールデンウィークということで3連休とって4/29(月・祝)〜5/2(木)に3泊4日で群馬の上牧温泉に行ってきた。

大峰館

今回お世話になったのは大峰館(おおみねかん)。

ここには日帰り温泉で一度来たことがあって、露天風呂がとてもよかったのを覚えてる。

ちなみに、去年行った館山やお正月に行った水戸もよかったのでどこに行こうか迷ったんだけど、日頃の疲れを癒すならサウナよりやっぱり温泉かなと思い、上牧に決めた。 ちょっと風呂に入りたいなと思ったときにいつでも温泉入れるのはやっぱり魅力的よね。

さて、4/29は自宅を10時半頃に出発し、車を3時間弱走らせて無事水上に到着。 お昼を食べて少し散策したあと、予定通りに15時頃に大峰館に到着した。

大峰館の入口

大峰館

そうそう、水上は山の方ということもあってか、ちょうど山桜が見頃を迎えている感じだった。 いろんなところで花が咲いててとてもよかったなぁ。

チェックインを済ませたら部屋へ。

部屋

部屋は本館のトイレのある部屋。

古さはあるものの設備はちゃんと整ってて、とても過ごしやすかった。 自分が泊まった部屋はけっこう広くて、4〜5人は楽に泊まれそうだったかな。 旅館によくある「あの空間」はなかったけどw

部屋では基本ゴロゴロして積読してた本やマンガを消化してた。 眠くなったら軽く寝たり、お風呂行きたくなったら温泉入ったりと、まさに湯治って感じ。

自然豊かで、外から聞こえてくる鳥や蛙の鳴き声が心地よかったなぁ。 音楽流せるようにスピーカーを持ってったりもしてたんだけど、結局使わなかった。

ちなみにWiFiもちゃんと飛んでてネットにも繋がった。 ちょっと回線速度は遅い気もしたけど、配信見れるくらいには大丈夫だった。 将棋ウォーズしようとするとさすがに遅延が気になったけど。

一応、少し残念だったことも書いておくと、自分の泊まった部屋だと窓が山側で眺めはちょっと悪かったかなぁ。 新館は窓が谷側にあると思うので、眺めもよさそうな気がする。 ということで次は新館の部屋にも泊まってみたいな。

風呂

お風呂は新館の方へ移動して階段を降りたところにある。

前に日帰り温泉で入ったときも思ったけど、やっぱりいい温泉。 こじんまりした露天風呂なんだけど、風情があってとてもいいんよね。

腰掛けるのにちょうどいい感じの石もあって、十分に温まったらそこに腰掛けて休憩もできたり。 繰り返すことで体の芯から温まってコリもほぐれる気がした。

お風呂を出たところには冷やした温泉も置いてあって、飲めるようになってたり。 ほのかな香りがするので苦手な人もいるかと思うけど、冷えてて飲むと気持ちいい。

入りたいと思ったときにいつでもすぐ入れるのもよくて、1日に4, 5回は入ったかなぁ。 1, 2回だけ他のお客さんがいたりというのはあったけど、基本貸切状態だったし。 贅沢だったなぁ。

料理

食事は朝夕の2食が出るプラン。

夕食はメインが上州牛の石焼で、おかずもいろいろ。

ある日の夕食

上州牛の石焼

この牛さんの美味しいこと。 あと写真にはないけど別の日に出てた岩魚の塩焼きとかも美味しかったなぁ。

朝食はおひつに入ったご飯に湯豆腐、そしておかずという感じ。

ある日の朝食

ご飯はお茶碗2杯分はあってたっぷりという感じ。 美味しくてとてもよかった。


宿ではそんな感じで、基本はゴロゴロしてたんだけど、少し出かけたりもしたので、それについては次に書きたい。

今日はここまで!

『Pythonでスラスラわかる ベイズ推論「超」入門』を読んでみた。

Pythonでスラスラわかる ベイズ推論「超」入門』を読んでみたので、軽く感想とか。

概要と感想

ベイズ推論の本はいろいろあるけど、この本は理論というよりツールとして活用することに重きをおいた感じの本。

サンプリングをどう計算するのかとかはライブラリ(PyMC)に任せてしまって本では解説せず、統計モデルの作り方と得られたサンプリングの結果の使い方の解説が中心になってる。 数理最適化でたとえると、単体法とかの解説はしないでPuLP使ったモデリングの解説をしている感じ。

そういうこともあってすごく読みやすかったし、実用としてはこういう本の方が助かるよね。 別に研究者として新しいアルゴリズムを作りたいとかでもないし。

数理最適化もそうだけど、理論とか勉強しても実際に使うときはライブラリ叩くだけで、一番壁になるのはモデルを作る部分なので、その部分がちゃんと解説されてるのはとてもよかった。

とくに興味深かったのは6章で、ABテストでの効果検証、線形回帰での要素の影響度合い、項目反応理論でのテスト評価といった内容が取り上げられていて、こんな感じで使うんだというイメージが持てた。 こういうのをいくつか知っておくと別の分析でも使ったりできそう。

ただまぁ、この本であらためて思ったけど、こういった統計モデルは分析に使うもので、予測に使うには力不足な感じ。 モデルとしては単純な線形モデルにすぎないからねぇ。 それをどう解釈するのかという部分、つまり分析としては、より慎重な解釈を与えてくれるけど、予測の精度が上がるわけではないからなぁ。

あと、実際に使うときにはちょっとジレンマがありそうな感じも。

データが少ない場合は事前分布の重要度が上がるので恣意性がかなり入りそうだし、保証できる範囲も広くなってしまって分析としての意味がどれだけあるのかとなりそう。

一方でデータが多い場合はサンプリングにかかる時間がだいぶ増えてしまって、実用的に使えるか分からないところが。 6.3節では50問のテストを1,000人が受けた結果を分析するタスクがあったけど、たかが50,000程度のデータ、パラメータとしては1,100程度しかないのに、サンプリングで数分が要求されたり。 実際にはもっと次元の多いデータを扱いたいことが多いわけで、オモチャの問題でそんなだとなぁという感じも。

それとこの本では時系列データの扱いがなかったけど、そのあたりも気になるところ。 続編とか出るのかな?

時系列データを同じような感じでモデリングするのを試したことはあって、でもモデルのサイズが大きくなってぜんぜん動かなかったというのがあった。 これについては時系列データ用の分布がいくつか用意されてるのでそれを使うとサンプリングが走るようにはなったんだけど、複雑なモデルを作るのはちょっとキツそうな感じも。 実際の問題で使い物になるんかなぁ。

もくもく読書会

今回本を読むうえで「もくもく読書」という予定を立てて読むというのをやってみた。

これは社内で読書会をやったときに、読書会という場が用意されているとちゃんと最後まで読み進められるという学びがあったから。

あと、connpassをためしに使ってみたかったというのも。

やってみた感想としては、やっぱり予定を立てておくのは効果が大きいと感じた。 実際、予定通りに8回でちゃんと最後まで読み通すことができたし。 計画立てておかないと他のこと優先したりで最後まで読めてなかった可能性高かったと思う。

予定を立てておくと読むペースとかも分かるのがいいところ。 いつ頃までに読み終わるのか分かったり、1回でどれくらいの時間かけて何ページくらい読めばいいのかとかも調整できる。

connpassを使ってみたのはまぁ微妙なところ。 使い方とかは分かったのでとりあえずよかったけど。 あと画像の仕様とか。 資料を貼っておけるのも悪くはなかったかな。

最後に今回の読書でメモったノートブックを貼っておこうと思う。

今日はここまで!

長瀞・秩父で桜を見てきた。

先週末の4/14(日)に長瀞秩父に行って桜を見てきた。

法善寺

まず向かったのは長瀞にある枝垂れ桜の法善寺。

時期が少し遅かったのもあり、けっこう散ってる感じはあったけど、まだ少し残ってた。

法善寺の枝垂れ桜

アップで

北桜通り〜長瀞駅宝登山神社

そこからは北桜通りを抜けて長瀞駅を通り、宝登山神社へ。

北桜通りもまだ桜自体は残っていたけど、だいぶ葉桜になっていた感じはあった。 車で通り抜けたので写真はなし。

そして長瀞駅を通過して、宝登山神社へ。

宝登山神社の鳥居

宝登山神社の本殿

いやー、やっぱり宝登山神社は何度見ても立派よね。

そして今回はロープウェイで上には行かず、駅前へ戻り。

宝登山神社への参道の桜も散り気味

たまにキレイに咲いている桜も

長瀞駅前から参道への入り口

長瀞

駅前に戻ってきてちょうどお昼時になったので、ご飯を食べることにした。

いつもの鮎めしもいいなと思いつつ、ご当地グルメとして豚みそ丼も有名で食べたことがなかったので、今回は豚みそ丼を食べようかなと。

事前に調べていて、長瀞駅前で有名だったのは「有隣」というお店。

ただ、すでに数組が待っていて、けっこう待つことになりそうだったので、どうしようかなぁと。

そして他に空いてそうな店がないかなと少し探してみると、すぐ近くの「長瀞屋」がすぐに入れそうだったので、入ってみた。

昔ながらの定食屋という感じで、豚みそ丼と蕎麦のセットを注文。

豚みそ丼と蕎麦のセット

この豚みそがすごく柔らかくてびっくり。 味付けはもうちょい濃くてもいいかなとか、もうちょいボリュームほしいなとは思いつつも、美味しかった。 運転がなければビールも飲みたかったなぁ。

あと、ちょっと暑かったので、追加でかき氷も頼んでみた。

あずきミルクのかき氷

これがとんでもない量だったw 食べても食べてもなくならない(^^;

ただ、味は美味しくて、氷も積もったばかりの雪みたいな柔らかさ。 せっかくだからと大きいサイズを頼んだけど、小さいサイズにしとけばよかったなw

岩畳

お昼を食べたあとは少し散策して岩畳を見たりお土産を買ったり。

荒川ライン下り

岩畳と荒川

駅前の花壇がキレイだった

美の山公園

長瀞をあとにして、次に向かったのは美の山公園。

秩父の東の方にある山をぐんぐん登った上にある公園なんだけど、ここは桜がちょうど見頃で、眺望もよく、とてもよかった。

美の山公園への入り口

駐車場で撮った桜

駐車場を見下ろして

駐車場から公園へ向かう階段

公園入り口の桜と展望台

ヤマザクラらしい

展望台からの眺め

ちなみに展望台から見えてるのは秩父の市街。

桜と東の山々を臨んで

東に広がる絶景

園内の桜

秩父市街と桜を臨む

いいところだったなぁ。

清雲寺

元々は美の山公園に行ったあとは帰るつもりだったんだけど、お昼を食べた長瀞屋に飾ってあったカレンダーの枝垂れ桜が気になり、調べると清雲寺という秩父のお寺さんで、時期は過ぎちゃってるけどまだ残っていそうだったので、少し足をのばして向かってみた。

ここでちょっと意外だったのが、お寺には駐車場がなかったということ。 周りのお家で数百円払って停めさせてもらう感じだった。

清雲寺

見ての通り、散っちゃってる桜もけっこう多かったんだけど、まだ残っている桜もあって、キレイだった。

清雲寺の枝垂れ桜

近くで撮影

墓地の方にも

キレイな枝垂れ桜

すごく古い桜もあったみたいで、ただそこはすでに散っちゃっていたので、残念。 いい時期を狙ってまた来てみたい。

浦山ダム

そのあとは、すぐそばに浦山ダムがあるということなので、せっかくだから行ってみた。

浦山ダム

ダム湖が広がる

ここでダムカードもゲット。 初めてもらったかも。


そんな感じで長瀞秩父の桜(&ダム)を堪能してきた。

少し時期が遅かったのもあってけっこう散っちゃってたのはあったけど、それでもいい桜が見れたのでよかった。 とくに美の山公園はよかったなぁ。

今日はここまで!

「日付」と「日時」の話。

プログラミングで時間を扱おうとすると出てくるのが「日付」と「日時」。 これらに関してちょっと考えたことがあるので、その話をしてみたい。

「日付」と「日時」を構成するデータ

「日付(date)」を構成する要素を考えると「年(year)」「月(month)」「日(day)」。

一方で、「日時(datetime)」を構成する要素を考えると、「年(year)」「月(month)」「日(day)」「時(hour)」「分(minute)」「秒(second)」(とミリ秒などもあるけど省略)。

なので、差分プログラミング的に考えると、「日付」クラスを継承して「日時」クラスを作るとするのが自然。

たとえば、(あまりいいコードではないけど)Pythonでデータクラスを使ってシンプルに書くと、次のようになりそう:

from dataclasses import dataclass

@dataclass
class Date:
    year: int
    month: int
    day: int

@dataclass
class DateTime(Date):
    hour: int = 0
    minute: int = 0
    second: int = 0

date = Date(2024, 3, 31)
datetime = DateTime(2024, 3, 31, 12, 0, 0)

実際、Pythonの標準ライブラリにあるdatetimeモジュールでは、日付はdatetime.dateクラス、日時はそれを継承したdatetime.datetimeクラスとして実装されている。

これはRubyでも同様で、標準ライブラリのdateライブラリで、日付はDateクラス、日時はそれを継承したDateTimeクラスとして実装されている。

ただし、面白いことにRubyDateTimeクラスはDeprecatedとされていて、代わりに組み込みライブラリのTimeクラスを使うことが推奨されている。 これがDateクラスもDeprecatedになってるならdateライブラリ自体がよくないのかなとなるけど、継承したDateTimeクラスだけがDeprecatedになってるのが不思議なところ。 で、実はこれは自分が気になったところが原因じゃないかと思ってる。

「日時」は「日付」なのか?

さて、そんな感じでデータ構造を考えると「日時」を「日付」のサブクラスとして作るのは自然なんだけど、疑問が出てくる。

はたして、「日時」は「日付」なのか?

クラスの継承では「is-a」関係があるのが望ましいとされている。

たとえば「動物」を継承して「犬」とか「猫」を作るという例が代表的だけど、この場合「『犬』は『動物』の一つ」だし「『猫』も『動物』の一つ」なので、たしかに「is-a」関係が成り立ってる。

これは集合関係として捉えることもできて、「『サブクラスのオブジェクトの集合』⊆『スーパークラスのオブジェクトの集合』」となっているのが妥当な継承関係と言える。

たとえば「『犬の集合』⊆『動物の集合』」だし「『猫の集合』⊆『動物の集合』」とこの関係が成り立っている。

それを踏まえたうえで、「日付」と「日時」でそういった妥当な関係が成り立ってるのかどうか?

「日時」は「日付」の一つかというと、ちょっと違う。 というのは、もしそうであるのなら、「日付」をたくさん集めてきた集合の中に「日時」も含まれることになるわけだけど、そこには日付しかなくて、日時というのは入っていない。 「日付」を集めた集合の中に、たとえば「2024-03-31」という日時は含まれていても、「2024-03-31 12:00:00」という日時は含まれてない。

「日付」と「日時」がどういう関係なのかを考えると、1対多の関係とみるのが妥当そう。 1つの「日付」の中に複数の「日時」が含まれている感じ。 これは逆に「日時」側からみると1つの「日付」が対応付くので、「has-a」関係ともいえる。 なので、継承ではなくコンポジションを使うのが設計としては妥当そう。

簡単なコードで書くと(あまりいいコードではないけど)以下:

from dataclasses import dataclass

@dataclass
class Date:
    year: int
    month: int
    day: int

@dataclass
class DateTime:
    date: Date
    hour: int = 0
    minute: int = 0
    second: int = 0

date = Date(2024, 3, 31)
datetime = DateTime(date, 12, 0, 0)

継承だと起きる問題

とはいえ、継承で何か問題があるの?ともなりそうなところ。

実は問題があって、引数で「日付」の型でくるとなってたときに、データが「日付」の場合も「日時」の場合もあるのが変なことを起こしたりする。

たとえば、「ある日時がある日付に含まれるかどうか」という関数を作りたいとする。 素直な実装は次のようになる:

import datetime as dt

def is_datetime_in_date(datetime: dt.datetime, date: dt.date) -> bool:
    return datetime.date() == date

is_datetime_in_date(
    dt.datetime(2024, 3, 31, 12), dt.date(2024, 3, 31)
)  # => True
is_datetime_in_date(
    dt.datetime(2024, 4, 1, 12), dt.date(2024, 3, 31)
)  # => False

何も問題なく動いてるように見えるけど、実は問題があって、次のようなコードが型として問題なく実行できてしまう:

is_datetime_in_date(
    dt.datetime(2024, 3, 31, 12), dt.datetime(2024, 3, 31, 9)
)  # => False

datetime.datetimedatetime.dateを継承してるので、datetime.dateが指定されるべき引数でdatetime.datetimeが指定されても、型としては何も問題がない。 そしてこれはdatetime.date(2024, 3, 31)datetime.datetime(2024, 3, 31, 9)の比較がされるので、結果はFalseとなる。 日付はどちらも2024-03-31であるにも関わらず。

一応、実装を次のようにすれば、結果をTrueに変えることはできる:

def is_datetime_in_date(datetime: dt.datetime, date: dt.date) -> bool:
    return (
        (datetime.year == date.year)
        and (datetime.month == date.month)
        and (datetime.day == date.day)
    )

is_datetime_in_date(
    dt.datetime(2024, 3, 31, 12), dt.date(2024, 3, 31)
)  # => True
is_datetime_in_date(
    dt.datetime(2024, 4, 1, 12), dt.date(2024, 3, 31)
)  # => False
is_datetime_in_date(
    dt.datetime(2024, 3, 31, 12), dt.datetime(2024, 3, 31, 9)
)  # => True

ただ、冷静に最後の式の意味を考えると「2024-03-31 12:00は2024-03-31 9:00に含まれるか?」となってるので、やっぱりおかしい。 日付しか指定できないところで日時も指定できてしまってるのが本質的な問題で、この問題が起きてるのは継承してるからに他ならない。

これが継承を使わない実装になってれば、「日付」を指定するところで「日時」を指定するのは型としておかしいと弾けるので、問題を防げる。 本来くるべきではない値は型として弾くのがいい。 で、継承を濫用してスーパークラスを型として指定すると、都合の悪いサブクラスが指定されてしまったときにおかしくなる、と。


これに似た話が直和型でもあったりする。 それについてはまた別に話したい。

今日はここまで!

OOC2024で登壇してみた。

3/24(日)にお茶の水女子大でObject-Oriented Conference 2024 (OOC2024)が開催された。

今までカンファレンスで発表したことはなかったんだけど、オブジェクト指向に関する話を発表できる機会ということで、せっかくだからとプロポーザルを出してみた。 そしたらなんと採択してもらえたので、登壇して発表してきた。

その発表の概要と感想とか。

発表の概要

タイトルは「オブジェクト指向の修得はなぜ難しいのか」。

スライドはこちら:

ざっくりと内容を紹介すると、プログラミングを学ぶと普通は「処理の流れ(フロー)」に注目して「トップダウンで処理を分解」してプログラムを書いていく(これを自分は「フロー指向」と呼んでいる)けど、オブジェクト指向だと実はそうしなくて、「データ」に注目して「ボトムアップで部品を組み上げ」てプログラムを書いていくので、考え方が180度違うから学ぶのが難しいんだよ、といった感じ。

ちなみにこれに近い内容が増田さんのセッションでも出てきてて、ちょっと嬉しかったw

p.16の「オブジェクト指向プログラミングの設計スタイル」で、「機能 vs データ型」で「データ型」が、「ブレークダウン vs ビルドアップ」で「ビルドアップ」が選ばれてるのがそうで、これは自分のオブジェクト指向の理解と同じになっていて、またここで「機能 & ブレークダウン」を選ぶと自分が呼ぶ「フロー指向」になっている。

感想とふりかえり

オンラインのLTで発表したことはあったけど、オフラインの場でそれなりの人を前にして発表するのはほぼ初めてということもあり、かなり緊張した。

ただ、今回は事前に原稿を用意したり少し練習しておいたのもあって、なんとか話し切れた気はする。

この原稿を用意したのがよかった点で、実際のところ、本番のときに原稿を見る余裕は全然なかったんだけど、説明の流れや言葉選びをあらかじめ推敲する機会が生まれてたので、詰まることが少なくスムーズに進められたと思う。 まぁ、もうちょい練習した方がよかった感じはあるけど(ただ本番のテンションで練習するはなかなか難しい・・・)。

あと、今回すごく助かったのが、すごく頷きながら聞いてくれる方が会場にいたこと。 その方を見つけられたことで、途中からは緊張も和らいで発表できたと思う。 リアクションしてくれる聴衆って大事なんだなぁと実感した。

ただ、それは本当にラッキーで、今思えばその方以外の聴衆の反応は全然見れてなかった。 もっと意識してリアクションしてくれる方を探さないとダメなんだろうなぁ。 次があったら意識してみたいと思った。

少し関連することで、タイムキーパーの方が残り時間を表示してくれていたんだけど、全然気づけてなかった。 やっぱり緊張してて視野が狭くなってるんだろうなぁ。

タイムキープに関しては別の反省点も。 iPhoneでストップウォッチを使って時間を見ようとしてたんだけど、気づいたらロックがかかってて見れなくなってることが何度か。 これはLTでも同じミスをしたことがあって、それを回避するために「おっかけプレゼンタイマー」というツールを導入してたんだけど、今回はネットワークに繋げられない環境だったので、このツールが使えずに同じ過ちを繰り返してしまった。

ネットワーク使えないときは気をつけるようにしないと。

とまぁ、初めてだったこともあっていろいろ反省点はあったけど、無事発表できたので、とてもいい経験になったと思う。 次があったらもうちょっと改善していきたいなぁ。

今日はここまで!

ソフト開発における「設計」とは何なのか。(まとめ)

これまでの各記事は、以下から。

だいぶ長くなったけど、現時点での自分の考えをある程度書き出せたかなと思う。

ポイントを少しまとめておくと、以下のような感じ:

  • ソフトウェアにおける開発とは、ソースコードの差分を生み出すこと
  • 開発はWhy → What → Howの順にブレークダウンしていく
    • Whyは要求で、「顧客が」何を望んでいるのか
    • Whatは要件で、顧客の要求を解決するために「開発者が」何を提供するのか
    • Howは設計で、要件を満たすためにソースコードの差分をどう生み出すか
  • 要求を満たす要件や要件を満たす設計は複数ありえる
    • 取捨選択するのが要件定義や設計というプロセス
    • 方向性を確認するためのコミュニケーションツールが要件定義書や設計書
  • 要件定義や設計においてユースケース記述は有用
    • イメージのすり合わせに使える
    • ドメイン知識の抽出に使える
  • ソースコードから作られる文書は設計書ではなく開発者向けドキュメント

せっかくだからもう少し整理して同人誌にしてもいいなぁ。

今日はここまで!

ソフト開発における「設計」とは何なのか。(その11)

前回はアジャイル開発に関する話や実現可能性の話を書いた。

今回はプロセスの話ではなく、ソフトウェアをどう考えて設計するといいかについて。

オブジェクト指向分析設計

今ソフトウェアの設計の話というと、ドメイン駆動設計(Domain-Driven Design, DDD)が流行っている感じはある。

ただ、どうにもDDDの本来の目的(ソフトが価値提供する領域(ドメイン)の知識をドメインモデルとして表現し中核に置くことで、価値提供の現場とのギャップをなくそうとしている)とはズレて、小手先のテクニックや紹介されているアーキテクチャの真似事に陥ってしまっている感じも。 根底にある思想の理解は難しいけど、やることのマネならなんとなくできてしまうからねぇ。

それと、一番肝心のドメイン知識をどうやって得るのかという部分についてはあまり語られていないというのも大きい。 「DDDやってみたいけど、ドメインモデルが抽出できない」というのもよく聞く。

そもそもの話として、オブジェクト指向的な考え方でなくフロー指向的な考え方をしてると、ドメインモデルをクラスとして表現するという発想ができないので、オブジェクト指向的な考え方ができてることは前提としてある (オブジェクト指向とフロー指向については『オブジェクト脳への一歩』というLTをしてみた。 - いものやま。や自分の同人誌『オブジェクト・ウォーズ』を参照)。 この前提がまずできてない人も多い印象・・・

それを抜きにしても、どうやってドメインモデルを抽出していくのかという「やり方」のは説明が必要だと思う。

実はそのあたりの「やり方」の話は、ソフト開発における「設計」とは何なのか。(その8) - いものやま。でも少し書いたけど、オブジェクト指向分析設計(Object-Oriented Analysis and Design, OOAD)で語られている。

オブジェクト指向分析設計について知りたい場合、次の本が楽しく読めると思う:

ただ、絶版なんだよなぁ・・・コード例が古いというのもちょっと難点。 デザインパターンは第2版が出たので、これもまた出るといいんだけど。

ユースケースから考える

さて、設計の出発点となるのは、ユースケース。 ここで、システムは何を顧客に提供するのか(そして何を提供しないのか)という境界を定めることになる。 また、システムが実際にどのように使われるのかや、その中で出てくる概念(ドメイン知識)を洗い出すことになる。

ドメイン駆動開発だと、このユースケースについて考えて分析するというプロセスが書かれてないんよね。

で、ユースケースを考えたあとにやりがちなのが、そのユースケースの流れをそのままコードにしてしまうということ。 これはとてもフロー指向的な考え方で、これをやってしまうとドメイン知識はどこにいるのか分からなくなってしまう。 トランザクションスクリプトと呼ばれるのは、これをやってしまった結果として生まれる。 とても自然な発想ではあるんだけど、ドメイン知識があちこちに散らばってしまったり、変更に弱いコードになりやすい。

じゃあ、ユースケースを考えたあとに何をやるといいのかというと、ユースケースに出てくる名詞(と動詞)に注目するということ。 それらはドメインに登場してくる重要な「概念」なので、それらを抽出して、その概念がどういったものなのか、データ(プロパティ)として何を持つのか、どういったデータが妥当なのか(不正なデータの規定になる)、何ができるのか(メソッド)、他の概念との関係性はどうなっているのかなどを分析する。 そうやって分析した結果として表現されたクラスにはドメイン知識が詰め込まれることになる。

また、それらの概念を使った「処理」というのもある種の概念となるので、それもクラスとして表現しておくといい。 どういった処理を行うのかという具体的な内容、知識がクラスの中に詰め込まれて、外部からはその処理を実行しろというキックだけ行えば、オブジェクトが適切な処理をしてくれるようになる。

あとはそうやって用意した部品を組み上げてユースケースを実現すればいい。 こうすることで、ドメイン知識の詰まったコードを生み出せるようになる。

で、実際の開発の場合、生み出すのはソースコードの差分なので、こうやって分析するのは今回開発or変更する部分についてだけとなる。 そして新しく作るクラスや変更の入るクラスが見つかったら、それを設計書に書いて、方針の確認をするといい。 こうすると、処理の流れといった詳細をダラダラと書くのではなく、ファイル構成やそこで実装されるクラスといった概念レベルでのチェックができたりもする。

今日はここまで!