The first DDD Open Forum of the brand new Paris DDD meetup was last night, hosted by Arolla, and it was good to meet again after a long time with twenty-some Paris DDD aficionados!
@tjaskula, the organizer of this new group, opened the evening with a welcome introduction. He also gave many suggestions of areas for discussion and debate.
A quick survey revealed that one third of the participants were new to Domain-Driven Design, while another third was on the other hand rather comfortable with it. This correlated with a rather senior audience, with only one attendee with less than 5 years experience and many 10+ years developers, including 22 years and 30 years experience developers, and still coding! If you work in Paris, I guess you know them already…
It was an open space session, so we first proposed a lot of topics for discussion with post-its on the wall: how to sell or convince about DDD, introduction on concepts, synchronizing between contexts…
We all decided to start with a walk through of the fundamentals of DDD: Bounded Contexts, Ubiquitous Language, Code as Model… It was great to have this two-way knowledge transfer between seniors and juniors, in an interactive fashion and with lot of questions, including some rather challenging and skeptical ones! There was also some UML bashing of course.
We concluded by eating Galettes des Rois, together with cider and beer, and a lot of fun. Thanks everyone for your questions and contributions, and see you soon on next meetup!
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.
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:
One value object often gathers several primitives together, and one thing is always simpler that a few things
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
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)
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)
The method toString() can just tell in a pretty-formatted fashion what it is, and this is precious!
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.
In the post “Playing with laser beams to create very simple rhythms” I explained a theoretical approach that I want to materialize into an instrument. The idea is to create complex rhythms by combining several times the same rhythmic patterns, but each time with some variation compared to the original pattern.
Several possible variations (or transforms, since a variation is generated by applying a transform to the original pattern) were proposed, starting from an hypothetical rhythmic pattern “x.x.xx..”. Three linear transforms: Reverse (”..xx.x.x”), Roll (”x.x.xx..”) and Scale 2:1 (”x…x…x.x…..”) or 1:2 (”xxx.”), and some non-linear transforms: Truncate (”xx..”) etc.
Geometry + Light = Tangible transforms
The very idea behind the various experiments made using laser light beams and LDR sensors is to build an instrument that proposes all the previous transforms in a tangible fashion: when you move physical object, you also change the rhythm accordingly.
Let’s consider a very narrow light beam turning just like the hands of a clock. Let’s suppose that our clock has no number written around, but we can position marks (mirrors) wherever on the clock surface. Still in the context of creating rhythms, now assume that every time a hand crosses a mark (mirror) we trigger a sound. So far we have a rhythmic clock, which is a funny instrument already. But we can do better…
Going back to our rhythmic pattern “x.x.xx..”, we can represent it with 4 mirrors that we position on a same circle. On the illustration below this original pattern is displayed in orange, each mirror shown by an X letter.. If we now link these 4 mirrors together with some adhesive tape, we have built a physical object that represents a rhythmic pattern. The rotating red line represents the laser beam turning like the clock hands.
Now we have a physical pattern (the original one), we can of course create copies of it (need more mirrors and more adhesive tape). We can then position the copies elsewhere on the clock. The point is that where you put a copy defines the transform that applies to it compared with the original pattern:
If we just shift a pattern left or right while remaining on the same circle, then we are actually doing the Roll transform (change the phase of the pattern) (example in blue on the picture)
If we reverse the adhesive tape with its mirrors glued on, then of course we also apply the Reverse transform to the pattern (example in grey on the picture)
If we move the pattern to another (concentric) circle, then we are actually applying the Scale transform, where the scaling coefficient is the fraction of the radius of the circle over the radius of the circle of the original pattern (example in green on the picture)
Therefore, simple polar geometry is enough to provide a complete set of physical operations that fully mimic the desired operations on rhythmic pattern. And since this geometry is in deep relationship with how the rhythm is being made, the musician can understand what’s happening and how to place the mirrors to get any the desired result. The system is controllable.
To apply the Truncate transform (that is not a linear transform) we can just stick a piece of black paper to hide the mirror(s) we want to mute.
If we layer the clock we just described, with one layer for each timbre to play, then again changing the timbre (yet another non-linear transform) can then be done by physically moving the pattern (mirrors on adhesive tape) across the layers.
From theory to practice
Though appealing in principle, this geometric approach is hard to implement into a physical installation, mostly because accuracy issues:
The rotating mirror must rotate perfectly, with no axis deviation; any angular deviation is multiplied by two and then leads to important position deviation in the light spot in the distance: delta = distance . tan(2 deviation angle)
Each laser module is already not very accurate: the light beam is not always perfectly aligned with the body. To fix that would require careful tilt and pan adjustment on the laser module support
Positioning the retroreflectors in a way that is accurate and easy to add, move or remove at the same time is not that easy; furthermore, even if in theory the retroreflectors reflect all the incoming light back to where it comes from, in practice maximum reflectance happens when the light hits the reflector orthogonally, which is useful to prevent missed hits
Don’t hesitate to check these pages for progress, and any feedback much appreciated.
I’m a big fan of design patterns, they do make my work easier, more explicit, more maintenable and also more enjoyable; however I’m surprised that not everyone knows them and actually uses them. What’s wrong with design patterns ?
they are difficult to learn and to teach, it is nearly impossible to teach design patterns at school unless students already have significant hands-on practice of software development, unless they already encountered real-world problems
they are difficult to implement correctly when you start with them, you often misuse them at first tries
they do not match the way many people think about software, many people still resist to them, they think using design patterns is counter-intuitive (this is especially true if you started your carrer with a procedural point of view, how many times people tell me: “using patterns or not, it is the same at the end of the day in the software !”)
once you know them, you are impressed at the power and expressiveness they give you, so you tend to overuse them
Since I’m still convinced design patterns MUST be known by any professional developer today, what are the best ways to learn or teach them ?
There is no magic answer, however these are some clues:
mentoring is undoubtedly the best way to learn design patterns; so the best way to learn them is to find coworkers that know them more than you do; it is even better to work on the same part of the software to really get the point in using, -or not using- patterns (pair programming ?)
If patterns have to be taught in a classroom environment to people that already have work experience (as in company internal training sessions), it is worthless to describe and explain the catalog of patterns, you’d better explain what you found difficult or confusing when you were learning them, this is much more valuable for your audience. For instance, explain that the intent of a pattern comes first, that yes it is normal that the UML diagrams may be the same for two or three patterns, because their intent is different, that yes they are already using some patterns without even being aware of it… I think presenting patterns through refactoring examples should also be very relevant since the value-added of patterns is more obvious.
Maybe design patterns are too abstract to be learnt directly (1); as usual when abstraction is a problem, we should then focus on more concrete examples (or instances). In the case of design patterns, more concrete examples may be J2EE patterns (it is very surprising to see that many people know much more about J2EE patterns than fundamental GoF patterns !), or Analysis Patterns that derive from design patterns and that solve a particular domain problem. Once the apprentice knows enough such concrete patterns, it becomes easier to describe the abstract pattern that sums them all.
(1) Actually one strength of design patterns is that they are abstract enough to be reusable to a great extent.
Initially published on Jroller on Monday April 25, 2005