1

疎結合の OOP 設計に関する質問があります。Email のような単純な値オブジェクトがあるとします。

final class Email 
{
    private $_email;

    public function __construct($email)
    {
        self::isValid($email);
        $this->_email = $email;
    }

    public function getEmail()
    {
        return $this->_email;
    }

    public static function isValid($email)
    {
    // some validation logic goes here  
        return true;
    }

}

isValid メソッドを実際に実装するまでは、すべてが単純明快です。ここには2つのオプションがあります:

1)次のようなひどく醜いものになる可能性のある独自の検証ロジックを実装します。

public static function isValid($email)
{
    $v = preg_match(
        '/^[-a-z0-9!#$%&\'*+\/\=?^_`{|}~]+(?:\.[-a-z0-9!#$%&\'*+\/\=?^_`{|}~]+)*@(?:[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?\.)*(?:aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|pro|[a-z][a-z])$/',
        $email
    );

   return $v > 0;
}

2) 組み込みのフレームワーク バリデーターを使用する

 public static function isValid($email)
 {
        $validator = new Zend_Validate_Email(); // tight-coupling detected!
        return $validator->isValid($email);
 }

車輪を再発明したくないし、コードを繰り返したくないので、最初の方法には従いたくないので、2番目の方法に固執しています。

2 番目の方法に従うと、問題が発生します。クラスが別のフレームワーク クラスに依存するようになります。

私の実際の質問は、単純なケースで依存性注入を使用せずに、エンティティ/値オブジェクトで低レベルのインフラストラクチャ クラスを直接使用することが許容されるかどうかです。

この例を「適切に」実装すると、疎結合のためだけに、コードがはるかに複雑になります。isValid 関数で使用される事前構成済みの EmailValidator のインスタンスを値オブジェクト (Email) クラスに提供する EmailFactory を作成する必要があります…</p>

4

1 に答える 1

0

検証関数が外部リソースを必要としない限り、依存関係を直接再利用し、注入を回避します。

ドメイン オブジェクトはドメイン ルールをカプセル化し、これらのルールを確保するために必要なすべての情報を含む必要があります。低結合よりも高凝集性を中心に設計されています (集約の概念自体が相互依存性を減らす手段として機能します)。

例のEmailクラスは、電子メール アドレス検証の単一障害点になるはずです。すべてのドメイン オブジェクトがそのクラスを介して電子メールを検証する場合、既存のフレームワーク (またはサードパーティ) の機能を再利用することは実装の詳細であり、疎結合に関する問題は少なくなります。検証ルールが変更された場合は、とにかく関数を再実装する必要があります-Zend_Validate_Emailまたはカスタムコードを使用します。

検証ロジックをエンティティまたは値オブジェクトに挿入すると、多くの問題が発生します。

  • ドメインオブジェクトに属するロジックは別のクラスに移動されます
  • エンティティへのサービスの注入は一般的に推奨されません
  • EmailValidatorクラス専用のインターフェースを導入することは、再利用された抽象化の原則に違反します
  • isValidで静的メソッドを呼び出すEMailことは不可能です

検証ロジックが外部リソースを必要とするまれなケースでのみ、ドメイン オブジェクトの作成時に検証するサービスが注入されたファクトリを使用する傾向がありますが、それはドメイン モデルの設計を再考した後でのみです。

于 2014-02-24T16:33:28.050 に答える