2021年5月10日月曜日

今更ながら DDD について考えてみた

今更ながら DDD について考えてみた

2003 年ごろに提唱された DDD がなぜか今盛り上がっている気がするので今更ながら DDD (Domain Driven Development) について考えてみました
なお原著であるエリック・エヴァンスのドメイン駆動設計は読んでいません
完全に個人的な主観で記載しているので解釈の間違い等はご容赦ください
また DDD のすべてに触れているわけではないのでそれもご容赦ください
文字が多いです

あくまでも「設計手法」であることを忘れてはいけない

いざ実装となるとそのプロダクトの性質や方向性が実装に大きく影響します
それに対して絶対 DDD を適用することは難しいと思っています

設計手法=数ある解決手段の中の一つにしかすぎないと思っています
何でもかんでも DDD を使うのは良くないと思うのでプロダクトのこの部分は適用できそうだとかここは難しいという判断が重要だと思います

DDD は完璧な銀の弾丸ではないかなと思います
もちろんトライすることは良いことだと思います

オブジェクト指向の拡張

に近いかなと個人的には思っています
オブジェクト指向のクラス=ドメインモデルになるケースは結構あるかなと思っています

ただ大きく違うのは粒度と性質かなと思っておりドメインモデルは「値オブジェクト」や「エンティティ」という表現を使っておりオブジェクト指向で言うところのフィールドが Immutable であるかどうかなどを決める必要があります
また振る舞いは「ドメインサービス」として別クラスに書いたりします

オブジェクト指向でもそのようなことはできますが基本的にはフィールドの Settter さえあれば値は変更できます
振る舞いに関しても同じクラスに書くことが多いと思います

また自分がオブジェクトの拡張だと思う理由のもう一つとしては DDD のサンプルをいろいろ調べると大抵のケースでクラスを使っています
当然クラスを使わないで DDD するのは不可能ですがクラスが使える言語は大抵オブジェクト指向な言語で書くことが可能な言語であることが多いのでそう感じているのかもしれないです

オブジェクト指向をしっかり使えていれば実は勝手に DDD っぽく書けているケースがあるかも?

ドメインモデルをどこまで抽出するか

例えば以下のようなコードがあるとします
何らおかしなところはないユーザを管理するクラスです

class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  attr_accessor :name, :age
end

ですが DDD 的には以下のように値オブジェクトとして name と age をドメインモデルとして抽出します

class UserName
  def initialize(value)
    @value = value
  end

  attr_reader :value
end

class UserAge
  def initialize(value)
    @value = value
  end

  attr_reader :value
end

class User
  def initialize(name, age)
    @name = name
    @age = age
  end

  attr_accessor :name, :age
end

UserName や UserAge クラスを新たにドメインモデルとして抽出しています
DDD 的にはこうすることでユーザ名や年齢のバリデーションを各クラスに持たせることがよしとされています (値オブジェクト)

かなり極端な例ですが個人的にはオーバーエンジニアリングな感じがあります
このようにどこまでをドメインモデル (クラス) として抽出するかの判断が非常に難しいと思っています

一応判断基準はあるのですが正直「経験」というか「感覚」が物を言う世界かなと思っています
やりすぎも良くないと思うのでいい塩梅のモデリングレベルが要求されるのでそれだけでもかなりの学習コストがあるのかなと感じます

フレームワークの流儀に従うかどうか

Web アプリなどを開発する場合は基本的には Web フレームワークを使うかなと思います
自分であればよく Sinatra という Ruby 製の軽量フレームワークを使います
また Ruby には有名な Rails というフレームワークもあります

基本的にはどちらも MVC を使って開発することがほぼんどです
そういったフレームワークが提供する機能というか書き方がある程度整っている状態で DDD を採用しようとすると MVC に対して無理やり DDD を適用するようなことが発生します

もちろん適用することは可能です
ルーティングの部分はそのままでモデルの部分だけを DDD っぽく書くなんてことはできるかなと思います
ただ Rails を使う場合には active_record と Model の関係がかなり密接に絡んでおり無理に Model を書き換えて DDD を適用しようとすると大変なことになりそうな気がしています (やったことはないのであくまでも予想です)

フレームワークにはそれなりの流儀というか書き方のルールがあるかなと思っています
個人的にはまずはそれを優先するべきかなと考えています
その上で一部のロジックを DDD にするというのはありなのかなーという気はしていますが、いろいろと設計思想が混同したコードはあまり良い方向にいかないような気もしています

DDD の知識がないとコードの可読性は落ちるかも

単純なことですが DDD にはある程度書き方やルールが決まっているのでそれを知らないでコードを読んでも逆に読みづらいのかなという気がしています

値オブジェクトやエンティティに関しては「なんでこんなに細かく抽象化しているのだろうか」とか感じたりするかもしれません
ドメインサービスに関しては「なんでこれはわざわざ別クラスとして切り出しているのだろう」と感じたりするかもしれません

しかもそのルールを知らないと実際にメンテナンスするときに振る舞いをドメインモデル側に記載したりしてしまうかもしれません

もちろんレビューしたり学習したり回避方法はいくらでもありますが完全に初見でコードをみたときに「あ、これは DDD だな」と気づく人は少ないんじゃないかなと思います

DDD で高メンテナンス性は担保できるのか

ドメインモデルを適切に抽出できていればモデルのクラスを見ただけで確かにコードを理解できるかもしれません

しかしそれだけではそのコードをメンテナンスすることはできません
あくまでもコードを修正してテストしてバグを修正できて初めてメンテナンスできるようになると思います

修正箇所を小さく局所的にすること=高メンテンス性なコードであるとは思います
しかしあくまでも修正できるかどうかはある程度の経験が必要だと思います
ここで言う経験は「コードのビルド」すなわちトライアンドエラーすることであると考えておりそれは CI/CD などで担保するものかなと思っています

要するに DDD だけでメンテナンスしやすいコードにするのは難しいのでちゃんと初心者がトライアンドエラーしやすい環境を作っておくことも重要だと言うことです

言語との相性

冒頭でも記載していますが個人的にはオブジェクト指向の拡張かなと思っています
なのでオブジェクト指向ができる言語とは相性が良いと思っています

もう少しいうとゴリゴリの型付け言語のほうが相性が良いかなと思っています (DDD の紹介書籍などを見るとそう感じると思います、たぶん)

具体的には C# や Java などが相性が良いかなと思っています
もちろん Ruby や Python、Swift などの高級言語でも可能だとは思います
ただ Python などはオブジェクト指向から外れたスクリプトみたいな書き方も簡単に含められるので、そういう便利機能というか DDD っぽくない書き方が含まれていると可読性などは落ちるのかなという気もしています

JavaScript とかでもやっているのをちらほら見ますが、まぁどうなんでしょうか、、?
(nodejs ならできるのかな?できないということはないと思うが)

ドメインモデルのスコープをどうするか

基本的にはクライアントから操作できるのはアプリケーションサービスのみです
しかし言語の仕様や実装上の namespace の問題でドメインモデルにアクセスできることはできてしまいます

代替手段はいろいろとありますが本来は機能として触れないようにするべきです (例えば外部に公開しないドメインモデルには private 修飾子を設定するなど)
しかしどうしてもできないこともあるはずです
そういった場合に「ルール」を作るのですがあくまでもルールでありやろうと思えばドメインモデルを直接使うことができてしまいます

個人的にはこのスコープを問題は大したことではないと思うのですが考える必要がある点に注意が必要です
なるべく Getter を作らないという考えも同じようなことだと思います

インターフェース

主にアプリケーションサービスとリポジトリでインターフェースなどで使うことになると思うのですがインターフェースが言語の機能としてない場合があるのでその場合にどうするか考える必要があるかなと思います

ガッツリ設計するような開発手法にはあっているかも

例えばウォーターフローモデルのような開発には向いているかもしれません
DDD は設計の段階でかなり時間を割くイメージがあり、かっちり決めてから開発することになると思うのでアジャイルやプロトタイピングのように書きながらとなると、それなりの DDD の経験と知識がないと難しいかもしれません

その他要素 (集約、委譲 (DI)、トランザクション、アーキテクチャなど) について

結局考える必要が出てくるので学習しておく必要があります
学習しておかなくても最悪良いのですが知っていたほうがいろいろと便利だし DDD の原則に従うことができます

特にアーキテクチャそれだけかなりの学習コストがあるので大変です

最後に

用法用量を守って正しくお使いください
あとは書籍や Web の紹介を読んだだけだと理解できないので実際に自分で手を動かしてコーティングしてみることをオススメします

用語集

  • ドメインモデル
  • ドメインオブジェクト
    • 値オブジェクト
    • エンティティ
  • ドメインサービス
    • 評価 (Specification)
  • リポジトリ (インタフェース)
    • クエリサービス
  • アプリケーションサービス (インタフェース)
  • 集約 (ルール)
  • アーキテクチャ
    • レイヤード
    • ヘキサゴナル
    • クリーン

2021年5月9日日曜日

ウマ娘プレイメモ&感想

ウマ娘プレイメモ&感想

巷で話題のウマ娘を 3 ヶ月ほどプレイしてみました
Podcast ep45 でも少し話しています

結論

  • よく作り込まれているゲームだと感じた (グラフィックやレースの順位計算など)
  • 単純におもろしろい、ひまつぶしにも良い
  • ガチ勢には勝てない

プレイスタイル

  • 無課金
  • ログインは毎日する
  • 育成やレースは気分で消化する
  • まったり

システムが結構複雑

よく言われるのはパワプロ+ダービースタリオンのようです
育成しながら対人の勝負をする感じです

ゲームシステム的にブラックボックスな部分が多いなと感じました
例えばレースの順位決めやスキルの発動条件などです
理解するまでは結構時間がかかった気がします
理解すればゲームもサクサク進めまれます

またアイテムの数も多く使いこなすのが難しかった印象です

結局ランキングで上位になるために育成するゲーム

RPG ではないのでエンドコンテンツ的なのはなさそうです
超高難易度レースが最終ステージになっておりそれがエンドコンテンツというわけでもなさそうです

あくまでも対人勝負で上位のランキングを目指すのがメインの目的になりそうです

因子ゲー

ゲームの重要な要素に「因子」という要素があります
ここでは詳しく説明しませんがこの因子を作成するのが大変です
しかも強い因子がないと強いウマも育成できないのでこの因子を集めるということが非常に重要な要素になっているなと感じました

自分は SS+ 2面待ちで周回しています

オール B 育成はかなり難しい印象です
自分はメジロマックイーンやシンボリルドルフの場合は根性以外の 4B を目指して育成しました

ちなみに自分が出した青星3 因子は 4/ 体です

1.7% の確率で出現しています

サポートカード

これも育成の重要な要素です
基本はガチャで手に入れます
因子と合わせて強いステータスのウマを育成するには強いサポートカードが必須です
このゲームの良いところは SR のサポートカードでも限界突破させれば優秀なサポートカードになるということです

SSR は 3% でしか手に入れないのでなかなか限界突破できません

金欠になりやすいかも

お金の概念があるのですがこれが結構なくなりがちでした
サポートカードのレベル上げや覚醒レベルの上昇などお金を使う場面が多いです
自分の主な収入源はデイリーレースだけでした
育成周回でもお金稼ぎはできるらしいのですが自分はやりませんでした

レースやライブは一切見なかった

イベントの会話も全部最速スキップしていました
アニメにもなっているのでそれを見てからプレイするともっと楽しめるかもしれません

育成について

育成時に重要だと感じた点を列挙します

  • 因子は可能な限り青因子3を持つ親から継承する
  • サポートカードは無理に SSR ではなく SR で良い
  • 絶好調は維持
  • イベントの内容を覚えることは重要
    • 体力を回復するイベント
    • やる気を上げるイベント
    • 状態を変化させるイベント (練習上手、愛嬌など)
  • 運も絡む
    • やる気を問答無用で下げるイベント
    • 得意率など

保持育成ウマ

SSR は 3 種類しかありません

保持サポートカード

SSR は 16 種類でうち 8 種類は 1 凸以上しています

SR は 27 種類あります
ほぼすべてで 1 凸以上しています

最後に

今度どれくらいまでインフレするのかが楽しみです