如何处理域层和数据库层之间的通信?

2022-01-04 00:00:00 oop php dns database-abstraction

我对为业务逻辑(域)和数据库访问逻辑使用单独的层还很陌生,但在解决问题的过程中我遇到了一个问题,我仍然觉得我没有找到一个很好的解决方案.

I am fairly new to using separate layers for the business logic (Domain) and database access logic, but in the course of working things out I've come across a problem to which I still feel I haven't found a great solution.

澄清 我现有的解决方案使用数据映射器直接处理数据库交互.但是,当我进一步调查这个问题时,许多人建议域层不应直接与实际执行数据库交互的数据映射器通信,也不应包含这些数据映射器.这就是为什么我将 Repository 对象放置在域和必要的数据映射器之间,但这感觉不太自然或正确.所以真正的问题是自然存在哪一层来处理域和数据映射器之间的通信?任何有关如何构建它的示例将不胜感激.

Clarification My existing solution uses Data Mappers to deal with the database interactions directly. However, as I've further investigated this issue many people have suggested that the Domain layer should not directly communicate with nor contain the Data Mappers that actually perform the database interaction. This is why I placed the Repository objects between the Domain and the necessary Data Mappers but this doesn't feel quite natural or correct. So the real question is what layer naturally exists to handle communication between the Domain and the Data Mappers? Any examples of how to structure it would be appreciated.

例如:

  • 如何正确处理在另一个域对象的上下文中检索域对象的集合?
  • 如何根据对另一个对象执行的操作强制插入单个域对象或对象集合.我目前面临的情况是,当一个人附加到一个活动时,我需要插入需要为该人为该活动执行的所有事件.

推荐答案

Gabriel,这被称为阻抗匹配问题."周围有很多解决方案,从重量级的解决方案(如 J2EE 实体 bean)到 Ruby ActiveRecord,再到简单地编写手动连接.

Gabriel, this is called the "impedance matching problem." There are many solutions around, from heavyweight ones like J2EE entity beans to Ruby ActiveRecord to simply coding a hand connection.

好吧,如果没有更多信息,很难确切地了解如何进行攻击,但这是基本方法.

Okay, well, its hard to see exactly how to attack this without a lot more information, but here's the basic approach.

任何此类架构问题都是由非功能性需求(如性能)驱动的;此外,这里还有一个正确性问题,因为您希望确保更新以正确的顺序完成.因此,您需要考虑工作负载,即实际应用程序中的使用模式.考虑到这一点,您基本上有几个问题:首先,您的应用程序中的基本数据类型可能无法正确映射到数据库(例如,您的代码中表示的 VARCHAR 属性是什么?),其次是您的域模型可能无法完全映射到您的数据库模型.

Any of these sorts of architectural issues are driven by non-functional requirements like performance; in addition, there is a correctness issue here, in that you want to make sure updates are done in the correct order. So, you're going to need to think about the workload, which is to say the pattern of usage in real-world application. With that in mind, you basically have a couple of issues: first, the base data types in your application may not map correctly to the data base (eg, what's a VARCHAR property represented as in your code?), and second your domain model may not map cleanly to your database model.

您想要的是让数据库和 dmain 模型工作,以便域对象的一个​​实例恰好是数据库模型中表的一行;在大型应用程序中,由于性能限制或预先存在的数据库模型强加的限制,您很少能做到这一点.

What you would like is to have the database and the dmain model work out so that one instance of a domain object is exactly a row of a table in your database model; in large-scale applications you can rarely do this because of either performance constraints or constraints imposed by a pre-existing database model.

现在,如果您完全控制您的数据库模型,它会稍微简化一些事情,因为这样您就可以使您的数据库模型更接近域.这可能意味着数据库模型有些非规范化,但如果是这样,您可以(取决于您的数据库)使用视图来处理它,或者只是没有完全规范化的数据库.归一化是一种有用的理论结构,但这并不意味着您不能在实际系统中放松它.

Now, if you completely control your database model, it simplifies things somewhat, because then you can make your database model more closely resemble the domain. This might mean the database model is somewhat denormalized, but if so, you can (depending on your database) handle that with views, or just not have a completely normalized database. Normalization is a useful theoretical construct, but that doesn't mean you can't relax it in a real system.

如果您不完全控制您的数据库模型,那么您需要一个对象层来进行映射.在实现它时,您有很多选项可供选择:您可以在数据库中构建视图或非规范化表,您可以构建中间对象,或者您可以同时执行某些操作,甚至可以同时执行这两个步骤(即,访问非规范化表的中间对象.)

If you don't completely control your database model, then you need a layer of objects that make the mapping. You've got a bunch of options to choose from in implementing that: you can build views or denormalized tables in the database, you can build intermediate objects, or you can do some of both, or even have several steps of both (ie, an intermediate object that accesses a denormalizaed table.)

不过,此时您会遇到不要重复自己"的问题;和做可能有效的最简单的事情".想想最有可能改变的是什么?你的领域模型?如果您有一个强大的领域模型,那可能性就较小——业务变化相对较少.数据库中数据的准确表示?比较常见一点.或者,最常见的是使用的确切模式(例如发现需要处理并发更新.)因此,当您考虑这一点时,您需要做些什么才能尽可能轻松地处理最常见的更改.

At that point, though, you run into issues with "don't repeat yourself" and "do the simplest thing that will possibly work." Think about what is most likely to change? Your domain model? If you've got a strong domain model, that's less likely --- the business changes relatively rarely. The exact representation of data in the database? A little more common. Or, most commonly, the exact patterns of use (like discovering a need to handle concurrent updates.) So, when you think about that, what do you need to do to make it as easy as possible to deal with the most common changes.

我意识到这并没有给您非常精确的说明,但我认为我们无法在不了解您的申请的情况下提供精确的说明.但是我也有点印象你想知道什么是正确的"?处理这种情况的方法是,当您已经在使用或多或少可以完成工作的东西时.所以,我最后会问你现在对什么不满意?"和你想如何解决这个问题?"

I realize this isn't giving you very precise instructions, but I don't think we can offer precise instructions without knowing a whole lot about your applicaiton. But then I also kind of get the impression you're wondering about what the "right" way of handling this would be, while you are already working with something that more or less does the job. So, I'd end up by asking "what are you unhappy with now?" and "How would you like to solve that?"

相关文章