3

私は Yii フレームワーク、特にその「コンポーネント」が好きで使用しています。これらは遅延インスタンス化され、構成ファイルでスワップインまたはスワップアウトできます。依存性注入ライトのようなものです。

コードの再利用やフレームワークの変更が必要になった場合に備えて、コードのビジネス ロジックをフレームワークから完全に独立させようとしています。

サービス層に AccountService というクラスがあり、これは IAccountService を実装し、1 つの引数のコンストラクターを持っているとします。

interface IAccountService
{
  function getUserById($id);
}

class AccountService implements IAccountService
{
  private $_userRepository;

  public function __construct(IUserRepository $userRepository) {
    $this->_userRepository = $userRepository;
  }

  public function getUserById($id) {
    return $this->_userRepository->getById($id);
  }
}

偉大な。これまでのところ、完全にフレームワークフリーです。ここで、これを Yii コンポーネントとして公開したいと思います。そうすれば、遅延インスタンス化して、Yii コントローラーや他の Yii コンポーネントで簡単に使用できるようになります。

しかし、Yii コンポーネント (IApplicationComponent を実装する) は、コンストラクター引数をまったく持たない必要がありますが、私のクラスでは 1 つ必要です!

何か案は?

これが私が持っているものです。私はそれらのどれにも満足していません。どちらも過剰に設計されているように見えますが、独特のにおいがします。

オプション 1 - 作成: Yii の IApplicationComponent を実装する「AccountServiceComponent」というクラスを作成します。コンストラクターのために AccountService クラスを拡張することはできませんが、次のようにプライベート メンバーとして 1 つをインスタンス化し、そのすべてのメソッドをラップすることができます。

class AccountServiceComponent implements IApplicationComponent, IAccountservice
{
  private $_accountService;

  public __construct() {
    $this->_accountService = new AccountService(new UserRepository());
  }

  public getUserById($id) {
    return $this->_accountService->getUserById($id);
  }
}

短所:すべてのメソッドをそのようにラップする必要があります。これは面倒であり、「バクラバ コード」につながる可能性があります。特に、それぞれに複数のメソッドを持つ複数のサービス クラスが存在することを考慮してください。

オプション 2 - mixin : (または、動作または特性、または最近呼ばれるもの。)

Yii (PHP 5.4 より前に作成されたもの) は、IBehavior を実装するクラスの形式で「振る舞い」を提供します。サービスを拡張する動作クラスを作成し、それをコンポーネントにアタッチできます。

class AccountServicesBehavior extends AccountService implements IBehavior
{
  // Implement the few required methods here
}

class AccountServiceComponent implements IApplicationComponent
{
  public function __construct() {
    $accountService = new AccountService(new UserRepository());
    $this->attachBehavior($accountService);
}

短所: 私のコンポーネントは IAccountService を公式に実装しなくなりました。また、レイヤードで過度になっているようです。

オプション 3 - オプションのコンストラクター パラメーター:

サービス クラスへのコンストラクター パラメーターをオプションにして、それをコンポーネントに拡張することができます。

class AccountService implements IAccountService
{
  public $userRepository;

  public function __construct(IUserRepository $userRepository = null) {
    $this->userRepository = $userRepository;
  }

  public function getUserById($id) {
    return $this->_userRepository->getById($id);
  }
}

class AccountServiceComponent extends AccountService implements IApplicationComponent
{
}

短所: オプションのコンストラクター パラメーターは、必要なものすべてを提供しなくても、このクラスをインスタンス化できることを意味します。

...だから、私が見逃している他のオプションはありますか? それとも、邪魔にならないものを選ばなければならないのでしょうか?

4

1 に答える 1

1

オプション3ですが、オプションの引数としてオブジェクトを使用すると、最高の音のように聞こえます:

public function __construct(IUserRepository $userRepository = new UserRepository()) {
    $this->userRepository = $userRepository;
}
于 2012-12-19T21:48:00.433 に答える