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

自分たちのコードを Composer パッケージに分割して開発する

自分たちのコードを Composer パッケージに分割して開発する

PHP カンファレンス沖縄 2021

Shohei Okada

May 29, 2021
Tweet

More Decks by Shohei Okada

Other Decks in Programming

Transcript

  1. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ...
  2. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ...
  3. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ...
  4. ローカルのディレクトリを Composer パッケージとして扱う
 { ... "repositories": [ { "type": "path",

    "url": "../../packages/my-package" } ], ... } ... ├── apps │ └── my-app │ └── composer.json ├── packages │ └── my-package │ └── composer.json ...
  5. ローカルのディレクトリを Composer パッケージとして扱う
 { ... "repositories": [ { "type": "path",

    "url": "../../packages/my-package" } ], ... } ... ├── apps │ └── my-app │ └── composer.json ├── packages │ └── my-package │ └── composer.json ...
  6. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ... $ composer require "my/package:*@dev"
  7. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ... $ composer require "my/package:*@dev" "name": "my/package"
  8. ローカルのディレクトリを Composer パッケージとして扱う
 ... ├── apps │ └── my-app │

    └── composer.json ├── packages │ └── my-package │ └── composer.json ... apps/my-app/vendor/my/package から 
 packages/my-package へとシンボリックリンクが張られる 
 
 → Composer の autoload 機能を経由して 
   my-app から my-package を利用できるようになる 

  9. Laravel におけるディレクトリ構造の例
 ├── app │ ├── ... ... ├── composer.json

    ... ├── app │ ├── ... ... ├── packages │ └── my-package │ └── composer.json ... ├── composer.json ... ※ “my-package” はあくまで例なので、 
  適切な名前をつけてあげてください。 

  10. 
 
 
 
 
 
 
 
 
 


    後藤知宏, “Laravel Package Development”, Laravel JP Conference 2019, https://speakerdeck.com/mikakane/laravel-package-development
 
 参考資料

  11. Laravel の例を挙げれば
 • Illuminate に依存しない(use したり、完全修飾名で利用しない)
 ◦ extends、implements、引数、戻り値に出てこない
 • グローバルヘルパ関数や

    Class Alias(\Log とか)を使わない
 
 これらを取り除いて残るのは、自ずと「自分たち」固有のコードになるはず
 
 ※ここでいう「自分たち」とはサービスやビジネス
 フレームワークに依存していない状態

  12. 
 
 
 
 
 
 
 
 
 


    @77web, “そのコード、フレームワークの外でも動きますか?”, PHPerKaigi20201, https://speakerdeck.com/77web/sofalsekodo-huremuwakufalsewai-demodong-kimasuka 
 
 参考資料

  13. 
 
 
 
 
 
 
 
 
 


    @sonatard, “オブジェクト指向その前に凝集度と結合度”, Object Oriented Conference 2020, https://speakerdeck.com/sonatard/coheision-coupling
 
 参考資料

  14. 型情報の上でフレームワークに依存しなくなっても
 「見えない依存関係」が存在しているケースがある
 • 型宣言がない箇所で、フレームワーク固有のクラスを想定している
 • 関数の呼び出しに暗黙の前提条件が存在している
 • 型は int や

    string だが、その値の意味がフレームワークに特化している
 ◦ 例)フレームワークで使われるクラス名の文字列
 
 このような実装は「結合度が高い」と言える
 →そのクラスや関数を使うのに、型から得られる情報以上の知識が
  必要になってないかを意識する
 見えない依存関係

  15. パッケージに切り出す(モジュール化する)こと
 = インターフェースをデザインすること
 
 ポイントは
 • (特にフレームワークとの)依存関係
 • 凝集度と結合度
 


    →いきなり「自分たちのコード」を網羅的に切り出すのは難しい
  まず、1 つの関数だけでいいので切り出してみよう
 どうやって分割していくか?(再掲)

  16. ルートパッケージの vendor ディレクトリ内に全ての依存関係が
 フラットに集約されるため、例えば次のような場合もエラーにならない
 依存関係を厳密にチェックできるわけではない
 ルートパッケージ パッケージ A パッケージ B

    ルートパッケージ パッケージ A パッケージ B ▪ composer.json に定義した依存関係
 ▪本来依存していないパッケージにアクセスできてしまう
 パッケージ B からパッケージ A のコードを利用

  17. 私はやったことはないが、想定できるのは
 🙆 分離することで CI のサイクルが早くなる
 🙆 共通のコードを複数のプロジェクトから使える
 🙅 運用やデプロイ(ローカル開発環境含む)が複雑になる
 🙅

    インターフェースの決定や変更について取り決めが必要になる
 
 相当の規模の開発でないか、運用上のノウハウが無い限り
 デメリットの方が大きい気がする(経験・知見のある方の意見求ム)
 パッケージごとに Git リポジトリを別にすべきか?