Graduate Program KB

Part 1: Putting the Domain Model to Work

  • Every model represents some aspect of reality or an idea that is of interest
  • They ignore the extraneous details and focus on aspects related to the problem
  • The domain of the software is the subject area with a user applies the program to
  • Domains can be physical, or intangible, and typically have little to do with computers
  • To create valuable software, a dev team must have an understanding of the activities it will be used to perform (making accounting software)

The utility of a model in Domain-Driven Design

Three basic uses determine the choice of a Model:

  1. The model and the heart of the design shape each other
  2. The model is the backbone of a language used by all team members
  3. The model is distilled knowledge

The heart of software

  • The heart of software is its ability to solve domain-related problems for its user, all other features support this basic purpose
  • Tackling the domain can be challenging, often the technical talent will want to simply work on what they know best, trying to solve the problems with technology
  • The book uses the example of a shot taken from Monty Python, in which the editor cut out a funny scene due to a minor issue, but by doing so lost the essence of the scene as it was removed entirely, they did not see the bigger picture but rather focused on their own small field of view

Chapter 1: Crunching Knowledge

How can a developer create a piece of software for something which they know nothing about?

  • The first part of this chapter follows the example of designing software for PCB design, where the developer knows nothing about PCBs, and the designers know nothing about software development, an obvious disconnect between the two parties
  • The initial approach was to have the PCB designers tell the developer the software should do, however the proposed changes were not going to lead to a leap in productivity
  • After a first few initial meetings, with the concept of nets coming up multiple times (a wire conductor that can connect any number of components on a PCB), they had the first element of the domain model (Figure 1.1)
  • Through further discussions and diagrams, they were able to evolve the domain model to be more comprehensive, and comprise of more components, the key thing to note in the discussions is the sharing of knowledge from both sides to come to a common understanding
  • Eventually the discussions lead to figure 1.4, as we can see this has built on the original domain model quite heavily
  • The next hurdle came when the developer did not understand the 'pushes' (referring to the component pushing a signal through)
  • Figure 1.6 was created, however the experts reaction showed the previously mentioned disconnect between the two knowledge bases they posses, as the developer is trying to visualise something the expert has said, but has done it in a way that the expert themselves does not fully understand what it means
  • Eventually a simple prototype was made without persistence or a UI
  • The prototype allowed the domain experts to more clearly see what the model meant, and from there the model discussions became more interactive, also from the prototype, the experts had concrete feedback to evaluate their own thoughts
  • As new features needed to be added, they went through the object interactions with the models, and when that failed, they brainstormed new ones, crunching their knowledge

Ingredients of Effective Modelling

  1. Binding the model and the implementation
    • Early prototype was maintained and built upon through subsequent iterations
  2. Cultivating a language based on the model
    • At first there was a disconnect between the language used by the developer and the engineers, eventually they used a commonly shared language centred around the model itself
  3. Developing a knowledge-rich model
    • The model was integral to solving a complex problem, and the objects had behaviour and enforced rules
  4. Distilling the Model
    • It became important to both add and remove concepts to the model as it progressed, when concepts were tightly coupled a new model was created to separate the concerns so a concept could be dropped/added as required
  5. Brainstorming and experimenting
    • A vital aspect, where ideas are formed, became like a lab with testing experimental variations

Knowledge Crunching

  • Effective domain modellers are knowledge crunchers, they have the ability to find a small stream (from a torrent of information) that is the most relevant
  • Knowledge crunching is not a solo operation, typically a team of developers and domain experts collaborate, the majority of the raw material to sift through comes from the domain experts
  • The old waterfall method does not apply here as there is no feedback between the different stages, nobody has the opportunity to learn from other divisions, knowledge trickles in one direction but does not accumulate
  • Another methodology which fails is the use of an iterative process, the project will not end up in a state where powerful new features can be consistently updated/added
  • When good programmers work by themselves, they may be able to develop a model that can do more work, but without domain expert collaboration, the software will do a basic job but lack a deep connection to the domain expert's way of thinking
  • As collaboration continues, the developers begin to learn important principles of the business they assist, and the domain experts begin to refine their own understanding to match that of the developers
  • As these interactions continue, the resulting product is greatly improved, and it also enhances the team's knowledge crunching capacity

Continuous Learning

  • When we set out to write software, we never know enough, or we don't realise how much we don't know
  • Knowledge is scattered or fragmented across many different areas
  • Projects also leak knowledge, experts/people who have learned something tend to move on, knowledge becomes further fragmented, and with typical design approaches, the code/documents will not express the remaining knowledge is a usable form
  • The above point is especially true for tacit knowledge - "The knowledge, skills and abilities an individual gains through experience that is often difficult to put into words or otherwise communicate". Tacit knowledge is typically shared naturally through shared activities like working on a project together, or using a mentor model, this is part of the reason why collaboration is so important. A TDD mindset is not something you can readily verbally communicate, yes there are principles and rules to follow, but the real understanding comes from practising what you've learn and watching/hearing from an experienced and knowledgeable individual
  • This is reinforced by the next paragraph which states that highly productive teams grow their knowledge consciously, practising continuous learning
  • The accumulated knowledge in the minds of a core team of developers who are self-educated make them more effective knowledge crunchers

Knowledge Rich Design

  • The PCB example demonstrates that the kind of knowledge captured in the model goes further than just the surface level findings
  • As a developer's knowledge grows, they should refactor the implementation to reflect that
  • There are sometimes gaps/inconsistencies amongst business rules, and typically domain experts fill in this gaps without knowing by using common sense, this however is something that software cannot do
  • Knowledge crunching and collaboration can manage this shortfall

Example: Extracting a Hidden Concept

Simple domain model that could be the basis of an application for booking cargo onto a voyage of a ship.

  • The responsibility of the booking application is to associate Cargo with a Voyage. This could look something like this:
public int makeBooking(Cargo cargo, Voyage voyage) {
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo, confirmation);
    return confirmation;
}
  • Overbooking is common in industries such as this, as they forecast that a certain percentage (on average) will be cancellations, this way they maximise the amount of business the shipping company can get
  • This knowledge/strategy may not be known or understood by developers
  • This change is reflected in the line below with the 10% additional weighting added
public int makeBooking(Cargo cargo, Voyage voyage) {
    double maxBooking = voyage.capacity() * 1.1;
    if ((voyage.bookedCargoSize() + cargo.size()) > maxBooking)
        return -1;
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo, confirmation);
    return confirmation;
}
  • This hides an important business rule which an application method, later in the book we will see that this should be moved, but for now we will focus on other things
  1. "As written, it is unlikely that any business expert could read this code to verify the rule, even with the guidance of a developer"
  2. "It would be difficult for a technical, non-businessperson to connect the requirement text with the code"
  • Whilst this is just a simple example, it becomes clear that a more complex rule would leave more at stake

  • The overbooking rule is a policy, which is another name for the design pattern known as STRATEGY

  • The concept we are trying to capture fits the meaning of a policy

See diagrams in book

public int makeBooking(Cargo cargo, Voyage voyage) {
    if(!overbookingPolicy.isAllowed(cargo, voyage)) return -1;
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo, confirmation);
    return confirmation;
}
// Within overbooking class
public boolean isAllowed(Cargo cargo, Voyage voyage) {
    return (cargo.size() + voyage.bookedCargoSize()) <= (voyage.capacity() * 1.1);
}

Now it becomes clear TO ALL, that overbooking is a distinct policy and the implementation of that rule is explicit and separate. The more explicit design has some advantages to it:

  1. Programmers and everyone else involved will have come to understand the nature of overbooking as a distinct and important business rule with this change.
  2. Programmers can show business experts technical artifacts, even code, that should be intelligible to domain experts (perhaps with some guidance), thereby closing the feedback loop.

Deep Models

  • Useful models seldom lie on the surface, they must go through many revisions, with subtle abstractions emerging, or what we deemed important elements at the start being later discarded
  • The shipping model is one such example of this, through further discussion they found that the handling of cargo was not so centralized as they had previously thought, in fact it is handled by many different parties throughout its life cycle
  • This deeper understanding required the model to be profoundly changed, it now became transferring responsibility from entity to entity rather than simply moving containers from one place to the next

"Knowledge crunching is an exploration, and you can't know where you will end up."