generated at
データと情報の違い
データ(data)と情報(information)をソフトウェア開発論の中で区別して語ることはあまり多くないが、ただ取得したり計測したり外部から連携されてくるモノと、それを活用して事業活動で使う段階のモノには明らかな違いがあるので、これを区別して世の中の方法論を理解してみようという試み。

データと情報を区別している文献
データ: それ自体に意味はなく、記録として残しておくもの
情報: データを選択・加工して、当事者が必要とする知識(新たな価値)を取り出したもの
DIKWの論文。データと情報を区別する系の元ネタ。
データ: モノやイベントの性質を表すシンボル
情報: 処理されたデータであり、その処理はその有用性を高めることを目的としている
知識: 指示、つまりHow-toの質問に対する答えによって伝えられる
データ: シンボルやシグナルの読み取りの記録
情報: 意思決定や行動のための関連する意味、含意、インプットを含むメッセージ
知識: 情報を元に価値を創造する

ソフトウェアにおけるデータと情報の区別
主にLiewの定義を元に考える。
データを多くの文献で「ただ取得したり計測したり外部から連携されてくるモノ」とすると、スキーマ定義を与えたモノはデータなのか? という疑問が浮かぶ。データは構造を持っていても良いので、スキーマが定義されていても良いが、これが特定の意思決定や行動のためのものであるとデータとは言えず情報になる。
ハッキリした線引きはできないが、以下のように考えうる。
データを特定の意思決定や行動のために必要な形に解釈を加えたものが情報である。
Rich HickeyとAlan Kayの議論のすれ違いは、データを解釈して、利用価値のある情報になる、と考えれば説明できそう。
Rich Hickeyはデータに下手に解釈を加えず(ただしメタデータやフォーマットは含まれる)、事実として記録されたものと捉えることで、必要な時に解釈を加えて価値を生み出す機会の最大化を主張しているようにみえる。
Alan Kayは解釈するものがいてはじめて利用価値がある(DIKWでいうところの知識が生み出せる)という立場から、データだけでは価値がない、と返しているようにみえる。
業務システム構築におけるデータモデリングの整理は、概ねそうとも言えるが、何の解釈も加えていないローデータだけをデータベースに保存するわけではないので、そこには設計のグラデーションが存在する。

データと情報の間には明確な線引きはできないものの、概ね以下のようにDIKWと整合できる。
つまり、データを解釈したものがドメインモデルである、と考える。

オブジェクト指向とデータ
オブジェクト指向はデータと振る舞いをひとかたまりとするものである。振る舞いをデータにバンドルできるということは、データを解釈済みの情報として扱うことを前提としていることに他ならない。
情報ではなく単なる「データ」を扱うと貧血症と呼ばれる
単なる「データ」であるにもかかわらず、半ば無理やり振る舞いを持たせる
ふるまいが特定の1つの情報にバンドルさせるのが難しいことがある。
例えば口座間の送金で、「送金する」という振る舞いは送金元口座なのか送金先口座なのか? のような問題

解釈をどこでやるかのスタイル3選
1. データの解釈は各メソッドや関数の中で行う
すなわちドメインモデルを作らない。
task.ts
class Task { title: string; deadline: Date; status: TaskStatus; asignees: Person[]; completedAt: Date; } function postpone(task:Task, days: number) { if (task.status != "DOING") { throw new Error(`延期するにはTaskがDOINGでなければなりません`); } if (days <= 0) { throw new Error(`延期する日数は1以上の整数で指定してください`); } task.deadline.setDate(task.deadline.getDate() + days); }
一見、上記 Task はモデルとして機能しているようにみえるが、データと情報の区別の観点からいけば、 Task の解釈の仕方はいかようにもできる余地がある。そのため、 Task を処理する関数の中でその状態のチェックが入る。 Task のデータを期限延長という業務で見たときには、ステータスが DOING でなくてはならないという制約がる。が、これを Task が満たしているか解釈するのは期限延長の直前になる。すなわち、データを業務的な解釈を加え情報として利用する箇所が、あちこちに散らばるることになる。
さらには各プロセスの事前条件/事後条件がコードからは読み取れないので、ドキュメンテーションが重要になる。

2. データの解釈を関数の事前条件、事後条件として記述する
Rich HickeyのMaybe Not参照
あまりないスタイルではあるが、「情報」の仕様変更影響が波及するのを最小限にするために、データのまま扱い、ロジック(知識)のIN/OUTの条件として、どう解釈するかを記述する。
1のスタイルで、事前条件/事後条件をドキュメンテーションとしてきっちり書きメンテしなきゃいけない点を、動くコードとして記述するところに違いがある。(この視点だけからすれば、Design by Contractと同じにみえる)
task.clj
(s/def :task/title string?) (s/def :task/deadline #(instance? LocalDateTime %)) (s/def :task/status #{:todo :doing :done}) (s/def :task/assignees coll?) (s/def :task/completed-on #(instance? LocalDateTime %)) (s/def :task/task (s/keys :req [:task/title :task/status] :opt [:task/deadline :task/assignees :task/completed-on])) (s/def :task/status-doing #(= (:task/status %) :doing)) (s/fdef postpone :args (s/cat :task (s/and :task/task :task/status-doing) :days pos-int?) :ret :task/task) (defn postpone [task days] (update-in task [:task/deadline] #(.plusDays % days))) (st/instrument `postpone) (def task {:task/title "task" :task/status :done :task/deadline (LocalDateTime/now)})
このスタイルは、型に秘められた暗黙的な意味的結合を弱めることを目的とするが、その分コード記述量は増えがちである。

3. データの解釈は型として記述される
他の解釈の余地がない程度まで、型を設計すると、ドメインロジックからはバリデーションが消える。
task.ts
type TodoTask = { title: string; } type DoingTask = { title: string; deadline: Date; asignees: Person[]; } type DoneTask = { completedAt: Date; } type Task = TodoTask | DoingTask | DoneTask function postpone(task: DoingTask, days: PosInt) { task.deadline.setDate(task.deadline.getDate() + days); }
このスタイルでは型が増えがちである。が、データの解釈は型に表現され、型がそのドキュメンテーションの役割を果たすようになる。
ここに至るためには、以下の性質を満たすようにドメインモデルを作っていく必要がある。
Totality(全域性)