我应该在哪里创建对象?库?厂?

时间:2016-06-09 14:03:15

标签: php design-patterns repository-pattern factory-pattern

我有一个业务对象的存储库,我需要根据数据创建不同的对象。我应该直接在repo中创建它们还是将代码移到其他地方 - 工厂或业务逻辑层中的某些类?

/**
 * @returns Applier
 */
class ApplierRepository implements IApplierRepositoryInterface {
  //some code
  public function find($id) {
    $data = $this->findBySql($id);

    //Is it a business logic?
    if($data['profile_id'] != null)
      $object = new ProfileApplier();
    if($data['user_id'] != null) {
      $user = $this->userRepository->find($data['user_id']);
      $object = new UserApplier($user);
    }
    //...
    return $object;
  }
}

1 个答案:

答案 0 :(得分:2)

我会将 存储库 视为数据访问级别应用程序逻辑之间的抽象级别 find()方法中的内容实际上是 工厂方法

为了清楚说明,想象一下你需要测试ramework 来测试你的类的逻辑。你会怎么做?您的 ProfileApplier UserApplier 和其他应用程序似乎会调用一些 数据源 来检索用户数据。

在测试方法中,您需要将这些数据源替换为测试数据源。您还需要替换数据源访问方法。这就是 存储库 模式的设计目标。

更清洁的方法如下:

class AppliersFactory {
  IApplierRepository applierRepository;

  public AppliersFactory(IApplierRepository repo)
  {
    $this->applierRepository = repo;
  }

  // factory method, it will create your buisness objects, regardless of the data source
  public function create($data) {
    if($data['profile_id'] != null)
      $return new ProfileApplier();
    if($data['user_id'] != null) {
      $user = $this->applierRepository->find($data['user_id']);
      $object = new UserApplier($user);
    }
    //...
    return $object;
  }
}

在真实应用程序中使用此存储库

class RealApplierDataStorageRepository implements IApplierRepositoryInterface {
  //some code, retrieves data from real data sources
  public function find($id) {
    //...
  }
}

并在测试模块中使用此测试来测试您的逻辑

class TestApplierDataStorageRepository implements IApplierRepositoryInterface {
  // some code, retrieves data from test data sources (lets say, some arrays of data)
  public function find($id) {
    //...
  }
}

希望,这有帮助