あいさつ
みなさんこんにちは! この喜びに満ちた、かなり暖かい金曜日に、(より楽しいバージョンで引用するために)私に直接会った。 正直なところ、このアクションは非常に頻繁に発生しますが、通常どおり、感覚が原因です。
なんてバカなんだ
今回は少し違った感覚で訪れましたが、確信したように、私だけではありません。 この気持ちは、インタビューの1つを思い出しました。「デコレーター」パターンのスケルトンを書くように頼まれました。これは、インタビュアーの個人的な考え方が古典的な解釈とはまったく異なることが判明しました。
読者の脳を「認知的不協和音」に失望させないようにするために、この記事ではこの
会社の 「仮説的」インタビューについて説明することを明確にします。したがって、「戦略」パターンについて話すように求められた場合 前のケースのように、私の回答はインタビュアーの目には少なくとも疑わしく見えたでしょう。
覗かないで
知識の電子倉庫には、C ++の例が記載された完全な記事「Strategy Design Template」があり、GoFの本と既知のすべてのプログラミング言語(そして突然、難解な言語を含む)から引用されていることがわかっているので、私の仕事は:同様の例を
記事からパターンの概念に詰め込みます。 何をする必要があり、何が起こったのか見てみましょう。
見た、修羅、見た
私の意見では、特定の種類のクラスを操作するのは良くありません。この場合
、クラス
インターフェースに関する知識だけでなく、多くの追加メソッド(多くの場合open ===
public )を通常含む
実装についても知って
います 。 代わりに、
インターフェイスベースのアプローチが提案されているため、例をリファクタリングする最初のステップはそれらを強調することです。
interface IValidator { function isValid($validatorParam); }
少しリラックスできるようにしたので、コードには最小限のコメントが含まれます(実際、IDEのコードには最小限のコメントが含まれています)。 合計:渡された引数について有効性判定を発行できるエンティティ。 この場所で、あなたのように、それは私を歪め始めることを書く価値があります:
- 引数の数は厳密に固定されています(配列変数はメソッドではありません)
- 上記の問題は、関数をオーバーロードしても解決できません(はい、C ++はPHPを...と見なします)
- 引数の型は未定義です(多くのPHPプログラマーにとってこれは問題ではありませんが)
しかし、私は息を吐き(空気だけ)、制限に耐えて、書き続けます。 パターンの名前に基づいて、さまざまなケース(またはユースケース)に異なる
戦略を適用するためのメカニズム(または
機会 )が必要です。たとえば、コンパイル段階だけでなく、外部要因にも依存します。 正式な形式では、私たちの欲求は次のようになります。
function Validate(IValidator $validateStrategy, $param) { return $validateStrategy->isValid($param); }
そして、たとえば、ユーザー名は次のようになります。
function ValidateName($userName) { return Validate(new NameValidator(), $userName);
「同意します」あなたの目に見えない質問に、熱心な読者に答えます:
コンストラクターが呼び出されるたびに? シングルトンまたは静的関数変数はできませんか?
しかし、これらは次のリファクタリングの問題です。 例のサブジェクト領域に戻りましょう。検証用のエンティティ、たとえばメールボックス(電子メール)、および質問への回答が必要です。これはHohoのアドレスですか? この住所は短すぎませんか、長すぎませんか?
class HohoEmailValidator implements IValidator { public function isValid( $email) { return $email === 'Hoho';
Validate()関数ではバリデータのコレクション(リスト、配列)を使用できないため、バリデータのコレクション(リスト、配列)を引数として使用して機能を拡張する必要があります。
function IsValidByStrategy( $strategyCollection, $param) { foreach($strategyCollection as $strategy) { if($strategy instanceof IValidator) {
そうそう、これは頭の上の髪のいい動きです:
- バリデータのコレクションが空の状態は監視されません
- 関数の動作を変更することはできません。最初のfalse関数isValid()で失敗します
すべてのカードを手に入れたので、渡された電子メールアドレスをチェックする
戦略パターンのコンテキストで、あまり有用でない最初の関数を説明できます。
検証ロジックはスマートであることが判明しました(<-これはエラーではありません):
- 電子メールは「Hoho」という文字列である必要があります-これはすでに狂っています
- まあ、たとえ住所が本当に「Hoho」であっても、5文字を超えることはありません
- ただし、このコンテキストでLengthEmailValidatorを使用したチェックは実行されないことに注意してください
追加
サンプルをばかげたものにするために(
LengthEmailValidatorを思い出して
ください )、
IsValidByStrategy()関数の動作の変更に関して
strtegyパターンをもう一度適用し、次の機能を実装します。
interface IsValidReturnRule { function validateStep(&$validateResult, $validateResultByStep); function initialize(); } class ValidReturnRuleAny implements IsValidReturnRule { public function validateStep(&$validateResult, $validateResultByStep) { $validateResult |= $validateResultByStep; return $validateResult; } public function initialize() { return false; } } function IsValidByStrategyByRetRule( $strategyCollection, $param, IsValidReturnRule $retStrategy) { $result = $retStrategy->initialize(); foreach($strategyCollection as $strategy) { if($strategy instanceof IValidator) { if($retStrategy->validateStep($result, $strategy->isValid($param))) return $result; } } return $result; }
受け取った合計:
- 検証動作を変更する機能
- 検証プロセス自体の動作を変更する機能
次に、郵送先住所が有効と見なされることを確認するために、次のコードを記述する必要があります。
class ValidReturnRuleAny implements IsValidReturnRule { public function validateStep(&$validateResult, $validateResultByStep) { $validateResult |= $validateResultByStep; return $validateResult; } public function initialize() { return false; } } function IsValidEmailSoft($email = 'habr@habr.ru') { return IsValidByStrategyByRetRule(array( new HohoEmailValidator(), new LengthEmailValidator() ), $email, new ValidReturnRuleAny()); }
検証
戦略の結果
を処理するための
戦略の使用により、
IsValidEmailSoft関数は、長さが100500文字以下のアドレスを気にしません。
- IsValidEmailStrong()
- 検証戦略のいずれかが falseを返す場合、アドレスは無効です
- IsValidEmailSoft()
- 検証戦略のいずれかがtrueを返す場合、アドレスは有効です
覚えておくべきこと
一般的なタスクの洗練されたソリューション(言語機能を含む)を実装する設計ソリューションには、使用上の制限があります。 この意味で、GoFの
デザインパターンは美しく構成されています。
おわりに
この記事は、単純なことについて、「そんなに水を注ぐ」ことができる方法の例になるのではないかと心配しています。 しかし、1つ確かなことがあります。この記事の後に、何らかの理由でデザイン
パターンを熟知することを怠ったか、恐れていた私たちが恐怖を克服できたら素晴らしいことです。
結局のところ、知識は無知よりも優れており、光は闇よりも優れています。 ありがとう、素敵な週末を!
更新:PSはい、これは私の最初の記事です。おめでとう、批判、,辱、間違い/間違いはPMで受け入れられます。