Upgrade to Pro — share decks privately, control downloads, hide ads and more …

複雑性に立ち向かうためのサーバーサイドコード分割 / JJUG CCC 2023 Spring

複雑性に立ち向かうためのサーバーサイドコード分割 / JJUG CCC 2023 Spring

hirokuni-maeta

June 04, 2023
Tweet

Other Decks in Programming

Transcript

  1. 自己紹介 ▌前田 浩邦 / Hirokuni Maeta ▌2014年4月 サイボウズ入社 ▌kintone開発チーム /

    ソフトウェアエンジニア ▌バックエンドとフロントエンド ▌最近はkintoneのインフラ移行プロジェクトに参加 2
  2. コード分割で目指す構成 UpdateController GetController FieldService FieldRepository com.kintone.appsettings AppData FieldData CategoryData 共有するデータ

    ArchUnitで 依存を禁止 アプリ機能 アプリ設定機能 12 com.kintone.app RecordData RecordService RecordRepository GetRecordController
  3. コード分割で目指す構成 RecordData RecordService RecordRepository GetRecordController AppData FieldData CategoryData 共有するデータ ArchUnitで

    依存を禁止 UpdateController GetController FieldService FieldRepository com.kintone.appsettings com.kintone.app 機能の性質上関わらないならば、 コードでも関わらせない 13 アプリ機能 アプリ設定機能 機能に対応するパッケージを作成 機能に属する全コードをパッケージに配置
  4. コード分割で目指す構成 AppData FieldData CategoryData 共有するデータ ArchUnitで 依存を禁止 UpdateController GetController FieldService

    FieldRepository com.kintone.appsettings 機能間で共有が必要なデータ 現状は共有を許容 14 RecordData RecordService RecordRepository GetRecordController com.kintone.app アプリ機能 アプリ設定機能
  5. 分割前のAPIトークンの仕組み ApiTokenService - getToken - list() - update() ApiToken -

    long appId - bool canView, canAdd - String memo レコードを 取得する 設定を 変更する 28 APIトークンを表現する データクラス APIトークンに関する処理 を担当するサービスクラス アプリを 作る人 アプリを 使う人
  6. 分割前のAPIトークンの仕組み ApiTokenService - getToken - list() - update() ApiToken -

    long appId - bool canView, canAdd - String memo レコードを 取得する 29 listで設定を取得 updateで変更 アプリを 作る人 アプリを 使う人 設定を 変更する
  7. 分割前のAPIトークンの仕組み ApiTokenService - getToken - list() - update() ApiToken -

    long appId - bool canView, canAdd - String memo レコードを 取得する 30 getTokenで取得 canViewを確認 アプリを 作る人 アプリを 使う人 設定を 変更する
  8. このまま分割することは不可能 ApiTokenService - getToken() - list() - update() ApiToken -

    long appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings 31 getTokenのある appsettingsに依存 アプリを 作る人 アプリを 使う人 ArchUnitで 依存を禁止 設定を 変更する
  9. getTokenがappsettingsにあるのが変? ApiTokenService - getToken() - list() - update() ApiToken -

    long appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings 32 - list, update, ApiToken → 変更する際に利用される - getToken → 変更することとは関係ない アプリを作る人が設定を 変更する際に利用されるコード アプリを 作る人 アプリを 使う人 ArchUnitで 依存を禁止 設定を 変更する
  10. 分割後のAPIトークンの仕組み (サービス、データクラスを分割) ApiTokenService - list() - update() ApiToken - long

    appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings ApiTokenRightService - getToken() ApiTokenRight - long appId - bool canView, canAdd Impl 33 アプリを 作る人 アプリを 使う人 設定を 変更する
  11. Dependency Injectionによって実装への依存を避ける ApiTokenService - list() - update() ApiToken - long

    appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings ApiTokenRightService - getToken() ApiTokenRight - long appId - bool canView, canAdd Impl 34 DIを使うことで appsettingsへの依存を回避 アプリ設定のテーブルを参照 するため、appsettings内 アプリを 作る人 アプリを 使う人 設定を 変更する
  12. データクラスの可読性の向上 35 ApiTokenService - list() - update() ApiToken - long

    appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings ApiTokenRightService - getToken() ApiTokenRight - long appId - bool canView, canAdd Impl アプリを作る人向けの変更 がしやすくなった (memoの追加など) 不要なプロパティに依存 しなくなった アプリを 作る人 アプリを 使う人 設定を 変更する
  13. サービスクラスの可読性の向上 36 ApiTokenService - list() - update() ApiToken - long

    appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings ApiTokenRightService - getToken() ApiTokenRight - long appId - bool canView, canAdd Impl アプリを 作る人 アプリを 使う人 機能と実装の対応が取れている - できること → ApiTokenService - 設定の表示 → #list - 設定の変更 → #update 設定を 変更する
  14. サービスクラスの可読性の向上 37 ApiTokenService - list() - update() ApiToken - long

    appId - bool canView, canAdd - String memo レコードを 取得する com.kintone.appsettings ApiTokenRightService - getToken() ApiTokenRight - long appId - bool canView, canAdd Impl getTokenとlistが分かれた - 同じApiTokenを返しているので、共通化できそう にすら思える - 事前のアクセス権チェックの有無などが違うため、 実は大きく異なる アプリを 作る人 アプリを 使う人 設定を 変更する
  15. コードを複雑にしていたもの ▌使う側と作る側で同じサービスクラス、データクラスを使用していたこと ▌APIトークン以外でも同様の現象が見られた ApiTokenService - getToken - list() - update()

    ApiToken - long appId - bool canView, canAdd - String memo レコードを 取得する 作る人のための情報、 使う人には不要 実行するのが使う人か作る人かで、 必要な処理や情報が異なる → serviceの実装がちぐはぐに見える 38 アプリを 作る人 アプリを 使う人 設定を 変更する