前言
相当大的php项目。网站与PHP模板。 Php驱动的API。 我们正在使用Doctrine ORM。模型(=实体)以及映射元保持业务逻辑。
模型示例:
class User {
private $firstName;
private $lastName;
public getFullName() {
return $this->firstName + $this->lastName;
}
}
此处User类包含两个字段和getFullName(),它们是基于字段值的业务逻辑。
问题:
在API中如何在模型中重用业务逻辑,同时保持高性能。
使用API中的doctrine模型不是一种选择。 因为Doctrine(与任何正常的ORM一样)在内存中提取整个对象。 对于API,这是问题(主要是时间)。我们只需要在api中返回有限的字段集。 即使关联是延迟加载,也会在每次使用相应的模型方法时获取它们。 我们有相当多的协会,反过来可以有其他协会等。 当我们处理收集调用时,问题会变得更糟(即使有分页限制)。
示例:
// GET /users
{
[
{
id: 123,
firstName: John,
lastName: Doe,
children: [
{
id: 456,
firstName: Mary,
lastName: Doe,
friends: [
{
{
id: 678,
firstName: Jane,
lastName: The Strawberry
}
},
]
},
...
]
},
...
]
}
这是一个虚拟的例子,但展示了一个问题。
可能的解决方案:
在这种情况下,业务逻辑保留在现有模型中,同时仅获取所需的字段。 但它并没有多大帮助,响应时间减少约100毫秒这是不够的。 此外,部分对象使用起来非常危险,在许多ORM中都是禁止使用的,而且Doctrine本身也非常不鼓励使用。
2)原始数组。
我们可以使用dql(甚至是原始的sql)。事情变得快2到3倍(响应时间和记忆)这是好事。 但是,从模型中重用域逻辑会成为一个问题,因为我们正在处理未包含在模型中的纯行。 因此,很明显逻辑必须“提取”到可以在两个模型对象中重用的地方以及处理原始数组结果时。这可以通过一些模式(例如策略模式)来完成。我们现在正在调查, 但它很复杂:(
任何想法/常见做法/想法?
P.S。像“Trow away Doctrine,你的架构很糟糕......”之类的评论被接受:)