「Object-Oriented Conference 2024」に参加してきました

オブジェクト指向のリ・オリエンテーション ~歴史を振り返り、AI時代に向きなおる~

  • 羽生田 栄一さん

オブジェクト指向の嬉しいところ

  • プリミティブだけじゃなくてドメインに対して操作できるようになった
    • 意味のある領域にクラスを割り当ててプログラミングできるのがいい
    • 概念を使ってプログラミングするのを可能にした

オブジェクト指向の段階

  1. オブジェクト指向ミニマム
    • idを持っていて1つ1つ区別できる
    • カプセル化された状態をもっている
  2. 責務/ロールの概念整理
    • メッセージへの応答能力
    • 存在理由を1つに定めて1つの責務を果たす
    • SRP(Signle Responsibility Principle)
  3. クラス/継承/ポリモフィズム
    • 意味のあるメソッドが体系付けられてクラスの中に閉じ込める必要がある
    • リスコフの置換原則が理解できてないなら継承を使うな
    • 継承はサブタイピングとして強い型付けを意識
  4. 構造主義的なオブジェクト指向
  5. レイヤー化
    • 依存関係の制御

オブジェクト指向と関数型

生成AIの不確実性と向き合うためのオブジェクト指向設計

  • 菊池 琢弥さん

生成AIのユースケース

  • copilotなどの開発での活用ではなくプロダクトへの埋め込みの話
  • 技術視点から
    • システムで扱いにくかったデータが扱いやすくなる
      • 表記揺れの吸収とか
        • 文脈を意識した分類とか
  • 体験から
    • 自動化(Automation)
    • 代行(Agent)
    • 助言(Advice)
    • 強化(Augment)

クソコード動画『カプセル化 Mk-II』で考える、上手くカプセル化できない理由

  • ミノ駆動さん

カプセル化と関心

  • データとデータ操作ロジックをひとまとめにすること
  • 正常に操作可能なメソッドのみ公開する
    • setterは不整地も含めて代入できてしまうため避けること
  • 関心ごとに構成を分離する
    • Aを修正してもBに影響がでないように

目的と手段

  • システム手段で実現したい目的があるはず
  • 目的には下位目的が発生する
    • それぞれの目的を達成するための手段を用意する
  • 目的が決まると達成したいことが決まる
    • それぞれの目的に必要な要素は異なる
  • [上位目的]商品を売買したい
    • [下位目的]在庫管理したい/注文したい/配送したい
  • 手段に紐づく目的は1つ
    • 目的外の利用はだめ
    • システムでも一緒とのこと
    • 特定のクラスが多目的に使われると崩壊する
    • 手段からみて目的が1つになるように設計するといい

モデリング

  • ECサイトで「商品モデル」を作ると巨大化する
    • 中心的になるモデルはあらゆる目的に紐づいてしまう
  • 目的論的抽象/存在論的抽象
    • 存在論:魚類
    • 目的論:夕食の素材
    • 存在論では目的に合う要素だけをうまく抽出できない
  • モデル
    • ある目的を達成するために目的に合致した特徴のみを抜き出し他を捨て去ったもの
  • モデリング
    • 特徴を抜き出し他を捨て去る活動

DDDはなぜ難しいのか / 良いコードの定義と設計能力の壁

  • pospomeさん

DDDを理解する

  • ドメイン
    • 領域
    • ユーザがソフトウェアを適用する対象領域
  • DB駆動設計
    • テーブルと1対1でクラスを作る
    • 複数のクラスにまたがるロジックの置き場所に困る
    • FatModelかドメインモデル貧血症になる

良いコード

  • ICONIX
    • 図を書いて設計に落とす
  • 実装ファーストで考えるのが良い
    • 図を書くだけではうまく設計できない
  • 保守性
    • モジュール性
    • 再利用性
    • 解析性
    • 修正性
    • 試験性

設計能力の壁

  • 基礎力が必要
    • よくある原則的なもの
  • DDDの本はプラクティスを教えてくれるだけ
  • 時間を消費する割に品質がそれほど高くないものになってしまう

ビジネスロジックを「型」で表現するOOPのための関数型DDD

関数型DDD

  • 関数型のエッセンスを加えてビジネスロジックを型の力で柔軟にしたDDD
  • 型があると実装ミスをコンパイルで検知できる
  • 例えば特定の条件のときだけ値があるフィールド、みたいなものをコンパイルで検知できる

モデルの状態を代数的データ型で表現する

  • 特定の条件のときだけ必須の項目
  • コンストラクタで検証する?
    • 実装なのでテストしないといけない
  • 状態ごとにモデルを作ると良い
    • 注文取得したときのどの状態か分からないのでanyにするしかないのが課題
    • 各ステータスの注文をまとめて扱いたい
  • 代数的データ型
    • 直積集合と直和集合で表される構造体
    • 継承はどんな子クラスがあるか制限できないのが違う(直和の性質がない)
    • Enumは個別の構造体が持てない(直積の性質がない)

モデルの状態遷移を型と全域関数で表現する

  • ステータスの繊維のダメなルートをコンパイルで落としたい
  • ルールの適用と違反時のハンドリングがある
    • 前者を型で守る
    • 校舎はテストで担保
  • 関数の全域性
    • すべての入力が対応する出力を持つこと
    • inputが決まるとすべてのoutputが同じ挙動をするもの
    • ルール違反になるパターンが有るときはinputの型を絞る
      • 割り算で0以外の整数の方を作ると全域関数になる

ロジック内のDBアクセスを高階関数で表現する

  • DBアクセスの理想
    • 最初に全部読み込み、処理して、最後に書き込み
    • ドメインモデルがシンプルになってテストが書きやすい
  • ドメイン層に隠蔽したいところだけを高階関数にする

設計の知識と技能で駆動するソフトウェア開発

はじめに

  • 開発プロセスの中に開発と設計がある
    • 設計が良いと開発が楽になる
  • 設計は経験則の面も大きい
    • 技能として身につけるには手を動かすことが重要
    • 知識と技能を持ち寄って組み合わせるとさらにレベルアップする

ソフトウェア設計の基礎知識

  • 基本課題
    • 本質的な複雑さ/発展性に対応できない
    • 巨大なモノリス/大きな泥団子
  • 解決アプローチ
    • 関心の分離
    • 部品化
    • モジュール化
      • 交換容易性
      • 交換するかは置いておいてできる状態になってるのがいい状態
  • 基本となる技法
    • モジュラー性
      • モデル(要約)
      • カプセル化(自立性)
      • 直接的な写像(分かりやすい構造)
      • 仕様(意図の伝達)

モジュール設計スタイル

  • モジュールの設計スタイルの分類
    • 抽象化の方向
      • 機能/データ
    • 用途
      • インバウンド/アウトバウンド/演算
    • 状態の扱い
      • 可変/不変
    • システム構築の原理
      • ブレークダウン/ビルドアップ
  • オブジェクト指向の設計スタイル
    • データ/演算/不変/ビルドアップ
    • クラスとメソッドで演算ロジックをモジュール化
  • ドメイン駆動設計の設計スタイル
    • データ/演算/不変/ビルドアップ
    • 複雑な業務ロジックに焦点を合わせる

アプリケーション全体のモジュール構成

  • ポート&アダプターの設計スタイル
    • コア
      • 業務ロジック(データ/演算/不変/ビルドアップ)
      • アプリケーション(データ/演算/可変/ブレークダウン)
    • アダプター
      • プライマリ(機能/インバウンド/可変/ビルドアップ)
      • セカンダリ(機能/アウトバウンド/可変/ビルドアップ)
  • コアの分析設計に投資する
  • コアの実装
    • 高密度/強度/交換容易性
  • アダプターの実装

モデル駆動設計

全体

  • 事業活動モデル/基本設計
    • 事業活動を最適化するのが目的
    • いろいろな制約の中で何が貢献できるか

コア

  • 業務ロジックモデル/ドメインモデルのクラス設計
  • 業務機能モデル/アプリケーションサービスのクラス設計

アダプター

オブジェクト指向は必要なのか

初心者にとってのオブジェクト指向

  • 初心者が目指すべきものみたいになってる
    • 初心者にとってはすぐに学ばなくて良いもの
  • オブジェクト指向という言葉が曖昧
    • その中の要素を別の名前として定義した方が良い

オブジェクト指向の定義

抽象データ型

  • データの操作だけを公開することで変更に強く柔軟
  • データのカプセル化

オブジェクト指向と関数型D

  • 区分けに意味はない
  • オブジェクトと関数は可換

デザインパターン

  • デザインパターンは言語に足りない機能の補完
    • 多くのパターンが言語の機能導入で不要になっている

オブジェクト指向の使い所

  • オブジェクト指向は状態管理技術
    • I/O
    • List
  • 状態管理はモジュールの協会に現れる
    • DOM/HTTP/DB接続