简体   繁体   English

业务对象和数据层

[英]Business Objects and Data Layer

This site has provided me with many useful answers, however after a hours search I haven't found anything that specifically answers my needs. 这个网站为我提供了许多有用的答案,但是经过一个小时的搜索,我找不到任何能够满足我需求的东西。 So here goes... 所以这里......

The company I'm working for is in the process of designing a new Business Objects Layer and a Data Access Layer - these will reside in separate assemblies. 我正在为之工作的公司正在设计新的业务对象层和数据访问层 - 这些将驻留在单独的程序集中。

The problem is I'm having a hard time getting my head around the interaction between these two layers - specifically, should the DAL know about the BOL, I've read numerous articles that have said the dependency order should go something like this: 问题是我很难理解这两层之间的交互 ​​- 特别是,如果DAL知道BOL,我已经读过许多文章说过依赖顺序应该是这样的:

GUI / Presentation --> BOL ---> DAL GUI /演示 - > BOL ---> DAL

But as far as I can see, the DAL needs a reference to the BOL in order to be able to 'return' objects to the BOL layer. 但据我所知,DAL需要引用BOL才能将对象'返回'到BOL层。

I'm going for a intermediate assembly between the BOL and DAL which will be basically a thin layer filled with interfaces to decouple those two DLL's, so the framework can use different DALs if the need arises. 我要在BOL和DAL之间进行中间组装,它基本上是一个薄层,里面装有接口来解耦这两个DLL,因此如果需要,框架可以使用不同的DAL。

This lead me to the idea of introducing another thin layer with a bunch of interfaces that the BOs implement, then when the BOL calls the DAL interface, it passes it an object which implements one of these BO interfaces and then the DAL proceeds to populate the object. 这让我想到引入另一个薄层,其中包含BO实现的一堆接口,然后当BOL调用DAL接口时,它传递一个实现其中一个BO接口的对象,然后DAL继续填充宾语。 This removes all dependencies between the BOL and the DAL - however, I'm finding it hard to justify it to be honest. 这消除了BOL和DAL之间的所有依赖关系 - 但是,我发现很难证明它是诚实的。

Ideally we would like to use an ORM as it just removes the need to write CRUD stuff but our clients have a habit of fiddling with column lengths on their database and this is the cause of most of our errors to-date using the strongly typed DataTables. 理想情况下,我们希望使用ORM,因为它只是删除了编写CRUD内容的需要,但我们的客户习惯于在数据库中摆弄列长度,这是我们使用强类型DataTables迄今为止的大多数错误的原因。 。 I've heard Linq2SQL also stores column lengths at compile time, not sure if NHibernate does or not (but, I'm not sure if our Database Schema is designed cleanly enough for NHibernate, pitfalls of dealing with legacy systems). 我听说Linq2SQL也在编译时存储列长度,不确定NHibernate是否存在(但是,我不确定我们的数据库模式是否为NHibernate设计得足够干净,处理遗留系统的陷阱)。

So yea, any insight on the relationship between a BOL and a DAL would be very much welcome - apologies if the above is poorly written, if anyone needs clarification I'll be happy to provide more detail. 所以,对BOL和DAL之间关系的任何见解都会非常受欢迎 - 如果上述内容写得不好,请致歉,如果有人需要澄清,我会乐意提供更多详细信息。

Marlon 马龙

The way the I do this is the BO expects a DataReader or a DataContext or whatever back from the DAL, not the actual formed object. 我这样做的方式是BO期望DataReaderDataContext或者来自DAL的任何东西,而不是实际形成的对象。 It is then the job of the BO layer to take and fill itself from the object that came back. 然后,BO层的工作是从回来的对象中获取并填充自己。 The DAL isn't returning back a completed BO. DAL没有返回完成的BO。 The main thing to remember is that changing something in the BO layer shouldn't cause issues for the DAL layer, but changing something in the DAL layer could cause issues for the BO layer. 要记住的主要事情是,在BO层中更改某些内容不应该导致DAL层出现问题,但是更改DAL层中的某些内容可能会导致BO层出现问题。

A short example of what I typically do 我通常做的一个简短例子

In the BO layer 在BO层

FillData(){
   DataReader dr = DataLayer.GetData("SomePropertyForAStoreProcedure");
   If dr.Read(){
    Property1 = dr.GetValue("Property1");
    //So on and so forth
   }
}

In the DAL 在DAL中

DataReader GetData(String SPProperty){

}

看看SubSonic http://subsonicproject.com/它为大多数数据访问繁琐的工作,它比大多数ORM更容易

The DAL needs a reference to the BOL so that it can populate the objects. DAL需要对BOL的引用,以便它可以填充对象。 What you do not want to have is any reference or coupling from the BOL back to the DAL - doing so causes your BOL to be coupled to a specific database implementation. 您不希望有的是从BOL返回到DAL的任何引用或耦合 - 这样做会导致您的BOL耦合到特定的数据库实现。 When you think about it this makes sense. 当你考虑它时,这是有道理的。 Your DAL knows details about the business objects down to the level of properties and how to retrieve their data from the database - of course the DAL is inherently tightly coupled to the BOL. 您的DAL知道业务对象的详细信息,直到属性级别以及如何从数据库中检索数据 - 当然DAL本质上与BOL紧密耦合。 So the reference that way is fine. 所以参考方式很好。 And if you think about it what is on the other side? 如果你考虑一下另一方面是什么? The database. 数据库。 "Tightly coupling" going from your object data to your database? 从您的对象数据到数据库的“紧密耦合”? Yeah, it is pretty darn tight. 是的,它非常紧张。 The concept is not very meaningful even. 这个概念甚至没有多大意义。

It is all the other direction where you need to decouple. 这是你需要解耦的另一个方向。 So yes as long as there is no direct coupling from the DAL into the BOL you can change your data platform anyway you want. 所以,只要没有从DAL到BOL的直接耦合,您可以随意更改数据平台。

Not much point in creating interfaces for BOs and passing them to DAL in this scenario. 在这种情况下,为BO创建接口并将它们传递给DAL没什么意义。 You might sometimes need to go the other way however. 但是,您有时可能需要采用其他方式。 As a rule business objects should not have to know anything about how they are either created or persisted. 通常,业务对象不应该知道有关如何创建或持久化它们的任何信息。

In practice even with most ORMs, for example, creating a business layer completely free of any sort of persistence artifacts can become very difficult, sometimes effectively not possible. 实际上,即使对于大多数ORM,例如,创建完全没有任何类型的持久性工件的业务层可能变得非常困难,有时实际上是不可能的。 So occasionally you have something that is just too difficult to work around though, and you might find that strictly avoiding having any data knowledge in BOs is leading you to over complexity that is degrading rather than adding value. 所以偶尔你会遇到一些难以解决的事情,你可能会发现严格避免在BO中拥有任何数据知识会导致你过度复杂而不是增加价值。

If you feel like there is no better way and you need to have something persisted from within the BOL, create a simple interface so that the DAL functionality can be passed into the BOL. 如果您觉得没有更好的方法,并且您需要在BOL中保留一些内容,请创建一个简单的界面,以便将DAL功能传递给BOL。 That way you can still keep the BOL decoupled from the specific database implementation at least. 这样,您至少可以将BOL与特定数据库实现分离。

Also, although it is a lot of additional work, unless this is a very simple throwaway app, I strongly recommend that you also add another layer between the UI and the BOL. 此外,虽然这是一个额外的工作,除非这是一个非常简单的一次性应用程序,我强烈建议您在UI和BOL之间添加另一个层。 The MVP (Model-View-Presenter) pattern is a general purpose design pattern for reducing coupling between the core app and the UI. MVP(Model-View-Presenter)模式是一种通用设计模式,用于减少核心应用程序和UI之间的耦合。 There are a lot of variants on presenters, don't get too caught up in the specific details, just start off with the simple MVP if you have never used it. 演示者有很多变种,不要过于关注具体的细节,如果你从未使用它,只需从简单的MVP开始。

The patterns is not that hard, it is just that UI itself is so messy that it may take you at least a couple of major iterations / applications before you feel like the code you are writing at any time is systematically and methodically working to decouple the UI. 模式并不那么难,只是UI本身是如此混乱,以至于在你觉得你在任何时候编写的代码系统地和有条不紊地努力解耦之前,你可能至少需要几个主要的迭代/应用程序。 UI。 Just keep working at it, start to acquire an arsenal of techniques, and don't get hung up on the fact that you really have not achieved a sharp clean separation yet. 只要继续努力,开始掌握各种技术,并且不要因为你真的没有实现清晰的分离这一事实。 Anything and everything you learn and can do that even contributes a little to creating creating a well defined boundary at the UI is a big step in the right direction. 您学到的任何东西都可以做到这一点,甚至可以为在UI上创建一个明确定义的边界做出一点贡献,这是朝着正确方向迈出的重要一步。

The 'correct' approach is going to vary depending on business needs. “正确”的方法将根据业务需求而变化。 To be honest, there are many projects where I feel the old style ado recordsets incurred less development time and were easier to maintain than many of the ORM's out now. 说实话,有很多项目让我觉得旧式的ado记录集比现在的许多ORM产生更少的开发时间并且更容易维护。 Take some time to identify what your needs are, and remember that development time and maintainability are design goals that should be properly weighed as well. 花些时间确定您的需求,并记住开发时间和可维护性是设计目标,也应该适当权衡。

It also depends on if/what library/ORM (Object-Relational Mapper) you use. 它还取决于您使用的/ /库/ ORM(对象关系映射器)。 When using a (good) ORM, the DAL should be a very remote concern, because it is almost completely hidden by the ORM; 当使用(好)ORM时,DAL应该是一个非常遥远的问题,因为它几乎被ORM完全隐藏; however, best practices dictate that even then, for medium to large size applications, you should introduce another layer between the BOL and ORM, usually DTO (Data Transfer Objects). 但是,最佳实践要求即使在那时,对于中型到大型应用程序,也应该在BOL和ORM之间引入另一层,通常是DTO(数据传输对象)。 DTOs can also be used without an ORM, as they are just dumb objects defined in a separate library, and the DAL can be responsible for persisting them (transforming them from/to database structures), while the BOL can query the DAL and receive those objects. DTO也可以在没有ORM的情况下使用,因为它们只是在单独的库中定义的哑对象,并且DAL可以负责持久化它们(将它们从/向数据库结构转换),而BOL可以查询DAL并接收这些对象。

Decoupling the layers can be achieved in a variety of ways, most commonly through interfaces and/or MEF or another DI/IOC framework. 可以以各种方式实现层的分离,最常见的是通过接口和/或MEF或另一个DI / IOC框架。 Any such technique achieves more than sufficient decoupling if used effectively. 如果有效地使用,任何这样的技术都实现了足够的解耦。

Also, depending on the technology used, as Sisyphus said, one of the layered architectural patterns will help separate concerns nicely: MVC, MVP, MVVM etc. I personally recommend MVVM with WPF (desktop) or Silverlight (web) but I'm highly biased - ie I love both of them to death :) 此外,正如Sisyphus所说,取决于所使用的技术,其中一个分层架构模式将有助于很好地分离关注点:MVC,MVP,MVVM等。我个人推荐使用WPF(桌面)或Silverlight(web)的MVVM但我很高兴有偏见 - 即我喜欢他们两个人去死:)

These are my findings, 这是我的发现,
1. Use interfaces 1.使用接口
2. Use DTOs [Data Transfer Objects] between DAL & BLL 2.在DAL和BLL之间使用DTO [数据传输对象]
3. Split BLL into two, 3.将BLL分成两部分,
a. BLL
b. Service Layer
4. Use Inversion of Control (IoC) container for keep coupling as low as possible. 4.使用控制反转(IoC)容器使耦合保持尽可能低。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM