C# 如何将业务层和数据层完全分离?
目前,我在应用程序的单个项目中表示我的业务层和数据层。我对这两组类的关注点进行了很好的分离。但是,我的数据层类将作为参数并返回我的业务对象。因此,我将使用类似的代码(请不要对这段代码过于挑剔,我的生产代码看起来不太像这样):C# 如何将业务层和数据层完全分离?,c#,design-patterns,C#,Design Patterns,目前,我在应用程序的单个项目中表示我的业务层和数据层。我对这两组类的关注点进行了很好的分离。但是,我的数据层类将作为参数并返回我的业务对象。因此,我将使用类似的代码(请不要对这段代码过于挑剔,我的生产代码看起来不太像这样): //业务类片段 公共bool Save() { 如果(this.IsValid) { //DataProvider是实现IDataProvider接口的许多数据访问类之一。在类中的其他位置切换。这允许切换数据库提供程序、xml等。 DataProvider.Save(这个)
//业务类片段
公共bool Save()
{
如果(this.IsValid)
{
//DataProvider是实现IDataProvider接口的许多数据访问类之一。在类中的其他位置切换。这允许切换数据库提供程序、xml等。
DataProvider.Save(这个);
返回true;
}
返回false;
}
公共列表GetObjectsByCriteria(字符串条件)
{
返回DataProvider.GetMyBusinessObjectsByCriteria(条件);
}
我不希望我的业务类必须处理数据集,就像我喜欢让我的数据层类处理业务类一样
为了解决这个问题,我读了很多关于数据访问对象或数据传输对象的文章,但对于这些模式来说,这似乎是一个反模式的案例
我能做什么?如何优雅地实现应用程序这两个层的完全分离?将持久性逻辑从业务对象中提取出来,并将它们放入数据仓库。它的工作原理类似于.NET中现有的适配器(OleDbDataAdapter)的工作原理。这样,您还将分离业务对象和持久性逻辑
您的客户机代码将更加冗长,但我认为这确实是真正分离层的最佳方式。执行此操作的流行模式是Repository模式。在本例中,存储库使用集合语义充当门面,完全隐藏持久化数据所在的位置,无论是文件系统还是数据库。您可以实现它来访问数据,然后将数据映射到您想要使用的任何类型
您可以将域驱动设计作为您正在使用的活动记录模式的替代方案。您应该看看DAO模式(数据访问对象) 最好是使用现成的DAO构造(弹簧加载)。看看 DAO不是反模式!将它们与Spring和泛型一起使用,您就不必在意;) 每一层之间都有连接!将它们完全分离意味着它们无法进行通信(因此它们是无用的)
使用基本的CRUD操作或动态查找程序,只要它有语义意义。这是一个比如何将域模型与数据访问分离更普遍的问题。当您试图将应用程序逻辑与域模型、表示模型与应用程序逻辑等分离时,也会出现同样的问题 常见的解决方案是一种称为依赖项注入(DI)的技术。有些人也把它称为控制反转(IoC) 关于这个主题的开创性文本是Martin Fowler的文章,但从那时起我们已经走了很长的路,所以一定要检查一些最近的文本 您可以手动实现DI,比如,或者让DI容器(即框架)为您完成工作 常见的DI容器有:
- 持久性->模型
- 服务->模型,持久性
- 查看->模型、服务
唯一一个没有依赖项的类是没有人调用并且从不调用其他类的类。这既不是有用的设计目标,也不是有价值的设计目标。n层设计:在业务逻辑层,您可以创建数据访问类和数据操作类。始终编程到一个接口。这就是我们所做的,但我们也将其与DTO结合起来。我看不到Nosredna问题上的“良好的关注点分离”。我认为这篇文章可能会澄清一些概念,并提供帮助。好帖子,达菲莫!
//business class fragment
public bool Save()
{
if(this.IsValid)
{
//DataProvider is one of many data access classes that implement an IDataProvider interface. Switched elsewhere in the class. This allows switching of Database providers, xml, etc.
DataProvider.Save(this);
return true;
}
return false;
}
public List<MyBusinessObject> GetObjectsByCriteria(string criteria)
{
return DataProvider.GetMyBusinessObjectsByCriteria(criteria);
}