【发布时间】:2013-11-29 20:48:10
【问题描述】:
我读过 Fowler 关于“贫血域模型”的文章(链接:http://www.martinfowler.com/bliki/AnemicDomainModel.html),我同意他的观点。
我尝试创建一个实体是简单 POPO 的应用程序,但这样,我有一个胖服务层,而将一些逻辑放入实体将是最简单的解决方案。
所以我会有这样的架构:
^
| Twig
| Controller | API
| Service
| Model
| Entity
地点:
实体:将是简单的 POPO,只是一袋 setter 和 getter
模型:将是用业务逻辑装饰的实体对象
服务:包含涉及多个实体的所有业务逻辑(这里我还要放置验证任务),并且充当转换器实体 -> 模型
控制器 | API:仅将 Request 与 Service、ParamConvert 匹配并检查自动化
Twig:表示层
我的问题是如何将实体层隐藏到控制器并且仅适用于模型。 为了用业务逻辑装饰我的实体,我想构建一个使用存储库并装饰结果的服务(我找不到其他方法来实现)。
所以,一个愚蠢的例子:
namespace ...\Entity\Article;
class Article {
private $id;
private $description;
// getter and setter
}
namespace ...\Model\Article;
class Article {
private $article; // all methods will be exposed in some way
private $storeService; // all required services will be injected
public function __construct($article, $storeService) {
$this->article = $article;
$this->storeService = $storeService;
}
public function getEntity() {
return $this->article;
}
public function isAvailable() {
return $storeService->checkAvailability($this->article);
}
...
}
class ArticleService {
private $storeService; // DI
private $em; // DI
private $repository; // Repository of entity class Article
public function findById($id) {
$article = $this->repository->findById($id);
return new \Model\Article($article, $storeService);
}
public function save(\Model\Article $article) {
$this->em->persist($article->getEntity());
}
...
}
上层是按照通常的方式制作的。 我知道这不是一个好的解决方案,但我找不到更好的方法来拥有一个模型层。而且我真的不喜欢这样的东西:
$articleService->isAvailable($article);
而不是更多的面向对象:
$article->isAvailable();
【问题讨论】:
-
我也对答案很感兴趣。为了执行他们的业务逻辑,您的模型是否具有容器意识(能够调用服务)?还是只限于他们自己?
-
你是怎么解决这个问题的?
-
看看GenieLamp 生成图层的软件工厂。最重要的元素是实体关系模型,可以在 1 天内编写一个 Python 生成器模块。
标签: php entity-framework symfony doctrine-orm software-design