11使用领域语言编程
Picture two codebases. In one you come across:
假设有两个代码库。在第一个你遇到下面的代码:
You scratch your head, wondering what this code might be for. It seems to be getting an ID from a trader object, using that to get a map out of a, well, map-of-maps apparently, and then seeing if another ID from a portfolio object exists in the inner map. You scratch your head some more. You look for the declaration of portfolioIdsByTraderId and discover this:
你搔搔头,想知道这个代码是干什么用的。它好像是从一个交易者对象那里得到一个ID,用这个ID来,呃,从一个map中得到一个map,然后确认这个内部map中是存在一个合同对象的ID。你再搔搔头。你发现portfolliidsbytraderid声明代码如下:
Gradually you realise it might be something to do with whether a trader has access to a particular portfolio. And of course you will find the same lookup fragment — or more likely a similar-but-subtly-different code fragment — whenever something cares whether a trader has access to a particular portfolio.
渐渐地,你会意识到这可能与交易者是否能够访问特定合同有关。当然,每当遇到需要判断交易者是否能够访问特定的合同的场景,你都会发现相同的代码片段,或者更可能是相似的代码片段。
In the other codebase you come across this:
在另一个代码库中,您会发现:
No head scratching. You don't need to know how a trader knows. Perhaps there is one of these maps-of-maps tucked away somewhere inside. But that's the trader's business, not yours.
根本不需要挠头。你根本不需要知道交易者是怎么知道能否访问合同的。也许交易者有内部就是有一个map的map藏某个地方。但那是交易者的事,不是你的事。
Now which of those codebases would you rather be working in?
现在你更愿意在那个代码库中工作?
Once upon a time we only had very basic data structures: bits and bytes and characters (really just bytes but we would pretend they were letters and punctuation). Decimals were a bit tricky because our base 10 numbers don't work very well in binary, so we had several sizes of floating-point types. Then came arrays and strings (really just different arrays). Then we had stacks and queues and hashes and linked lists and skip lists and lots of other exciting data structures that don't exist in the real world. "Computer science" was about spending lots of effort mapping the real world into our restrictive data structures. The real gurus could even remember how they had done it.
从前,我们只有非常基本的数据结构:比特、字节和字符(实际上只是字节,但我们会假装它们是字母和标点符号)。小数处理有些棘手,因为我们的日常使用的十进制数字在二进制世界中很难精确表示,所以我们需要使用几种长度的的浮点数字类型。然后是数组和字符串(实际上只是不同的数组)。然后我们有堆栈、队列、哈希、链表、跳转列表以及许多其他 现实世界中不存在的令人兴奋的数据结构 。“计算机科学”在将现实世界映射到我们限制性的数据结构时花费了大量精力。真正的大师甚至还记得他们是如何做到的。
Then we got user-defined types! OK, this isn't news, but it does change the game somewhat. If your domain contains concepts like traders and portfolios, you can model them with types called, say, Trader and Portfolio. But, more importantly than this, you can model relationships between them using domain terms too.
然后我们发明了用户定义的类型!好吧,这不是新闻,但它确实改变了游戏规则。如果你的领域中包含交易者和合同之类的概念,你可以用称为交易者和合同的类型来建模它们。更重要的是,你也可以用领域术语来建模它们之间的关系。
If you don't code using domain terms you are creating a tacit (read: secret) understanding that this int over here means the way to identify a trader, whereas that int over there means the way to identify a portfolio. (Best not to get them mixed up!) And if you represent a business concept ("Some traders are not allowed to view some portfolios — it's illegal") with an algorithmic snippet, say an existence relationship in a map of keys, you aren't doing the audit and compliance guys any favors.
如果你不使用领域术语来编码,你就是在创造一种默契(秘密),理解 这里的int 意味着如何识别交易者身份,而 那边的int 意味着识别投合同。(最好不要把他们搞混了!)如果你用一个算法片段(比如用map中的key来表达某种存在关系)来代表一个商业概念(“一些交易者不被允许查看一些合同---这是非法的”),那么你对审计和合规人员没有任何帮助。
The next programmer along might not be in on the secret, so why not make it explicit? Using a key as a lookup to another key that performs an existence check is not terribly obvious. How is someone supposed to intuit that's where the business rules preventing conflict of interest are implemented?
下一个程序员很可能不知道这个秘密,那么为什么不把它说清楚呢?使用一个key查找另一个key来确认访问权限,这种做法并不直观。人们怎么能凭直觉知道,防止利益冲突的商业规则是在哪里实现的?
Making domain concepts explicit in your code means other programmers can gather the intent of the code much more easily than by trying to retrofit an algorithm into what they understand about a domain. It also means that when the domain model evolves — which it will as your understanding of the domain grows — you are in a good position to evolve the code. Coupled with good encapsulation, the chances are good that the rule will exist in only one place, and that you can change it without any of the dependent code being any the wiser.
在代码中明确表达领域概念,意味着其他程序员容易收集代码的 意图 ,而不用去试图将算法改进成他们对领域的理解。这也意味着当领域模型进化时---随着你对领域理解的增长---你就处于代码进化的有利位置。再加上良好的封装,规则很有可能只存在于一个地方,而且你可以在没有任何依赖代码的情况下更改它。
The programmer who comes along a few months later to work on the code will thank you. The programmer who comes along a few months later might be you.
几个月后,继续维护这段代码的程序员将会感谢你,而这个程序员很可能就是你。
Last updated