如何使用Symfony2和Doctrine 2及其设计模式来制作具体的复杂模型逻辑? [英] How to make concrete complex model logic using Symfony2 and Doctrine 2 and their Design Patterns?

查看:110
本文介绍了如何使用Symfony2和Doctrine 2及其设计模式来制作具体的复杂模型逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具体类型的问题


我有一个对象A(一个实体)公司(实体),
公司可以联系在一起(如果他们有一些普通股东,例如b $ b)。我想要A能够知道一个公司C1是一个公司C2是
与公司C2联系。


感觉



在我的知识和习惯状态下,我认为公司实体应该有一种方法来告诉他或她不是与另一个一个(点1 )。我可以通过获得所有公司的联系方式来完成这些课程,而且我的公司C2还在那里(第2点)。但这是肮脏的,这意味着获得所有的依赖是什么原因?获取可以从数据库中轻松检索的布尔值,我可以考虑在与公司链接的存储库(第3点)中创建一个函数。但是,不,因为实体(A或C1和C2)中没有可用的东西,所以记住轻量级对象。



参数




  • 第1点是基于单一责任原则。随意批评这一点。由于实体应该嵌入模型逻辑,我认为isConnectedWith函数应该在CompanyEntity的定义中正确。请记住,A也是一个实体(所以在这里也是存放在这里)

  • Point 2是一个解决方案,它在某种意义上是好的:这是正确的方法,如果这是一个大如果,什么教义只是模拟是真的;如果只是简单地调用 $ object-> connexions 访问已存在的内存中的某个对象集合。但事实是可怕的:它不存在,它遇到了我们的webapp:数据库的常见瓶颈。

  • 第3点我厌倦了数据映射器和依赖注入组合告诉您的实体(和一个存储库)应该仅由自己生活,因为它们是模型逻辑。也许我对我的理解是非常错误的,但是由于每个人都在说这是一件坏事,我完全放弃了在实体中注入助手或配置的想法。



问题



您如何解决维护完整性和性能的问题,避免肮脏的解决方法?我的论点有哪些不好?

解决方案

分析你的分数



< h2>点3

点3根本不是一个解决方案!谁告诉说,注入很多东西都不是一个很好的解决方案,是绝对正确的。这几乎是OO和模式编程的最佳实践的标准事实。

实体只有仅表示对象(不在IT接受,当然!)所以,属性和访问器方法是你必须包含的唯一的东西。

想想一下你注入的东西,改变可能随着时间而改变(方法签名,方法返回类型或逻辑) :在这种情况下,你必须改变实体本身以保持事物一起工作,但是为什么你必须这样做成实体,这是不会改变的?深思熟虑,因为是OO编程的好起点(不是symfony2或实体代表!)



点2



是的,你是对的:为什么从数据库中获取所有实体,或者如果你写一个好的查询,那么你只需要搜索的实体,如果你永远不会使用它?

关于这一点,你必须分析一下如下:




  • 我要在其他地方使用这个(或那些)实体,所以抓取它好吗?

  • 我知道Doctrine2会在内存中保存对象(*)吗?这意味着,当您查询(或询问)先前提取的同一个对象时,他会向您返回该对象的同一个实例?所以,没有DB连接,没有fecth,没有重量级的操作。



点1



是的,这是一个好点。您必须实现(在存储库当中!)一种方法,如 - > isThere()或更好的东西(这是想到的名字)。 />
使用此方法,您可以编写自定义SQL(称为 D QL,其中 D 代表Doctrine),只返回一个标志或一个intenger由code> COUNT(*)或聚合函数获得)。
对于fetch不是 ArrayCollection 的实体,但标量结果,正如名称建议你,使用 $ query-> getSingleScalarResult();

我想我会倾向于最后一个解决方案。



希望能够很好地解释






(*)这被称为身份映射


Problem of the concrete kind

I've an object A (an entity) that manipulates some companies (entity), companies can be linked together (if they have some common shareholder for example). I want A to be able to know wether or not a company C1 is linked with a company C2.

Feelings

Within my state of knowledge and habits, I think that there should be a method in the company Entity to tell wether or not it's connected with another one (point 1). Of courses I can do it by getting all the company connexions, and looking wether or not my company C2 is in there (point 2). But this is dirty, it means getting all dependencies for what reason ? Getting a boolean that could be retrieved easily from the database, I could think about making a function in the repository linked with the companies (point 3). But no, because nothing is available in the entities (either A or C1 and C2), light weight objects remember.

Argumentations

  • Point 1 is based on the Single Responsibility Principle. Feel free to criticize that point. Since entity are supposed to embed the model logic, I think the isConnectedWith function should be right in the definition of the CompanyEntity. Please remember here that A is also an entity (so repository here too)
  • Point 2 is a solution, it's good in one sense : it's the right way to do, if, that's a big if, what Doctrine is only simulating was true; if simply calling $object->connexions accessed to some objects collection that was already there, somewhere in the memory. But the truth is awful : it's not there, it lived the common bottleneck of our webapp : database.
  • Point 3 I'm getting sick of that Data Mapper & Dependency Injection combo telling that your entities (and a bit repositories) should live only by themselves because they are the model logic. Maybe I'm terribly wrong on my understanding, but since everybody is telling it's a bad thing, I've completely dropped the idea of injecting helper or configuration in the entities.

Questions

How would you solved the problem maintaining integrity and performances and avoiding dirty workaround ? What points of my argumentations are bad ?

解决方案

Let's analyze your points

Point 3

Point 3 isn't a solution at all! Who told that inject pretty much everything into entity isn't a good solution, is absolutely right. This is nearly a "standard-de-facto" of best practices of OO and pattern programming.
Entity is there only for represent an "object" (not in IT acception, of course!) so, property and accessor methods are the only things you have to include.
Think about a situation where you inject something that change could change with time (methods signature, methods return type or logic): in those case, you have to change entity itself for keep the things works together, but why you have to do this into entity, that isn't changed? Think deeply about it because is a good point of start for OO programming (not symfony2 or entity representation only!)

Point 2

Yes, you're right: why fetch from DB all entity or, if you write a "good" query, only entity you're searching for, if you'll never use it?
About this point you have to analyze somethings like:

  • Have I to use this (or those) entities elsewhere, so fetch it could be good?
  • Did I know that Doctrine2 will keep in memory where he fetches the objects(*)? That means, when you query (or ask) for the same object previously fetched, he returns to you the same instance of that object? So, no DB connections, no fecth, no heavyweight operations.

Point 1

Yes, this is a good point. You have to implement (in repository, of course!) a method like ->isThere() or something better (this is first name that came in mind).
With this method you can write your custom SQL (called D QL, where D stands for Doctrine) where you return only a flag or an intenger (obtained with COUNT(*) or aggregative functions alike).
For fetch not an ArrayCollection of entity but a scalar result, as the name suggest you, use $query->getSingleScalarResult();
I suppose that I would incline for this last solution.

Hope to had explained all well


(*) This is called identity map

这篇关于如何使用Symfony2和Doctrine 2及其设计模式来制作具体的复杂模型逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆