In the article preview image: Gnucash uses accounts for amounts of money but also for expenses, consistently with the double-entry bookkeeping model.
Conceptual integrity is the property of a system to work on a consistent set of concepts, such as entities (user, groups, posts) or operations (transfer money to an account or convert it in different currencies). If a railway system has three different websites for selling tickets (I know of at least one case), each with different functionalities, its overall system lacks conceptual integrity.
The single architect
In one of the essays in the Mythical Man-Month, Fred Brooks talks about conceptual integrity, advocating that a single architect should maintains its own vision for the product and take architectural decisions for the rest of the team.
The responsibilities of this mythical architect should be:
- deciding which features to include, and which to postpone or cut.
- Validating new ideas from other people.
- Keeping complexity and costs down.
The idea is that fewer features can be developed, with the benefit of an increased integrity. You already know that some companies prefer minimalism and integration (like a single mouse button) trading away capabilities for it.
However, the idea of a single person producing every bit of architecture tries to separate architecture from implementation. Would that be possible? Probably yes, but how effectively? If you have ever developed code from someone else's UML diagram or CSS file, you know what I mean.
The Poppendiecks take a weaker stance on conceptual integrity: it would be really difficult to scale the work of one person (or of a small team) to an entire product. It would also deprive a large part of the colleagues of the capability of exercising their intelligence and taking decisions.
Thus Lean practices were invented to improve the communication among all the groups that participate to product development. In the case of cars (automotive examples are the norm in Lean texts) these groups are from design, marketing, engineering or manufacturing departments. In the case of software, the groups are usually cross-functional team that develop different systems that have to work together.
In the case of railways tickets, there are several vertical slices of functionality that are always break up into subsystems: the web sites (front ends), back ends for updating ticket prices and timetables, accounting systems for generating invoices or accepting payments. When each of these components contributes to the final product (selling train trips), conceptual integrity is a quality of their integration. In other cases subsystems are broken out *because* it is too complex to maintain them together and they should evolve independently.
However, conceptual integrity is a fractal property of software: you can evaluate it between subsystems, but also between classes and methods of a codebase, or (at an intermediate level) between the UI layer and the domain one. The classic solution "I'll just put an if() inside the user interface" creates many problems when the kind of logic we're introducing is not strictly part of presentation: conceptual integrity of the ensemble is lowered and a developer looking to update or improve this logic doesn't know where to look first.
The Poppendiecks propose to copy some automotive practices to improve conceptual integrity between parts of the system working on very different concerns. Let's be careful in adapting them to our context, keeping in mind that the daily activities of sofware development is analogue to the *design* phase of a car and not to the *manufacturing* phase.
- Use existing parts, even internal ones that have been developed in your company (assuming their quality is high enough for reuse). Engines are commonly shared between cars of different models. This reduces not only cost (you're not writing that code) but also risk as you're borrowing a design that has worked in the past instead of starting from scratch. With open source software we often reuse code, but standards such as JSON or open file formats are reuse too.
- Integrated problem solving means to early connect business, software, marketing people and everyone that should be involved. While you're working on a 1000-line class to support a requirement, the user of the software has already in mind a way in which the application would work the same but less costly for you.
- Put experienced people in critical points (isn't that obvious?) We often trade-off the presence of experience with efficiency, putting a junior to work on a complex component just to use up its time. Have you ever heard of a company introducing a test suite by having it written from the last person hired? What was the result?
Conceptual integrity is not only an internal quality of software (like coupling and cohesion) but also a measure of the match between the models used in different parts of the application and the one in the user's head. The easier communication between team members with different expertise is, the higher the conceptual integrity of the final product: you don't have to put an if() in the user interface to deal with a corner case if you can tell the back end developer to revise a domain model operation in a minute.