Key insights that you probably missed on DDD

As suggested by its name, Domain-Driven Design is not only about Event Sourcing and CQRS. It all starts with the domain and a lot of key insights that are too easy to overlook at first. Even if you’ve read the “blue book” already, I suggest you read it again as the book is at the same time wide and deep.

You got talent

The new "spoken" language makes heavy use of the thumb
A new natural language that makes heavy use of your thumbs

Behind the basics of Domain-Driven Design, one important idea is to harness the huge talent we all have: the ability to speak, and this talent of natural language can help us reason about the considered domain.

Just like multi-touch and tangible interfaces aim at reusing our natural strength in using our fingers, Eric Evans suggests that we use our language ability as an actual tool to try out loud modelling concepts, and to test if they pass the simple test of being useful in sentences about the domain.

This is a simple idea, yet powerful. No need for any extra framework or tool, one of the most powerful tool we can imagine is already there, wired in our brain. The trick is to find a middle way between natural language in all its fuzziness, and an expressive model that we can discuss without ambiguity, and this is exactly what the Ubiquitous Language addresses.

One model to rule them all

Another key insight in Domain-Driven Design is to identify -equate- the implementation model with the analysis model, so that there is only one model across every aspect of the software process, from requirements and analysis to code.

This does not mean you must have only one domain model in your application, in fact you will probably get more than one model across the various areas* of the application. But this means that in each area there must be only one model shared by developers and domain experts. This clearly opposes to some early methodologies that advocated a distinct analysis modelling then a separate, more detailed implementation modelling. This also leads naturally to the Ubiquitous Language, a common language between domain experts and the technical team.

The key driver is that the knowledge gained through analysis can be directly used in the implementation, with no gap, mismatch or translation. This assumes of course that the underlying programming language is modelling-oriented, which object oriented languages obviously are.

What form for the model?

Text is supplemented by pictures
Text is supplemented by pictures

Shall the model be expressed in UML? Eric Evans is again quite pragmatic: nothing beats natural language to express the two essential aspects of a model: the meaning of its concepts, and their behaviour. Text, in English or any other spoken language, is therefore the best choice to express a model, while diagrams, standard or not, even pictures, can supplement to express a particular structure or perspective.

If you try to express the entirety of the model using UML, then you’re just using UML as a programming language. Using only a programming language such as Java to represent a model exhibits by the way the same shortcoming: it is hard to get the big picture and to grasp the large scale structure. Simple text documents along with some diagrams and pictures, if really used and therefore kept up-to-date, help explain what’s important about the model, otherwise expressed in code.

A final remark

The beauty in Domain-Driven Design is that it is not just a set of independent good ideas on why and how to build domain models; it is itself a complete system of inter-related ideas, each useful on their own but that also supplement each other. For example, the idea of using natural language as a modelling tool and the idea of sharing one same model for analysis and implementation both lead to the Ubiquitous Language.

* Areas would typically be different Bounded Contexts

Read More

Big battles are won on small details

Small details matter because you deal with them often. Any enhancement you make thus yields a benefit often, hence a bigger overall benefit. In other words: invest small care, get big return. This is an irresistible proposal!

balance
Every single step matters

Examples of small design-level details that I care about because I have experienced great payback from them:

  1. Using Value Objects rather than naked primitives
  2. One argument instead of two in a method,
  3. Well-thought names for every programming element
  4. Favour side-effect free methods and immutability as much as possible
  5. Keeping the behaviour close to the related data
  6. Investing enough time to deeply distillate each concept of the domain, even the most simple ones

Ivan Moore has an excellent series of blog entries on this approach: programming in the small.

All these details emphasize that code is written once then used many times. The extra care at time of writing pays back at time of using, each time, again and again. Each enhancement that minimises brain effort at time of use is welcome, because software design is a matter of economy.

Other kinds of “details” that I care about involve the human aspects of crafting software: being on site, face-to-face communication rather than electronic media, respect and consideration at all times, always celebrate achievements, etc. Because ultimately, it also boils down to people that feel like building something together.

Read More

Degrees of freedom analysis

The concept of degrees of freedom looks so relevant to software development that I am wondering why it is not considered more often. Fortunately Michael L. Perry dedicates a full section of his blog to that concept. In this post I will quote a lot, please consider that as a sign of enthusiasm.

A common concept in maths

The concept of DOF is central in solving systems of linear equations, and in the main post of his series, Michael L. Perry starts by focusing on mathematical system of linear equations:

A mathematical model of a problem is written with equations and unknowns. You can think of the number of unknowns as representing the number of dimensions in the problem.

Depending on the number m of equations compared to the number n of unknowns (variables), there are several cases:

  1. m > n: there is no solution, the problem is over-constrained
  2. m = n: there is only one solution
  3. m < n: the system is under-determined system, and the dimension of the solution set is usually equal to n ? m, where n is the number of variables and m is the number of equations.

A common concept in mechanics

3 legs are enough to be stable, but tables usually have 4 legs anyway.
3 legs are enough to be stable, but tables usually have 4 legs anyway.

The concept of DOF is prevalent in mechanics. In particular, a system with more internal constraints than the total possible number of DOFs has no solution. However in practice it can still work, provided some of the bodies are not absolutely rigid.

The table is often given as an example, because it only needs three legs to be stable on the ground, but usually has 4 legs. This only works because the table is not fully rigid, and can accommodate the small imperfection of the ground.

Not yet common in software

In his post, Michael L. Perry explains in practice how to analyse software using DOF. First find the unknowns:

To identify the degrees of freedom in software, start by defining the unknowns. These are usually pretty simple to spot. These are the things that can change. In a checkbook program, for example, each transaction amount is an unknown, as are the the account balance and the color used to display it (black or red).

Then find out the constraints between the DOFs.

Next, define the equations. These are the relationships between the unknowns that the software has to enforce. In the checkbook, the balance is the sum of all transaction amounts. And the color is red if the balance is negative or black otherwise.

Finally:

Subtract to find your degrees of freedom. One amount per transaction (n), one balance, and one color gives n+2 unknowns. The balance sum and the color rule give us two equations. n+2-2 = n degrees of freedom, one per transaction.

What for?

Quoting again Michael L. Perry (across various posts in the DOF category):

Understanding the degrees of freedom in the software helps to create a maintainable design.

Adding independent data to a system increases its degrees of freedom. Adding dependent data does not. Adding an immutable field does not.

You want no more degrees of freedom in the system than the problem calls for.

The concept of degree of freedom is remarkably useful to help distilling the domain down to the essential variable parts and the constraints between them. Any extra independent data can only create opportunities for bugs.

Read More

Design your value objects carefully and your life will get better!

Many concepts look obvious because they are used often, not because they are really simple.

Small quantities that we encounter all the time in most projects, such as date, time, price, quantity of items, a min and a max… hardly are a subject of interest from developers “as it is obvious that we can represent them with primitives”.

Yes you can, but you should not.

I have experienced through different projects that every decision to use a new value value object or to improve an existing value object, even very small and trivial, was probably the design decision that yields the most benefit in every further development, maintenance or evolution. This comes from the simple fact that using something simpler “all the time” just makes our life simpler all the time.

We often dont pay attention to the usual chair, however it was carefully designed.
We often dont pay attention to the usual chair, however it was carefully designed.

As a reminder, value objects are objects with an identity solely defined by their data. Using value objects brings many typical benefits of Object Orientation, such as:

  1. One value object often gathers several primitives together, and one thing is always simpler that a few things
  2. The value object can be fully unit-tested: this gives a tremendous return, because once it is trusted there will simply be no bug about it any more
  3. Methods that encapsulate even the simplest expression with a good name tells exactly what it does, instead of having to interpret the expression every time (think of isEmpty() instead of “size() == 0”, it does save some time each time)
  4. The value object is a place to put documentation such as the corresponding unit and other conventions, and have them enforced. Static creators makes creation easy, self-explanatory, can enforce the validations and help select the right unit (percent, meter, currency)
  5. The method toString() can just tell in a pretty-formatted fashion what it is, and this is precious!
  6. The value object can also define various abilities, such as being Comparable, being immutable, be reused in a Flyweight fashion etc.

And of course, when needed it can be changed to evolve, without breaking the code using it. I could not imagine a team claiming to be really agile without the ability at least to evolve its most basic concepts in an easy way.

The first time it takes some extra time to build a value object, as opposed to jumping to a few primitives; but being lazy actually means doing less in the long run, not just right now.

Read More

How I became enthusiastic about patterns

In my very first job, I  was doing R&D, working on a map-matching algorithm. The goal of this algorithm was to pinpoint a moving car on a vector map, based on the data from various sensors, including a GPS, an electronic compass and the car odometer. Such algorithm was essential for the business of the company, and there was very little literature on the subject.

The R&D challenge

At school I had been taught some C programming, so I started doing the algorithm in plain C code. One special case after another, the code began to grow until it became quite complicated. I had a specially equipped car with a computer and all the gear in it to do real testing on the roads around the office, from the highway to forest road, city streets or even car parks, and this was fun! But situation after situation, I had to make the code more and more complicated. At some point, it became obvious to me that the mode of implementation (plain C code) had become the main obstacle for improving the algorithm. It was becoming increasingly difficult to grow the sophistication in a mess of structured code.

My early mentors

Yes savoir-faire can be found in books (but not only)
Yes savoir-faire can be found in books (but not only)

At the same time I was willing to progress, so I was getting closer to the few very experienced colleagues. Our company was a startup in 2000, and there were many more junior developers than senior ones. At first, I thought UML could help me (it did not indeed) so I started asking questions about UML. When I became more comfortable with UML, a senior colleague told me I should now have a look at design patterns, starting with the Composite. So I took the GoF book on my desk and began to look at it as a reference to get design ideas during the day. I also borrowed the pattern pattern book from Mark Grand and read it in the train.

And then it has been “Wow patterns are a great way of transfering knowledge!”. I remember reading the pattern “Cache” in the book. It was not in itself a very innovative design idea, but I understood that the pattern format was ideal to document just any idea. I hate long explanations in long books, and the pattern format, which tends to be short and structured, is perfect for quick scanning whenever you’re looking for ideas. Even when I didn’t find a pattern for my case, I found it stimulating to read other people ideas.

Enthusiasm and success as a result

I started to apply the State and the Strategy patterns into the map-matching algorithm and this made it much, much simpler. It actually made it so much simpler that we were now able (the team was growing at that time) to go an order of magnitude further in sophistication, while being perfectly in control of the code. The introduction of two simple design patterns had suddenly given a really big advantage to a piece of code essential to the company! This is how I became enthusiastic about patterns.

The reality

I am also enthusiastic about deserts.
I am also enthusiastic about deserts.

What actually happened is that reading and starting to play with patterns just taught me object-oriented programming. Patterns acted like examples of good design, until the underlying principles became natural. Later I discovered the SOLID principles of Robert C. Martin, and recognized the principles behind many design patterns. In my next job experiences I took the habit to look for patterns for whatever problem I was encountering, and to my surprise, I found out that most common problems were already being taken care of in the form of analysis patterns or other kinds of patterns! To give the most obvious example, Martin Fowler “Things that change with time” is really a must-read, which you can apply easily to solve your problem.

Conclusion

This is how I became enthusiastic about pattern, not just design patterns but every kind of patterns, from analysis patterns to domain driven design patterns, enterprise integration patterns, PLoP patterns and many patterns from various authors. I know my enthusiasm is a bit exaggerated, a bit like the souvenir of a first love that cannot be much objective. Fortunately I quickly learnt when not to use patterns, to keep things as possible as they can be, and to do unit testing. By the way the benefits of unit tests also struck me when I started with them, but not as much as patterns, there can be only one first time, and my first first time was with patterns, not unit tests!

Read More

Manipulating things collectively

There is great power in being able to manipulate collective things as one single thing. It gives you simplicity, hence control. You can focus your attention on it and reason about it, even though behind the hood it is made of many parts. The composite thing is kept simple, therefore you can also deal with several of them at a time. This would not be possible if you had to deal with every part they are made of, because it would be overwhelming.

There exists many strategies to deal with collective things as if they were one single thing: statistics, multiple selection, groups, classifications and super-signs.

Statistics

Statistics is probably the most obvious way to deal with collective things, when the things can be expressed as numbers. Historically it has been used with great results in physics, thermodynamics in particular.

It is all about extracting a few macro properties that we can reason on instead of the whole set of data:

  • number of elements
  • mean, deviation, moments, percentiles, etc.
  • regression, clusters
  • total property: total weight, total volume, total price

Multiple selection

Many software applications enable you to select multiple elements at a time in order to apply one operation to each element:

Arman accumulation
Arman accumulation
  • When sending an email, you can select multiple addresses to send to
  • In a word processor, you can select several words, several paragraphs, or even all the document to copy, paste or apply formatting to each element
  • In a spreadsheet, you can select multiple rows or columns to apply operations to, and you can also repeat formula for each row or column

The selected elements can be of the same kind or not. However for multiple selection to be useful, they must share at least something in common: the capability of being copied or pasted, or the fact that they are specific for a particular user.

Functional programming and the three higher order functions map, fold and filter address very well how to apply operations collectively to many elements.

Groups

When multiple selections are often needed, you can create groups. We can consider a group to be a multiple selection made explicit. You create a group and you explicitly add elements to it. Common examples of groups:

  • Mailing lists are named groups of email addresses
  • Vectors in maths

As for multiple selection, the elements in a group must share something in common. For example, they must all have a price. Elements of various kinds can be grouped if they relate to something common, for example  the set of various data (name, address, phone number, preferred colour and date of birth) specific for a user is called a user profile.

A group is extensional. The elements in the group may or may not know they belong to a group.

Java packages are groups, and they are declared within the same file as the elements they refer to. Java classes also group fields and methods under one name.

The Composite pattern suggests to group objects that share the same interface into a Composite that also shares the same interface. The intent is to manipulate the collective set of objects as if it was one single object, i.e. without knowing it is collective.

Classification

You get control over multiple things if you just classify them. Given several flowers, if you classify them into categories, then you can talk about several flowers collectively without having to enumerate each of them: the category is a way to refer to several flowers with just one name.

Classifications enable intensional grouping. This means that groups are defined not by the set of their elements, but by a condition (predicate) to be satisfied. The condition can test for the category of something (is this animal a bird?), or test for its attribute (is this car red?).

Of course abstraction is one particular way to classify.

Java modifiers (private, public, abstract, interface etc.) classify Java elements, and can be used to refer collectively to them, as in “let’s generate the Javadoc for every public elements”.

Super signs

Super-sign
Super-sign

There are elements that exhibit a special property when considered together as a whole. For example, the ink dots on the paper can be seen as letters. Letters next to each other can be seen together as words, which again can be seen together as sentences, and then again up to the novel. Collective arrangements of multiple things that together exhibit a property are called super signs.

This phenomenon is related to emergence, and only exists for a given observer if he can recognize the super sign.

In science in general, we use models to account for the collective behavior of several elements, typically objects with measurable properties, and forces in action.

In a Java program, idioms and patterns can be considered super signs for those who know them.

Conclusion

Manipulating multiple things in a simple way really matters, it is a life saver.

In software development it is paramount because it is a lever you use to manage tons of data with no effort. The art is to find the way you think about collective things that reduces the most your effort.

I already mentioned this topic in previous posts: group together things that go together, don’t make things artificially different, and my definition of abstraction, because abstraction is an essential way to refer to different things in what they share in common.

Read More

Patterns as another kind of types

Patterns represent a couple (intent, solution), where the intent matters most. Based on that intents, that can be generic or specialized, I propose to consider patterns like types in languages with strong typing, for the compiler to enforce their constraints.

Declaring patterns: what for?

Consider the very simple Quantity pattern from Analysis Patterns (Fowler):

Represent dimensioned values with both their amount and their unit

By simply declaring this pattern, we immediately express many things:

  1. We wish to represent a quantity with its unit
  2. Quantity is a special kind of ValueObject (as in Fowler or DDD), hence:
    1. It is Immutable, therefore it has no setter, only a valued constructor
    2. Identity is based solely on its values, two value objects are equal if they share the same values
  3. In Java, the hashcode() and equals() methods must be implemented solely on the values of the immutable fields, and the hashcode can be cached internally; the toString() result can be cached as well
  4. In the spirit of Domain Driven Design, it also probably follows Closure of Operation and Side -Effect-Free Functions
  5. It must not depend on any heavyweight dependencies such as middleware, database or gui classes
  6. It must not depend on Entities and Services
Strangely typed furniture
Strangely typed furniture

If we had an explicit way to mark the use of the pattern in the code, and if the compiler was able to know about this pattern, then it could enforce all the above. Moreover, it could also generate corresponding unit tests to assert the dynamic and runtime aspects constrained by the pattern.

This approach can be considered similar to the typing used in programming languages, where the compiler can enforce many constraints according to the type declarations given by the developer.

In practice

In current languages there is no explicit way to declare the use of patterns in the source code. The reader of the source must pay attention to various hints and compare to his/her prior knowledge to decide whether or not a pattern is used. Typical hints include naming conventions, where the class or interface names ends with the name of the pattern participant: an interface TradeFactory is probably a Factory that creates Trade instances.

Since many years I have been using a custom Javadoc tag @pattern to explicitly mark the patterns I use in my source code, hoping that a tool could use it in the future. Over time I have noticed several benefits from doing that, the biggest one being that I am forced to be 100% clear about what I want. Many times I noticed that asking myself to explicitly declare in patterns what I was doing required me to think deeper. Though I know what I am doing, when trying to express that intent using patterns from the books I am forced to clarify my intent to decide which exact pattern I am applying.  This is fully in the spirit of the Pragmatic Programmer‘s “Programming by Coincidence“, and also in the spirit of Test Driven Development where the unit test is forcing you to clarify what you really want.

In other words, we could call that Pattern Driven Development. PDD, yet another acronym!

Yet another strangely typed object (the disco vaccum cleaner)
Yet another strangely typed object (the disco vaccum cleaner)

Discussion

It may not sound intuitive that there exists a documented pattern for each and every possible design decision, but I can confirm that the panel of existing patterns is very wide and already covers a lot of common design decisions. Such patterns are far from sophisticated solutions or tricks, they usually just name intents and known practices. But this is exactly what we need. Dirk Riehle, in a recent paper entitled Design Pattern Density Defined, found that in the case of open-source frameworks, and considering only classic design patterns, the density of such patterns was between 40 and 70%, where density is defined by “The design pattern density of an object-oriented framework is the percentage of its collaborations that are design pattern instances.

In addition, it becomes increasingly common for software teams to use custom patterns as a convenient way of documenting their common design practices. Actually this is how the pattern story began when Kent Beck and Ralph Johnson decided to document the design of HotDraw in the now classic paper: Patterns generate architectures. To illustrate that, the Drupal team is using custom patterns in addition to standard patterns to document their design in an efficient way, as described in the program of the DrupalCon Paris 2009 conference:

This session will cover the how and why of design patterns, and review the most common patterns used in Drupal as well as a number of common patterns we could be using. Some are Drupal-specific patterns and some more more general software design patterns.

Another major example of patterns dedicated for a particular project is the the Eclipse IDE. Erich Gamma, the main Eclipse designer -one of the Gang of Four- wrote the book Contributing to Eclipse: principles, patterns, and plug-ins (together with Kent Beck) where Eclipse-specific and standard patterns are used together as the primary mean of documenting the design.

Conclusion

Patterns are signs to denote intents, and I propose to promote the use of patterns (patterns already existing or to be defined in the context of a particular project) to trace these intents explicitly, and to enable tools to enforce pattern-specific constraints.

Pictures taken at la Biennale Internationale Design, Saint Etienne 2008

Read More

Software design as a matter of economy

Economy is the management of limited resources. In software development the limited resources (*) are:

  • memory of the developer: names of types, methods signatures, tricks to know
  • time available to learn or discover new things

Therefore, every design decision should attempt to reach an optimal balance between both memory and time being consumed in the developer head.

Memory effort for the developers is positively reduced with:

  • less abstract types to know (make interfaces more generic, use more polymorphism, favor generic approaches)
  • less methods in interfaces (minimal interfaces)
  • logical system of conventions: classes/methods naming (idioms)
  • frequent use of the same set of concepts (patterns)
  • sharing of one same ubiquitous language between business talking and technical models (sharing of words as resources)

Time to learn:

  • more expressive names, dedicated for the case at hand (less generic)
  • humane interfaces (easier to find how to use them)
  • value objects, that bring explicit names even for simple primitive-like things
  • favor specialized classes and interfaces (that reflect the concrete elements of the domain) rather than generic interfaces
  • use practices, idioms and patterns already well known within the team

As usual, the optimum has to balance opposite forces, and will be somewhere between the two extreme approaches: smaller, full generic but totally unexpressive, or fully specialized, hence with some duplication of ideas but more expressive.

By making more concepts of an application sub-types of few interfaces, we obviously reduce the memory effort to deal with the code base: once created, instance of various types can be used under the same interface. Design patterns often also propose their participants to adhere to some existing interface (think about the Composite, Decorator, Proxy, Object Adapter) also encourage this trend.

On the other end there are design patterns that definitly make a design more costly for both limited resources, typically by introducing extra interfaces with no gain of expressivity. To discuss this case we need to introduce an extra quality criteria on top of our limited resources: the need for extensibility or flexibility. In this discussion design decision need to consider three antagonist forces: the memory effort in the developer head, the time needed by the developer to learn the code base, and the need for flexibility.

Every developer that feels concerned about maintenability or teamwork should be aware about this trade off in order to address it explicitly rather than just by gut feeling. For instance, the more unexperienced the coworkers, the less generic a design should be if they have to support it without help, but opportunities to rationalize the design will be wasted, hence some loss of agility. On the other hand one can decide to go more generic anyway while doing something to improve the expressivity of the code, e-g by introducing empty, useless but expressive sub interfaces just for the sake of expressivity (Taxonomy), or doing some effort on the documentation and training.

This approach of explicitly dealing with the memory and time being consumed in the developer head may suggest new metrics about design quality. I do not have the pretention to propose good metrics here but here are some ideas:

  • number of different interfaces (or number of fully qualified method signatures) over size of the code base (maybe with smaller weighting on constructors) as a way to estimate how much memory is needed to be on top of the code base
  • proportion of domain-specific names (e-g “Tax”, “Shipping”) within the code base as a way to estimate how specialized the code is
  • proportion of abstract words from a corpus (such as “data” or “processor”) within the code base as a way to estimate how generic the code is
  • amount of abbreviation and Flesher reading test applied for type and methods naming as a way to estimate how fast it is to discover the code base
  • number of explicitely mentioned idioms and patterns (either by javadoc documentation or obvious naming conventions) over size of the code base

(*) We assume here that runtime efficiency is not a constraint since this discussion focuses on software development methodology and human to machine aspects.

Read More

Sharing a common architecture or vision within a team

What do you think about when you hear the word “architecture” about software? Fowler defines it: whoNeedsArchitect “In most successful software projects, the expert developers working on that project have a shared understanding of the design system design. This shared understanding is called ‘architecture.'”.

However for most people the word “architecture” comes full of middleware connotations, hence I consider this word now inappropriate. Let us consider here the concept of a shared “vision” of the design.

First it has to be a shared vision of the domain, for instance the interest rate swaps trading business. Words must have only one meaning, known by everyone, from IT, marketing or support. A shared glossary is key for that.

Then the IT team must share a consistent set of practices: consistent between developers, and consistent between practices themselves. This also means that the set of practices de-facto excludes other practice that conflict with it, and this has to be clearly acknowledged.

Even though any set of practices can be considered arbitrary, everybody in a team must adhere to it, preferably wholeheartedly. Of course the more accepted and documented the practices, the easier it is for everybody to adhere to them.

For example, a team can have a set of practices that includes Agile programming (be prepared for change, no big design upfront), automated testing (unit tests, stress tests), domain-driven analysis as devised by Eric Evans, the use of proven solutions when they exist (hence design and analysis patterns from GoF, POSA, Fowler, Doug Lea…), a bit of functional-programming style (favour immutability and side-effect-free functions, pipe and filters…), and Eclipse default coding conventions.

Some practices that also belong to the shared set of practices might not be directly documented, though they derived from articles, papers, blogs and some personal opinions. Examples of such custom practices that I like a lot include “Align the code with the business” and “think options not solutions”.

“Align the code with the business”, focuses at the smallest level, i.e. at the class and method level. Just every bit of the application must make sense with the domain considered. A class must reflect some relevant concept, concrete or more abstract, of the domain, not of the requirement. The rationale is that while requirements change all the time, the domain concepts are very stable; they are not true or false, they just exist!

“Think options not solutions” refers to the very basics of Agile and XP: “be prepared for change”. It also acknowledges the fact that most of the code in a well done software project provides standalone, encapsulated and reusable building blocks that are then assembled together using a smaller amount of glue code, that can even be reduced by using a dependency-injection framework such as Spring. Typically, a concept from the domain, such as an interpolation algorithm in the finance domain, translates into an Interpolation interface along with several alternate implementations. Most of the time, only one implementation out of the ten possible is really used at a time. However the option to use the other nine alternatives is there. This also means that we can assemble a release of the software using some subset of its building blocks, and assemble another release using another subset, at the same time. One codebase, several possible applications: this is the goal.

In addition to every explicit practices, the existing code base implicitly shows practices that can either be reused just for the sake of consistency, or replaced as widely as possible when they conflict. Prior art, when of good-enough quality, can form a skeleton for a shared vision of how to create software. Again this is arbitrary, but consistent, and consistent design is valuable in itself, and often more than the design decisions themselves.

Of course there is a point where more shared practices become counter-productive, for instance when there are too many of them (more efforts to learn by newcomers, feeling of loosing freedom, lack of flexibility). However when they are standard enough, or becoming standard enough, developer should consider that acquiring these practices a long term, beneficial, investment.

Initially published on Jroller on Monday January 21, 2008

Read More

Software development is more than mastering syntax

When a junior developer joins our team, it is interesting to realize how mastering language syntax and API is just a small part of the skills that matter.

Just after the syntax and API knowledge (actually knowing where to find what you want in the API is enough), there are a few other skills you definitely must know.

First is unit test. It is not difficult to begin with that, it is not that easy to tune tests so that they dont depend on too many things, to save time when refactoring. Also mocking objects is the next step.

Mastering dependencies is another key to successful software development. Dependency Injection is a buzzword for a very simple idea, that everyone can apply only by being aware to do the ”new” where is it most convenient to change, using valued constructors or setters.

Design patterns are of course an essential tool to build flexible software. Everytime there is a design problem, design and analysis patterns often provide a good solution. They also guide you to good object-oriented thinking. However, when there is no design problem, there is no need for patterns.

The last very important thing to understand in software development is to look for simplicity, always. It is easy to build a complicated solution, it is difficult to build a simple one. But a simple solution has so many advantages… To simplify a design, domain analysis is a great tool; the more you understand the domain, the best you can align your design to it, and the simplest it will be. By separating orthogonal things or by unifying similar things you can also simplify.

There are also things that we must unlearn, like doing design first and testing at the very end of a project; it is most of the time also useless to create extensive UML diagrams, good design can hardly come from diagrams, if you are not close enough to the code you may miss the point and have a flawed design, even though it looks great as a diagram.

It is counter-intuitive to beginners to focus on anything but syntax. Therefore, unless you have a colleague to introduce you to other concerns, or unless you are really motivated to look for advises on the Internet, you can live a long time without even knowing there is more than that…

Initially published on Jroller on Tuesday June 28, 2005

Read More