持续无知有什么好处?

发布于 2024-07-22 01:42:21 字数 266 浏览 11 评论 0原文

我是 DDD+TDD 世界的新手。 但我从事编程已经快九年了。

有人可以向我解释一下坚持无知的好处吗? 典型的 nHibernate 应用程序只是将类和数据库之间的依赖关系推送到映射文件。

如果我更改类文件或数据库,我必须更改映射文件。 那么,这不是只是通过添加一个抽象层来推动依赖关系吗? 到目前为止,我认为这没有什么革命性的。 但我不确定我是否遗漏了一些东西。

最后如何测试映射文件? 映射文件有可能会出现错误,我该如何测试它们?

I am a newbie in the DDD+TDD World. But I have been in programming for almost 9 years.

Can someone please explain me the benefits of persistance ignornace ? Typical nHibernate application just pushes the dependency between class and database to mapping files.

If I change Class files or Database, I have to change the mapping files. So isn't it just pushing the dependency by adding one more abstraction layer? In my opinion so far I don't think it's anything revolutionary. But I am not sure if I am missing something.

Finally How can I test the mapping files ? There are chances bugs will appear from mapping files, how can I test them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

假扮的天使 2024-07-29 01:42:21

让我用一个例子来解释这一点。 假设您正在使用经典 SQL 方法来实现应用程序。 您打开记录集、更改数据并提交它。

伪代码:

trx = connection.CreateTransaction();
query = connection.CreateQuery("Select * from Employee where id = empid");
resultset = query.Run();
resultset.SetValue("Address_Street", "Bahnhofstrasse");
resultset.SetValue("Address_City", "Zürich");
trx.Commit();

对于NHibernate,它看起来像这样:

emp = session.Get<Employee>(empid);

// persistence ignorant 'logic'
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";

session.Commit();

持久性无知意味着业务逻辑本身不知道持久性。或者换句话说,持久性与逻辑分离。 这使得它更加可重用。

将“逻辑”转移到可重用的方法:

void MoveToZuerichBahnhofstrasse(Employee emp)
{
  // doesn't have anything to do with persistence
  emp.Address.Street = "Bahnhofstrasse";
  emp.Address.City = "Zürich";
}

尝试使用结果集编写这样的方法,您就会知道什么是持久性无知。

如果您不相信,请看看单元测试有多简单,因为与持久性相关的东西没有任何依赖性:

Employee emp = new Employee();
MovingService.MoveToZuerichBahnhofstreasse(emp);
Assert.AreEqual("Bahnhofstrasse", emp.Address.Street);
Assert.AreEqual("Zürich", emp.Address.City);

DDD 是不同的。 在那里,您首先构建域模型(类模型)并根据它创建数据库设计。 对于 NH,这非常简单,因为 - 由于对持久性的无知 - 您可以在拥有(最终的)数据库模型之前编写模型和逻辑并对其进行单元测试。


测试:我们通过创建实体的实例、将其存储到数据库、获取它并进行比较来测试映射。 这是通过大量反思自动完成的。 但你不需要走那么远。 大多数典型错误都会在尝试存储实体时出现。

您可以对查询执行相同的操作。 复杂的查询值得测试。 如果查询能够被编译,那是最有趣的。 您甚至不需要任何数据。

对于数据库集成测试,我们使用 Sqlite。 这速度相当快。 NH 使用 SchemaExport 动态生成内存数据库(在每次测试之前)。

Let me explain this with an example. Lets assume your are implementing an application using a classical SQL approach. You open recordsets, change data and commit it.

Pseudo code:

trx = connection.CreateTransaction();
query = connection.CreateQuery("Select * from Employee where id = empid");
resultset = query.Run();
resultset.SetValue("Address_Street", "Bahnhofstrasse");
resultset.SetValue("Address_City", "Zürich");
trx.Commit();

With NHibernate it would look something like this:

emp = session.Get<Employee>(empid);

// persistence ignorant 'logic'
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";

session.Commit();

Persistence Ignorance means that the business logic itself doesn't know about persistence. Or in other words, persistence is separated from logic. This makes it much more reusable.

Move 'logic' to a reusable method:

void MoveToZuerichBahnhofstrasse(Employee emp)
{
  // doesn't have anything to do with persistence
  emp.Address.Street = "Bahnhofstrasse";
  emp.Address.City = "Zürich";
}

Try to write such a method using resultsets and you know what persistence ignorance is.

If your are not convinced, see how simple a unit test would be, because there aren't any dependencies to persistence related stuff:

Employee emp = new Employee();
MovingService.MoveToZuerichBahnhofstreasse(emp);
Assert.AreEqual("Bahnhofstrasse", emp.Address.Street);
Assert.AreEqual("Zürich", emp.Address.City);

DDD is something different. There you build up your domain model first (class model) and create the database design according to it. With NH this is very simple, because - thanks to persistence ignorance - you can write and unit test the model and logic before having a (definitive) database model.


Testing: We are testing mappings by creating an instance of the entity, storing it to the database, getting it back and compare it. This is done automatically with lots of reflection. But you don't need to go so far. most of the typical errors show up when trying to store an entity.

You could do the same with queries. Complex queries deserve a test. It's most interesting if the query gets compiled at all. You don't even need any data for this.

For database integration tests, we are using Sqlite. This is pretty fast. NH produces the in-memory database on the fly using SchemaExport (before each test).

梦年海沫深 2024-07-29 01:42:21

我一直从领域的角度思考,虽然我过去使用过存储过程、ADO.NET,但只有当我最终转向 NHibernate 时,我才对自己的持久性机制感到满意。

领域驱动设计(DDD)将重点放在领域模型上。 这意味着主要焦点是创建一个概念模型,为用户和程序员形成通用语言。 用户几乎对你如何保存他们的信息不感兴趣。 NHibernate 通过将持久性作为次要的关注点来帮助您实现这种心态,而持久性是捕获业务规则和理解用户真正想要从系统中获得什么的次要因素。

Fluent NHibernate 减少了域模型更改对底层映射文件的影响。 它还具有自动映射。 虽然您永远不能完全忽略系统的持久性,但 NHibernate 和 Fluent NHibernate 允许您专注于域模型。 如果您不专注于使用丰富的域模型,那么 NHibernate 几乎没有什么好处。

至于测试映射,无论您使用什么方法来实现持久性,您都将编写测试(或者您应该编写测试)。 这并不是因为您使用 NHibernate 而出现的额外工作。 只需将测试您的映射视为测试您的持久性是否正常工作即可。

同样,Fluent NHibernate 是无价的。 它有一个持久性规范测试,在大多数情况下使用起来非常简单。

I've always thought in term of the domain and while I've used stored procedures, ADO.NET in the past, it's only when I finally moved to NHibernate that I was satisfied with my persistence mechanism.

Domain Driven Design (DDD) puts the emphasis squarely on the domain model. This means that the main focus is creating a conceptual model that forms a common language for both the users and programmers. Users are almost NEVER interested in how you are persisting their information. NHibernate helps you achieve this mindset by making persistance a concern that's secondary to capturing business rules and understanding what the user really wants from the system.

Fluent NHibernate reduces the impact that changes to your domain model have on the underlying mapping files. It also has auto mapping. While you can never totally ignore persistence for your system, NHibernate with Fluent NHibernate allows you to focus on the domain model. If you're not focusing on using a rich Domain model, there's little benefit to NHibernate.

As regards to testing your mappings, you'd be writing tests (or you SHOULD be) no matter what method you use to implement persistence. This isn't extra work that appears just because you are using NHibernate. Just think of testing your mappings as testing that your persistence works correctly.

Again for this Fluent NHibernate is invaluable. It's got a Persistence Specification Testing that's really simple to use for most cases.

冬天旳寂寞 2024-07-29 01:42:21

PI 并不是关于使用 NHibernate。 PI 代表在开发领域模型时忽略数据的存储方式。 是的,它通过添加一个抽象层来推动依赖性。 DDD 并不是革命性的 - 它更像是一个想法,一种如何使用已经熟悉的模式(大多数都是)进行编码的方法。 即,工厂模式或模块模式也不是新鲜事,但却是 DDD 的非常重要的一部分。

我最近也开始使用 NHibernate,因此无法提供更多有关它的详细信息。 但我得到了一个可能对你有用的提示 - 如果你还没有这样做的话,请尝试Fluent NHibernate

PI isn't about using NHibernate. PI stands for ignoring how data will be stored developing domain model. And yes, it is pushing dependency by adding one more abstraction layer. DDD isn't revolutionary - it's more like an idea, an approach how to code using already familiar patterns (most of them are). I.e. - factory pattern or module pattern isn't new too, yet quite important part of DDD.

I started to use NHibernate quite recently too, so - can't provide much details about it. But i got one tip that could be useful for You - try Fluent NHibernate if you haven't done that already.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文