gpt4 book ai didi

php - 将业务逻辑放在实体中

转载 作者:可可西里 更新时间:2023-11-01 12:22:02 26 4
gpt4 key购买 nike

我读过 Fowler 关于“贫血领域模型”的文章(链接:http://www.martinfowler.com/bliki/AnemicDomainModel.html),我同意他的观点。

我尝试创建一个应用程序,其中实体是简单的 POPO,但通过这种方式,我有一个胖服务层,而将一些逻辑放入实体将是最简单的解决方案。

所以我会有这样的架构:

^
| Twig
| Controller | API
| Service
| Model
| Entity

地点:

实体:将是简单的 POPO,只是一袋 setter 和 getter

模型:将是用业务逻辑装饰的实体对象

服务:包含涉及多个实体的所有业务逻辑(我也会在此处放置验证任务),并且充当转换器实体 -> 模型

Controller | API:只匹配请求与服务,ParamConvert和检查授权

Twig:表示层

我的问题是如何将实体层隐藏到 Controller 并且仅适用于模型。为了用业务逻辑装饰我的实体,我想构建一个使用存储库并装饰结果的服务(我找不到其他方法来实现它)。

所以,一个愚蠢的例子:

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();

最佳答案

我有 DoctrineEntity 对象扩展 DomainModel 对象。虽然 Controller 实际上可能接收 DoctrineEntities,但它们仅在 DomainModelInterface 上运行。

... namespace DomainModel;
interface ArticleDomainModelInterface ...
interface ArticleDomainModelRepositoryInterface ... // create, find, save, commit
class ArticleDomainModel implements ArticleDomainModelInterface

... namespace Doctrine;
class ArticleDoctrineEntity extends ArticleDomainModel
class ArticleDoctrineRepository implements ArticleDomainModelRepositoryInterface

... namespace Memory;
// Usually dont need a memory article object
class ArticleMemoryRepository implements ArticleDomainModelRepositoryInterface

所有模型的创建和持久化都是通过存储库完成的。 Controller 和其他相关服务只知道 ArticleDomainModel 方法。这为您提供了很好的分离,并允许使用不同的存储库进行测试或支持不同的持久性机制。它还允许在您的域模型中使用值对象,同时仍然使用 Doctrine 2 持久化它们。

但是,在 php 中,我确实在思考什么样的有用业务逻辑实际上可以放在域模型对象本身中。我倾向于以服务中的大部分逻辑结束。那是因为我的大多数 PHP 应用程序都是严重面向 crud 的。

还有一个问题: Controller 本身应该有权访问域模型对象吗?

Doctrine 2 的主要开发者之一,Benjamin Eberlei,有很多关于这个主题的博客文章。他的所有文章都值得详细阅读。这里有一些:

http://www.whitewashing.de/2013/07/24/doctrine_and_domainevents.html http://www.whitewashing.de/2012/08/22/building_an_object_model__no_setters_allowed.html http://www.whitewashing.de/2012/08/18/oop_business_applications__command_query_responsibility_seggregation.html

关于php - 将业务逻辑放在实体中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20018369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com