この記事はcloudpackあら便利カレンダーの9日目の記事です。
先日行われたPHPカンファレンス福岡2017に参加してきましたので、
参加メモですがここに残します。
PHP7で堅牢なコードを書く
DB情報が変更されるとエラーでるよね
不具合の発見が遅れれば遅れるほど傷は深くなる
- 要件定義の段階で発見できれば傷は浅い
予防的プログラミング
-
間違った予防法
is_null() やら is_array() やら array_key_exists() やら -
正しい予防法
インタフェース設計をする: 誤った使い方をすることが困難
== そもそも間違った使い方ができない
タイプヒントで int
string
で縛ればそもそも is_int() とかは不要
Enumつかってとりうる値を制御するのもアリ
PHPで列挙型を作る@hiraku
- 責務を増やしすぎない
- DIで責務をバランシングする
- 作る人: new PDO()
- 設計する人: DI
- 利用する人: $pdo->execute()
予防にまさる防御なし
攻撃的プラグラミング
fail fast
早めにクラッシュさせること
疑いがあればすぐに停止させるべき
正当性と堅牢性
- 正当性
不正確な結果を返すくらいなら何も返さない方がマシ
個々のクラスで担保 - 堅牢性
多少なんかあってもソフトウェアの実行が継続するようにする
アーキ・FWで担保
戻り値ではなく例外を使う
PDO::ERRMODE_EXCEPTION
: 何かしくるとErrorになる(その前はWarningくらい)
表明プログラミング
怒るはずがない
をコードで表す == assertion
assert(評価式)
このままだと警告出すだけで落ちない
php.iniで assert.exception = 1
によって表明違反でおちる is 最高
zend.assertions
で実行時の挙動を変更できる
暗黙の前提を明示的なコードにすることで読み手が理解しやすくなる
例外と表明の使い分け
例外は起こり得るものに
表明は起こり得ないものに
それぞれつかう
契約プログラミング
誰の責務化はっきりさせる契約による設計
- 事前条件違反は呼び出し側に問題がある
- 事後条件違反は供給者側に問題がある
AssertionError/LogicExceptionはcatchするのはまちがい
はやめに落としてなおしにいくべき
Exceptionの第三引数はstacktraceをつなげる役目がある
try{
} catch (\PDOException $e) {
throw new LogicException($e->getMessage(), $e->getCode(), $e);
}
ADR
Request -> BusinessLogic -> View
MVCとほぼおなじ
Controller <-> Action
Model <-> Domain
View <-> Responder
Action
- レスポンスを返却する責務がない
- 1つのClassで1つのリクエストを担当(GETならGETのClassを作る)
- Domain と Responderを接続する
- Closureや__invoke()で実行すべき
- Middlewareでよくつかう手法
Domain
- DDDのDomainを例に解説
Responder
- Actionに対するResponderを個別に用意
- ヘッダの設定とかも
- テンプレートを組み込んでもおk
ADRは何を目指すか
小さく、最小単位に
単一責任の原則
依存を逆転してもアプリケーションは動かないといけない
サービス要件とシステム要件をちゃんとわけて考えられているか
Specification Pattern
- 仕様パターン
このRepositoryには何を与えればいいかを定義
Domain Service Class
- バルク時の割引はEntityで表現できないよね〜みたいなときにつかう
1Action, 1Domain
1,800Req/s
就職活動支援系アプリのAPIの話
-
構成
- EC2: m4.xlarge x 2
- RDS: m3.xlarge
-
ミドルウェア
- Ubuntu
- PHP
- cakephp
- apache
- 負荷を想定
- 仮構成を作成
- 負荷試験 + 調整
- やばかったら?
- EC2はスケールアウトで対応
- DBはスケールアップ
PV -> APIコールの変換
- ユーザシナリオ
- シナリオの各ステップでのAPIコールをリストアップ
- その時のPVとAPIコールの比率をとる
3000PV/sec -> 1800call/sec
負荷テストで死んだ
APIコールのシナリオを見直す
- 静的化できるもの(config系)は積極的にキャッシュ: PHPを使わずApacheだけで完結させる
- m4.4xlarge x 16台構成に変更
本番稼働
- APIの静的化でDBコネクションの張り付きを逃れる
PHP-ML
いろんなアルゴリズムが実装されてる
でも対応状況はまだまだ
Pythonでは
- scikit-learn
- madplot-libで描画してる
機械学習
各種紹介にとどまる