Showing posts with label domain-driven design. Show all posts
Showing posts with label domain-driven design. Show all posts

Saturday, 11 May 2013

Fixation and variability

While explaining Why Everyone (Eventually) Hates (or Leaves) Maven, Neal Ford divides extensible software into two categories: composable and contextual.

Contextual software is best exemplified by plugin architectures - new features are added by slotting code into explicitly provided extension points. Composable software is best exemplified by the Unix ecosystem - new features are added by wiring together a combination of existing and custom components.

So what is it about contextual systems that provokes such hatred?

The key problem when making software extensible is where to put the variability. I have a fixed set of core features, but I also want others to contribute extra features that vary depending on their needs. How do I bind the fixed and variable functionality together so that they form a coherent system?

Maven accommodates variability like a classic contextual system. The promise (and the curse) of Maven is the consistency of its build lifecycle. There is a place for everything, and everything must be in its place. Maven affords very little flexibility on the relationship between variable additions and its fixed feature set.

Rake, on the other hand, empowers developers by allowing extension via a general purpose programming language. Rake qualifies as a composable system because any means of adding new functionality that can be expressed in Ruby can be used to extend it.

In composable systems, orchestration is variable. In contextual systems, orchestration is fixed. Keeping the means of combination in userland is an additional burden on those who would extend your system, but it's more than offset by the flexibility and power they enjoy in the long term.

Your software will grow, but your relationship with Maven won't. If When that happens, it's time to leave.


Friday, 25 November 2011

Overlapping magisteria

I've written that unit tests and acceptance tests represent two non-overlapping magisteria. I've realised I need to revise this.

Unit tests and acceptance tests specify internal and external behaviour respectively. There is no inherent reason why external behaviour should be trivially translatable to internal behaviour, because the structure of the internals need not bear any resemblance to the model the system presents to the world.

However, that is only true of systems in general. Systems produced using a domain-driven design methodology deliberately enforce structural similarity between the system's implementation and the domain it represents.

Because of this, it's possible to make inferences between external and internal properties of the system. For example, if a
LoginFailure
object returns
true
to the method
shouldLockAccount()
when its
int
field called
previousAttempts
is
2
or greater, there's a good chance that if a user thrice enters the wrong password that their account will be disabled.

If we know something about a well-designed system's external behaviour, we can generally extrapolate about its internal behaviour (and vice-versa).

Wednesday, 18 May 2011

Domain-driven teams

I just watched Phil present on why enterprise architecture usually sucks, and it struck me that his talk resembled a formal argument:
  1. Design always reflects team structure (Conway's law)
  2. Design should reflect the business domain (Domain-driven design)
It seems to me that the following conclusion is inevitable:
  1. Therefore, team structure should reflect the business domain
Logically, Phil's maxim that "what’s easy to change in the business model should be easy to change in your architecture" can only be achieved by structuring teams around domain concepts and avoiding cross-cutting concerns.