Monday, May 17, 2010

DDD and pragmatism

The human brain can forge the unlikeliest of connections between disparate concepts. Domain-driven design (DDD) is a software development perspective which is described in a book and a website. Pragmatist philosophy answers fundamental questions about human existence through a framework which is described among other sources in a book of writings by William James (here I'll refer to it simply as "pragmatism" although the more accurate term is probably "Jamesian philosophy" as a whole). These two strands of thought resonate with one another in a few ways. Apologies up-front if I massacre either in my descriptions.
  • DDD insists at all times on a domain model that matches up with how the code really executes. For instance, it advises 1) using the same domain language from analysis to design to code (i.e. "ubiquitous"), 2) unifying analysis and coding to prevent the accidental creation of impractical designs, and 3) starting out any refactoring by first inferring all the current domain models and contexts and the mappings in-between. In pragmatism, statements are also put into effectual, practical terms. A statement that has no consequences has no grounds for consideration. A pragmatic philosopher approaches a statement by asking, "If this statement were true, then what difference would it make, either to my experiences or to my actions?" Just as a domain model that isn't reflected in the code is worse than no model at all, a statement that posits an utterly immaterial idea is a waste of philosophers' time.
  • Early on, DDD raises a crucial distinction between a domain model's truth and its usefulness. It's neither required nor recommended that the model be an exact replica of the domain. The model's purpose is to adequately cut through the complexity of the domain such that all participants, user and analyst and developer and code, can accomplish the work effectively. A model is one particular organizational scheme that cleanly breaks up the problem along natural contours, which is why the appropriate model for a domain depends on whatever problem is to be solved. Meanwhile pragmatism also distinguishes between truth and usefulness but by redefining truth as something known-as usefulness. That is, truth itself is a process. It's obtained neither by mere abstract logical argumentation nor by mere sense experiences but by the actions and decisions and reactions of people upon the reality kaleidoscope. As DDD practitioners select a domain model according to their needs based on relevant criteria and data, pragmatists select the truth of all statements based on a range of needs and constraints that are objective or subjective.
  • In DDD, people "crunch knowledge". The software specialists learn from the domain specialists and attempt to summarize the salient factors and operations into a domain model of ordinary-named objects that "makes sense" and facilitates meaningful communication about the software. But everyone involved should recognize that the model will change. Whether the cause is a significant disruption within the domain, a realization that the model isn't suitable for implementation due to technological constraints, or a deeper level of understanding, successive pieces of knowledge are crunched into the model and ideally result in a breakthrough to the software applying greater power, simplicity, and/or flexibility to the problems of the domain. Therefore the sign of the domain model's maturity isn't eternal perfection; it's the model's suppleness, which is its relative ease of accommodating further improvements. This notion of continuous, ongoing improvement is reminiscent of pragmatism's preference for evolutionary truth. Pragmatic truth isn't found in universal conclusions reached by closeted skeptics. It's built bit by bit as people tango with realities (whether those realities happen to be "outside" or "inside" one's self). This theory of truth is "dirtier" and less "ambitious" than the confident pronouncements made by philosophies that presume that Truth stands alone. However, the total mound of individual pragmatically-obtained truths is arguably much more reflective of the reality in which humans actually live. A straw man of pragmatism is that it asserts that "all of reality is whatever someone likes it to be". However, this argument ignores the stepwise accumulation of knowledge portrayed by pragmatists. It should go without saying that it's not pragmatic at all to disregard the entirety of one's prior discoveries in one swell foop by a disembodied leap of one's imagination. "I reject your reality and substitute my own" is certainly allowable (where would we be if we never tried to falsify predominant hypotheses?) but only to the limited degree that the individual judges and then decides it to be sensible and rational in the present case.
  • When I first read about DDD, the extent to which it emphasizes communication took me by surprise. DDD repeats the importance of communication throughout, whether from customer to analyst, modeler to developer, module-team to module-team. One of the justifications behind having a communal domain model is to "anchor" everyone's language to the same meanings. Otherwise, like when there are separate models for the purposes of analysis and implementation, potentially useful information and feedback won't flow as well and people must expend effort on translation rather than forcing the domain model into an understandable shape that intimately connects the software to the domain experts' expectations. The ideal code-to-model connection is so close that the unit tests for the domain objects are largely intelligible to the domain experts who know the model and the context. (This does NOT mean that ALL code objects in the functioning system need to be known by the domain experts. Proper layering, perhaps using techniques like dependency injection to transparently and loosely connect layers, should at least partially eliminate the need for someone to know the "gory details" to comprehend the domain layer.) The model objects are commonly-acknowledged referents for project communicators who refer to them by name. Similarly in pragmatism, any name of an objective entity is an operator. Keep in mind that an untested reference doesn't imply the reference is meaningless. Part of the meaning of a location's name refers to the proposition that I would be at that location if I traveled there. In principle, what makes a reality objective is an agreement between people about that reality's implications and verification. Of course, locations (or anything in plain view) are less arguable than generalized concepts like "chair". When I say "chair" I might be referring to a chair like the chair at my desk that easily adjusts its height and can spin, while when you say "chair" you might be referring to a chair like the one in front of your television set that's extra-cushy and has a reclining function. Clearly, since the operations and sensations that I describe about my "chair" are different than your "chair", we must pragmatically be meaning different things by the same term. Although my set of experiences differs infinitely from yours in any number of ways (I'm curious if I could prove the set of differences to be uncountable by the natural numbers), we can still cooperate and communicate on a pragmatic basis provided that we can keep our meanings sufficiently attuned for whatever end we are pursuing. In DDD, the purpose is the project, and the model of the domain objects' attributes and methods and relationships is the negotiated "agreement zone" between what the software experts and the domain experts jointly affirm about the domain's problem and solution. When I say "account", I mean the account class in our domain model whose properties, behavior, and interdependencies are all explicitly laid out; when the domain expert starts stating facts about accounts that aren't captured by the model, everyone can see that the model may need to change once more.

No comments:

Post a Comment