PHP
BEAR.Sunday

PHPコーディングポリシー


コーディングポリシー

以下はBEAR.Sundayフレームワーク開発でのコーディング原則をまとめたものです。


ゴール


  • クリーン

  • ハイパフォーマンス

  • No BC break

(柔軟性や拡張性、テスト可能性などは"クリーン"であれば自然に含まれます)


グローバル


  • グローバル定数(define)の禁止

  • スーパーグローバル変数の参照の禁止

  • グローバルなサービスロケータの参照の禁止

  • グローバルな設定の参照の禁止(prod/devモードなど)

  • グローバルなプロパティ参照の禁止(スタティックプロパティ)

  • グローバルなメソッド利用の禁止(スタティックメソッド)


依存

 

* 基本全てDIで

* newの禁止 (バリューオブジェクトを除く)

* 実クラス名を使ったオブジェクトの取得(factoryメソッドなど)の禁止

* インターフェイスにないメソッドの利用の禁止

* 引数がオブジェクトでパブリックプロパティを使う場合、引数のタイプヒントはインターフェイス禁止。抽象クラスを使う。

* include_path依存の禁止

* 抽象クラス以外でのsetterインジェクションの原則禁止。

* composerで依存ライブラリの最小バージョンの指定のみを行う。特定のバージョンにロックしない。


継承


  • 実クラスの継承の禁止 (finalキーワード付加)

  • 子クラスから親クラスのメソッド利用の禁止

  • 抽象クラス以外でのprotectedプロパティの禁止。


トレイト


  • 原則禁止

  • アプリケーションでDIのセッターメソッドのみ


引数、返り値


  • 引数の数は4つまで(4も例外的)

  • 引数にbool値を使用することを禁止

  • スカラー値よりバリューオブジェクトを好む

  • 特定の構造を期待する連想配列を使わない

  • 返り値のmixedを避ける


  • nullのデフォルト引数を避ける

  • クロージャの引数を避ける


構造


シリアライズ


  • オブジェクトはシリアライズ可能に


メトリクス


  • 1つのクラスのメソッドの数は10以下

  • 1つのクラスのプロパティの数は15以下

  • 1メソッドの平均ライン数は10行以下

phpmdのデフォルトそのままです。


CI


OOP


  • setter、getterを使わない

  • デメテルの法則

  • 小さなクラスを好む。

  • 早期バリデーション、遅延評価

  • サービスにオブジェクトを渡さない。オブジェクトにサービスを渡す。 (XXManagerクラスの禁止)


  • DRYをあまり重視しすぎない。


原則


  • 小さく。迷ったら簡素な方を。

  • 言い訳はあとで。まずは取り組んでみる。

  • 守るのが難しく見える時、そもそも取り組み方がそれでいいのか再考する。

  • 速度を犠牲にする方向で解決することを避ける。


説明

いくつか解説します。


グローバルな設定の参照の禁止


ymlの設定ファイルを直接参照したり、Config(コンテナ)クラスを作ってその値をgetしたりしません。必要な値は依存として注入します。

$foo = Configure::read("foo") // NG

public function __construct($foo)

{
$this->foo = $foo; // OK
}


newの禁止


バリューオブジェクトなどは除きます。主にサービスオブジェクトの場合です。

$email = new Email('exmaple@example.com'); // OK

$http = new AnnotationReader() // NG


スーパーグローバル変数の直接参照の禁止


Foo::createFromGlobals(); //NG

Foo::create($GLOBALS) // OK

内部でスーパーグローバル変数を直接参照するのではなく依存として渡します。


elseの禁止


コンディションがboolの場合でelseの状態が1つに特定される場合は構いません。(=三項式はOK)

elseを文字通り「その他」として扱うようなelseを外します。(しかしその場合はガード節を使ってelseを簡単に外すことができます)


個別の意味をもたせた連想配列を引数で使わない


例えば引数にarray $locationと渡して$location['x']$location['y']と使用するのではなく$x, $yのpublicプロパティを持ったLocationクラスを用意します。


まとめ

様々なコーディングの原則は時に「現実的ではない」「PHP的ではない」と軽視されることがあります。しかし現在のPHPはこれらのOOP原則に従ったコーディングをする事は十分に可能です。クリーンなコードはむしろ簡素で、IDEやCIツールの利用で開発速度の犠牲も最初です。

クリーンなコードは開発速度やランタイムの実行速度とのトレードオフではないと考えます。

BEAR.Sundayが提供するのは、ライブラリの集合ではなく「フレームワーク」です。実装はその時その時に変化しますが、変わることのないHTTPアプリケーションの構造を継続的な進化と共に提供したいと考えています。ソフトウエアの設計原則に従う事はそのフレームワークを壊すことなく(後方互換性を犠牲にすることなく)進化を続けることを可能にするための土台です。


参考

https://github.com/jupeter/clean-code-php