---
# System prepended metadata

title: 2021/07/11 メンター相談
tags: [7月, メンター相談]

---

# 2021/07/11 メンター相談

###### tags: `メンター相談`,`7月`

## 凝集度や結合度などSOLID原則周りに関することを、チームみんなで意識する機会は設けているでしょうか？

- その場合、どういった場で意識するのでしょうか？
- SOLID原則などは個人で意識はしていても何かルール化されているわけではないな、、という話が出ました
- Prahaさんの場合、毎週金曜をリファクタリングdayにしていたプロジェクトなどもあるとのお話でしたが、そういった際に意識するのでしょうか？

---

- 改めて伝える機会は設けていない
- 金曜のリファクタリングはペアに分かれて行っていた
    - どっちかが持っている知識をもう片方に伝達
    - 設計の話を共有できる
- プロジェクトの始まりはモブプロをする
    - その際に設計の話を固める
- PrahaChallengeに社員がこっそり参加
    - 課題を通して知ってもらう
- 毎週勉強会をやっている
    - DDD
    - 関数型プログラミング (elm)
        - エラーメッセージが丁寧
        - バージョンを上げやすい
            - npm (セマンティックバージョニング)は、開発者次第
            - elmはインターフェースを見て、バージョンを強制するので、安心
- 勉強にかかる費用は会社負担
    - 勉強会
    - 輪読会
    - 有識者を呼ぶ
- Slackで知見を共有

## 課題「オニオンアーキテクチャを学ぶ」の特定のユーザーへのアクセス制御をどの層で行うべきかの質問です。

ペアで話した結果、以下の2パターンの意見が出ました。

- プレゼンテーション層で行う
    - 権限がないので、不正なリクエストをアプリケーション内部に取り込みたくない。一番外側の層で管理することで、エンドポイント毎に権限を分けるときに管理しやすいと思った。
- ユースケース層で行う
    - そのユーザーが権限を持つかどうかはDBに保存されたユーザーのデータを確認する必要があるため、インフラ層の処理が呼び出されるならユースケース層でチェックを行い、必要があればドメインのルールとして定義した方が良いと思った。

---

- 特によく議論になる
- 松岡さんのgituhbより
    - ドメイン層に「ログインユーザー」のインターフェースを置く
    - 実装クラスをPR層に置く (認証の仕組みはPR層に置く)
    - ドメイン層・ユースケース層がその情報を受け取って権限チェックを行う
    - [権限管理をどうdddと絡めるかという質問失礼します。権限には... · Issue #252 · little-hands/ddd-q-and-a](https://github.com/little-hands/ddd-q-and-a/issues/252)
    - [Slackのようなアプリケーションを作る際に、オーナー権限... · Issue #220 · little-hands/ddd-q-and-a](https://github.com/little-hands/ddd-q-and-a/issues/220)
- SpringSecurityのアノテーションとも似ているかも？
- 認証はPR層で行う
    - 認可に必要な情報をとってくる
    - ログインユーザーかどうか
    - ユースケースはログインユーザーをドメインサービスに渡す
- 認可はドメインサービスで行う
    - 例: User.isAdmin かどうか

## 普段、ユースケース層はどのくらいの粒度で作成することが多いでしょうか？

- 1つのエンドポイントでユーザーを作成し、作成したユーザーにメールを送りたいという仕様
    - それぞれクラスを分けますか？
    - それともエンドポイント毎に1つのユースケースクラスを作りますか？

---

- 1フロー毎にユースケースを作る (『実践ドメイン駆動設計』より)
    - >「アプリケーションサービスの責務はユースケースのフローにおけるタスクの調整でありフローごとに一つのメソッドが存在する」
    - フロー (ユーザーの操作する一連の流れ)
    - 1フロー・1ユースケース・1PublicMethod

    例）
    | ユースケース | フロー |
    |:-:|:-:|
    |銀行に振り込む |　残高確認　→　銀行に振り込む|

- 分岐はコントローラーではなくユースケース内で行う
    - コントローラー層をなるべくシンプルにしたいので (テストが難しい/書きたくない)

## 今までの業務の中で境界づけられたコンテキストによって用語を分けた事例などがありましたら教えていただきたいです。

- まだ経験がない
    - ただし、ログインユーザー、GitHubユーザーを作ったことはある
- M&Aサービス (売りてと買い手がいる) ではわけるかも？

## 高速にコーディングするために役立っているおすすめのプラグインなどがありましたら、ぜひ教えていただきたいです。

よく使うショートカットキーもありましたら、教えていただきたいです。

- あんまりVSCodeの拡張機能は入れていないかも
    - GitLens
        - 誰がこの実装を書いたのかすぐわかる
- snippetをよく作る
    - 競プロ用 (最大公約数、全探索など、、)
    - 新しいReactコンポーネントを作るとき用
    - テストケース作成用
- VSCodeショートカットキー
    - (キーは自由に設定できるので人によって違うかも)
    - サイドバーの開閉 (cmd B)
    - ターミナル開く (cmd J)
- github CLI
    - ブラウザを開くことなくプルリクエストを作成
- MACのショートカット
    - ウィンドウを別のデスクトップに移す (cmd option 1)
    - ウィンドウの位置を調整
- Alfred 便利
    - コピーの履歴
    - スニペット
        - ダミーテキスト ([lorem ipsum](https://ja.wikipedia.org/wiki/Lorem_ipsum))
        - メンバーへのメンション
        - メールの定型文 (この度はご連絡ありがとうございます など)
    - spotlightを編集できる
        - `p 松原` (prahaのドライブ内で松原を検索)
- vim
    - vim無しでは生きていけない
    - 速い
- vimium
    - ブラウザ操作をvimのコマンドで行うchrome拡張機能
    - マウスを触らずに操作できるのが良い
    - 画面内のリンクにキーボードだけで移動できる

## 小さい集約のデメリットとは？

大きすぎる集約には集約ルートやリポジトリの肥大化や、ロックを取る範囲が大きくなりすぎてしまうという問題があるので、

- なるべく集約は小さくするほうが良いという認識であっていますか？
- 逆に集約小さくすることのデメリットはありますか？

---

- 整合性を取りづらい
    - 集約間の整合性担保が難しくなる
    - ユースケースでまとめる (パフォーマンスに難あり)
        - １フローに対し、トランザクション範囲が広いので、アプリが遅くなる？
    - 結果整合性の実装は面倒
- 集約はなるべく小さい方がよいか？
    - バランスとユースケース次第
    - 絶対に壊れてほしくない整合性は同じ集約にする
- 集約は経験と感覚・・・！

## 「層をまたいで依存関係が発生するときはInterfaceを使おう」に関して

Interfaceを利用するケースとして、依存性の逆転以外でパッと思い浮かびません。
DDDは内側への依存は許可している認識なのですが、
Presentation->Usecase, Usecase->Domain への依存に対してもInterfaceを採用するのでしょうか？

「依存の方向は、より安定した方向に向かわなければならない」ことのメリットなどは理解しているのですが、
個人的にはPresentation->Usecase, Usecase->Domain への依存に対してInterfaceを用いるのはやりすぎかなと思いました。
この点に関して、教えていただければと思います

---

- 2層以上下のものを使うときに依存性の逆転で使用する (インターフェースを挟む)
- インターフェースの利点
    - 変更に強くなる (インターフェースがクッションになる)
        - インターフェイスを実装する事により、実装クラスのメソッド名を変更時、エラーが出る
    - 挙動を一部隠蔽できる
        - 実装クラスが呼び出すメソッドを制限できる
    - 詳しくは記事を参照
        - https://qiita.com/yutorisan/items/d28386f168f2f3ab166d
- prahaでは依存性の逆転くらいにしかつかっていないかも

## 共通の「課題」に担当者idをもたせることの是非について

PrahaChallengeのようなみんなで共通の課題に取り組むという仕様の場合、課題モデルに「担当者id」を持たせることに違和感を感じます。共通の課題というのは、あくまでもデータ上での都合のため、あまり気にしなくても問題ないのでしょうか？

- テーブル設計では、多対多テーブルにする
- テーブルスキーマとモデルの不一致は問題ない
    - 起こりうる
- 例: 社員を管理するアプリケーション
    - 社員モデルはステータスを持つ
    - 社員 - 中間テーブル - ステータス (社員はステータスフィールドを持たない)
- リポジトリでデータモデルをドメインモデルに変換する処理を入れる
    - データベースからのデータをドメインに詰め替えるようなメソッド（コンストラクターを使用した）を実装
- ドメインエンティティのコンストラクタをprivateにする
    - create ← 新規作成用
    - rebuildFromRepository ← リポジトリからしか呼ばないようにする
        - ↑ eslintのプラグインでできるようになった

## その他

- エンティティの識別子はDBのテーブルの主キーと一致させる？
    - 基本は一致させることが多い
    - 一致しなくても良いが、特定できなくなる
- 依存性の注入は誤訳
    - 正しくは依存オブジェクトの注入
