6 things to enjoy coding

I really enjoy my job. I understand some people code for food, and it’s fine. But some passionate people are also frustrated. For them I’d like to share some tips. I think most of them can be applied whatever your job is, but I can only testify as a developer.

Ease of mind
I need to be focus on the problem to solve to
be productive. Thus I use several techniques to free my mind at work:
– I don’t hesitate to interrupt myself to fix an important personal problem
– I try to do 1h of workout per day, just before lunch
– I strive to avoid misunderstanding with my co-workers and customers using a lot of communication (never keep a hard feeling for myself)
I may practice some meditation on very bad days

Small cognitive load
When a problem is too hard, I fix an easier part of the problem. Then I iterate until the whole problem is solved. Practices like TDD and EventStorming are a concrete implementation of this concept.
No need to be a genius to fix pretty complex problem thanks to this method. It requires “only” discipline and practices.

Focus sprint
I avoid multi tasking as much as possible. I saw several times that multi tasking is the best friend of workaholics. It is tempting to show how busy we are, but most of the time, it is just bad time management.
My strategy is to work less, but with high focus.
I use pomodoros to time-box 25 minutes sprints. During a sprint, I have a headphone on my ears and all notifications are shut down. On a typical day, I achieve 6 to 8 pomodoros, the rest of the time
I manage interruption.

Sharing

I do one pomodoro each week to share on my blog and on StakOverflow. I’m also really involved in local communities in Lyon. I attend 4 to 8 conferences per year (mainly in France but also in Europe).
I learn much more since I took this habit to share. Sometimes I’m wrong. Sometimes I sound stupid. And I know my English is far from perfect. But it’s fine as long as I learn something on the way.

Getting out of our comfort zone

If your the smartest person in the room, you’re in the wrong room”
L
ook for something to learn in the place you are, or go somewhere else. There is always something new to learn in our amazing job: a domain, a language, an IDE, a method, a paradigm…
Whatever it is, it will help you to be a better programmer.
I’m use to track my goals, and to evaluate them twice a year to see if I’m still moving forward to my path to become a software craftsman.

Have fun

Thanks to remote working 4 days per week, I can spend lots of time with my family, without give up workouts, video games, side projects, conferences and user groups.
Working is not your life, it’s a mean to enjoy it. Thus take time for your family, friends, and to have fun. There is no way to enjoy your job if you can’t enjoy your life. 


 

What the fuck ORM means?

Today is another day where a data model lealking into my business model ruins my productivity. So let’s talk again about impedance mismatch please.

Relational data model

We are all used to relational database. Back in school we learned how to design 1-n or n-n relationships and how to manage primary and foreign keys to manage consistency. We also learned how to normalize and denormalize the model, and to use views for performances.
What we did not learned in school is that it is only one way to store data, and that an automatic translation from this data storage model into memory is not a great idea.

What the fuck ORM means?

According to wikipedia: an Object Relational Mapper is a programming technique for converting data between incompatible type systems in object-oriented programming (OOP) languages.
The problem lies in the definition: we have incompatible type systems. But we somehow believe that the storage data model and the in memory object oriented model are the same thing.

The mismatch

Relational and object oriented are two different representation of the same model. One uses keys and relations to achieve data integrity, based on relational algebra and tuple relational calculus . The other defines bounded objects with defined responsibilities to simulate business processes in order to take decision, inspired by how cells work in biology.
Loading a relational model into memory as an object grape leads to well known problems. Lack of encapsulation (public get/set) is one of them. Anaemic model (data object without any behaviours) is another one. Both of them violate OOP principles.
There are also technical problems: when do you stop to load the grape? How do you manage circular references?

Complexity increase

In all the projects I met so far, the benefice of using an ORM was balanced by the incredible number of hacks we used to load and save what we need. Not speaking about the unmanageable complexity as soon as we try to cache something, because it is always a nightmare to know what is in memory or not.
Just to be clear: the core problem is not SQL or ORM by themselves (they are just tools), but the fact that most developers consider the data model to be their domain model.

How to escape it?

Keep in mind that a relational model is for storage, and that there is no simple way to automatically convert this model in your object oriented representation.
Using other data storage (document, graph, events…) mights help to remind that storing data and running business processes are two different problems with two different purposes.
And if a SQL storage is choose, I encourage to use simple library like Dapper to write actual SQL requests in the data layers. It will simplify the code, clarify the layers responsibilities and learn some SQL to the team, which is a great idea.

Trying to match automatically data model and domain model is a failure, because they are two different concepts.

 

It’s all about fast feedback

I’m a big fan of James Coplien.
I appreciate his controversial point of view about Unit Testing, even if I don’t agree with him. Recently he tweeted about this article explaining why integration tests are much better than unit tests.
Let’s explore it together.

Unit test problem

You write code and then run the unit tests, only to have them fail. Upon closer inspection, you realize that you added a collaborator to the production code but forgot to configure a mock object for it in the unit tests.”

In other words he points out that after a refactoring, some tests will fail despite there is no behaviour modification.
But it really depends on how you write your unit tests. When practicing TDD, I’m testing a logical behaviour. Several classes can emerge, I don’t necessarily have one test class for one production class. And when coupled with DDD practices, I can write unit tests without mocking anything, because I test business logic. Also when I strive for applying SRP, I have a few functions per interfaces, meaning one test won’t fail just because I change some interfaces in another place.
That being said, I agree that some refactoring might change some contracts, which requires to change both the production and the test code. My point is: if it is complicated, it is not because of the unit tests.

System tests solution

“While I was enslaved by unit tests, I couldn’t help but notice that the system tests treated me with more respect. They didn’t care about implementation details. As behavior remained intact. they didn’t complain.”
(System tests for the author are almost end to end and include database)

Again, I agree, if it’s a technical refactoring, the tests that use only production code without mocking may be less brittle.
But I also notice that, when a system test goes red after an actual regression, it takes me a while to find out what the actual problem is. Also, when I had some bugs in production, it is harder to reproduce it in my system tests. It encourages me to fix the code without changing the system tests.
And finally, when there is a business change, it hurts much more to change my system tests. I need a few hours just to write the test managing the new behaviour. I have to initialize half of the application just to check 2 lines of code.

 

Pyramid tests is a myth!

“If you’re like me, you were trained to believe in and embrace the testing pyramid.”…”But my experience revealed a different picture altogether. I found that not only were unit tests extremely brittle due to their coupling to volatile implementation details, but they also formed the wider base of the regression pyramid. In other words, they were a pain to maintain, and developers were encouraged to write as many of them as possible.”

I definitely disagree.
I was not trained to believe in the testing pyramid. I was trained to believe in the “get your shit done, faster please”. And using this approach I believed, like the author and many other developers, that system tests have a better ROI.

It’s all about Fast Feedback

So I tried, and it doesn’t work for me because of long feedback (more than a few minutes).
Feedback time is everything when you run your tests hundreds of times per day, on your local machine. And running your tests hundreds of times per day is really important to practice TDD.
Running the tests has to be easy and fast, or it becomes a pain. And when it’s painful, we loose discipline. We start checking Twitter while the tests are running, and that’s the start of the end of our productivity.


Contextual testing

Maybe there are contexts where systems tests have a better ROI than unit tests. But in my context of backend complex application, with lots of business requirements changing every day, it is not the case.
And I’m not speaking theoretically here. I was involved in 6 projects since I started my career. One has no tests at all, two used inverse pyramid, and three used the classic Mike Kohn Pyramid.
No need to talk about the failure of the project without tests.
The two who used the inverse pyramid have commons characteristics: it was really painful to maintain after a few months, and we need one or two developers almost full-time to keep the system tests working. Not mentioning the time we loose to run the tests before pushing our code, meaning that we often pushed without testing and break the build.

The projects I enjoyed the most as a developer, and my customer as well I believe, was when we have a solid unit testing strategy following the classical Mike Kohn Pyramid. We were able to run thousands of unit tests in a few seconds, and keep a few integration tests running only on the server.

To get results in the long run, don’t give up unit tests, at least if you are working in the same context than me.

 

The coding Iceberg

Recently, I read a few posts about AIs, including Uncle Bob’s post, in response to Grady Booch (about this tweet).
I think the fact tha
t some people believe AIs might replace developers leads to interesting questions about what is programming?

What is programming?

As Bob recalls us, Alan Turing defined programming as a sequence of simple statements of the following form:

Given that the sstem is in state s1,
When event E occurs,
Then set the system to state s2 and invoke behavior B

We express some needs in terms of state transition to be executed by a machine, in other words we build state machines in order to satisfy precise specifications.
This explanation makes it crystal clear that the complexity increases with the number of states in the system.

The perception

Lots of people consider coding as a translation in a given language. You can translate a text from French to English, so you should be able to translate specifications from human readable to computer understandable.
Of course, it is only the emerged part. The translation from human readable to machine understandable code is already automatic, it’s called the compilation.

Developers must be Domain Driven

Under water, developers must express business needs in an unambiguous way, which is the hard part. Coding would be a translation only if the requirements were already a precise state machine, ie a suite of exhaustive Given/When/Then.

As the specifications are never precise enough, we developers must complete them. We have to challenge existing specifications with our understanding of computer, and we have to fill the missing parts with our understanding of the domain.
Thus, considering developers as simple translator who do not need to understand what they are writing about is a sure recipe for failure.

The future

Believing that coders can be replaced by AIs is believing that coders do not need to understand what they are writing about.

AIs might help developers to do a better job though, if they are designed to optimize automatic part like compilation.

 

Rework

I discovered DHH during the « TDD is dead» trend with an ambiguous feeling. I highly value (smart) people with different opinions about testing, craftsmanship and software, but at first glance, DHH looks pretty bumptious to me.

Who’s this guy I’ve never heard of before who decides that one of my favourite development tool is dead?

TDD is dead?

First of all I listen to him and his arguments. I always knew TDD has limits, but rarely meet them. In a nutshell, he argues that TDD may hurts design. After some thoughts my feeling is that TDD does not fit well with invasive framework like Ruby on Rails. Does it make TDD or Rails dead? I don’t think so, they are great tools useful in given contexts.

DHH and I are not working in the same context. He’s more in the web fast app context, whereas I’m more in heavy line of business context (usually not even web). The good news is that his thoughts about my work’s style are less biased than people from my context.

Why I read it

I’ve a very simple way to select the books I read: the more I heard about it, the more it goes up in my reading list. I select rework in this way, without knowing DHH was one of the authors (the other one is Jason Fried).
It was a good surprise, and I definitely recognize his style, close of his blog. I also recognize William Zinsser’s influence, something we share. It is a really pleasant book to read.

Content

The content is full of short take-away. I think I would gain more benefice if I read it a few years ago. Some advices sound clearly obvious now. Still I admit it wasn’t this obvious when I discovered the world of software and entrepreneurship in 2009.

 

Favourites take-away

–        Scaling is not mandatory
–        You need less than you think
–        Beware the workaholists
–        Go to sleep
–        Don’t confuse enthusiasm with priority
–        Pick a fight

 

Should you read it?

I think the book stay a must read, especially if you like the direct style of William Zinsser, and/or if you are both entrepreneur and software developer.

It helps me to know more about DHH’s universe.

 

 

The over-engineering theory

I never was comfortable with the idea of “complex domain”.

“Use DDD only in complex domain” is a mantra used by DDD experts to avoid the Silver Bullet Syndrom. It is really convenient to avoid uncomfortable discussion.
 

Why do I mind?

We’d like to know what is a complex domain to know when to use DDD.

From a strategic perspective, I already argued that we could always use it. The remaining question is: when should I use DDD from a tactical perspective? When should I implement hexagonal architecture, CQRS/ES and other fancy stuff like that?

Not in a CRUD software?

Whatever the implementation we choose, software is a business abstraction. When we choose a CRUD implementation, we bet the future software will have few features. We bet we won’t need many abstractions.  The cognitive load due to the domain will stay low, implying we can mix business logic with technical terms, without building unmanageable software.

In my experience, lots of applications begun as simple CRUD, but they quickly evolved in something more complex and useful for the business. Unfortunately we keep coding them as simple CRUD, which results in a massive mess. Certainly not in purpose, adding just a bit of complexity day after day makes it hard to grab the whole complexity of the solution. We are the boiling frog.

The over-engineering theory

The challenge is to find at which point our simple CRUD application becomes a more complex line of business application.

My theory is that we consider patterns from tactical DDD over-engineering all the time. Because we are unable to feel the complexity of the software we are building day after day. Worse, we think that the knowledge we accumulate about this complexity makes us valuable as the dungeon master. We are deeply biased to sense our own work.

But what happens when we go working on another project? The will to rewrite the full software from scratch. Push the frog in hot water, and she won’t stay for long.

 

Looking for the inflection point

We’d like to find when it becomes interesting to implement tactical DDD patterns, despite the cost it has.

A part of the solution may be to check how long a new comer needs to be productive. When it is too long, there is room for improvement, and tactical patterns can help to decrease the code complexity.
Another solution may be to ask for a few audits by different DDD experts, but it could be more expensive.
A simpler solution may be to assume that the software will become more complex. It implies we should look at which tactical pattern can fit our needs, day after day.

Remember there is a world of practices in tactical DDD patterns. Using all of them all the time is not desirable. Picking the good one at the good time is the actual difficulty.

When should I use tactical DDD patterns?

I do not have a definitive answer for that, just an empirical observation: I’ve seen countless software implemented in a CRUD way that would be greatly improved by a DDD tactical approach. I’ve seen no software implemented with a tactical DDD approach that would be greatly improved by a CRUD implementation.

Just saying.

 

“If you think good design is expensive, you should look at the cost of bad design.” -Dr. Ralf Speth, CEO Jaguar 

 

 

 

It is not your domain

From a technical perspective, I would argue that a DDD project is nothing but a clear and protected domain.
Working on lots of legacy code though, I observe common mistakes to identify what is inside the domain, and what is outside.

 

Your data model is not your domain model

It is a really common mistake to use a data model as a domain model. I think ORM and CRUD have their part of responsibility in this misconception. A data model is a representation of the model optimized for data storage.

Building object in code from this model using ORM doesn’t make it a domain model. It is still a data model, it is still optimized for data storage. It is no longer sql tables, nothing more.

The data model has the responsibility to store data, whereas the domain model has the responsibility to handle business logic. An application can be considered CRUD only if there is no business logic around the data model. Even in this (rare) case, your data model is not your domain model. It just means that, as no business logics is involved, we don’t need any abstraction to manage it, and thus we have no domain model.

 

Your view model is not your domain model

Another common mistake is to add just one layer between the data model and the view. This layer has different name (Presenter, Controller, ViewModel…Whatever) in different patterns and languages, but the idea is the same: abstracting the view using code.

The mistake is when we believe this is the place to add business logic. This layer has already the responsibility to abstract the view, we don’t want to add any other responsibility.

 

Your data model should not notify your view

I go crazy when I find a model object with the responsibility to notify the view when some data changed (often using databinding). It literally means that this data or domain object, has also the responsibility to manage the way data are displayed.

As usual, it is all about separation of concern.

Your domain model should depend of (almost) nothing

The domain model is a set of classes or functions, group in a domain layer, containing all the business logic. This layer is absolutely free from the infrastructure. It should be a pure abstraction of the business.

A domain model is still valid if we change the way we render the software. A domain model is still valid if we change the data storage. A domain model is still valid if we decide to stop using our favourite Framework.

A domain model depends of one thing and one thing only: the business.

 

 

 

 

 

 

Just Blog It

Since 1 year I try to write more blog posts. I’m performing at least 1 pomodoro per week to write drafts. I don’t feel pressure about publishing these drafts though, sometimes I do, sometimes I throw them away, and sometimes I merge them into a single post.

I think it might worth sharing what I learned.

Writing for yourself

The first rule of blogging is: don’t write for others, write for yourself. Some people might find what you write interesting, but writing with the goal to be interesting is not possible. It’s by writing consistently about your thoughts that some people might become regular readers. I stopped wondering if my posts were good or even interesting. I just published my current state of mind.

Writing for yourself is the art to express what you think about, in a clear way. It is a useful journey by itself, a personal experience. Having readers is a pleasant side effect for our ego, not the goal.

Writing in English

I don’t think it’s mandatory, still I don’t regret this choice.

Mainly because It improves my English skills.

But also, according to WordPress, I published 28 blog posts for 6500 unique reader. Half of them are not from France. I have some readers in the UK, Belgium, Spain, Germany, Poland and US for example.
It’s a wonderful gift to have feedback from all over the world, and only an English blog allows that. As you see my English is far from perfect, but it’s enough to share and learn with the whole world.

What I learned (in no specific order)

Just blog it

I enjoyed writing to my blog this year. I feel much more comfortable since I write for myself rather than for others. I’m not bilingual, and don’t need to, even to write in English.

I hope this post will help some of you to enjoy writing on their blog as well.

 

Thanks to all my kind reviewers over the year.
Special thanks to Brian Gibson for his time and patience to help me improve my English skills.

And of course, thanks to all my readers, all the best for this New Year!

 

Abstracting the reality

Let’s define the reality as the consequence of all previous Facts.

Nobody knows every fact from the past. And when we share some facts, we don’t give them the same importance. We build our reality based on the facts we believe to know, and give them some importance based on what we think do matter.

In other words, there are several realities. A reality can be based on some false facts, still it is a reality for someone. Not to be confused with the concept of truth: there is only one truth, the problem is that nobody knows it (hint: most people suppose their reality is the truth).

Building a shared abstract reality (i.e. software) is exceptionally hard.

Spaghetti Realities

It’s the point of DDD to avoid mixing those realities. It takes lots of time and analysis to understand the realities of a business. It is an iterating task. Domain experts share a reality because they share some business processes. For example someone from the marketing team will understand another colleague from the marketing. But she won’t always understand a colleague from the shipping team. They face different challenges, they use different languages: they work in different realities.

Strategic patterns from DDD help us to build context specific solution, in order to build a software matching only one reality, avoiding an unmanageable level of complexity in the shared abstraction.

How to choose a reality

Essential complexity is the solution to a problem in its purest form. Accidental complexity is when the solution we develop is more complicated than required by the problem.

In the excellent paper Out of the tar pit, Ben Moseley and Peter Marks explain how we bring technical accidental complexity in our software, especially with states, control (the order in which things happen), and volume (the size in terms of line of code).

I think we often miss the opportunity to look for accidental complexity in the domain as well. We suppose that the problem is already well understood, whereas most of the time there is room for improvements.

How to implement the reality

If we agree that the reality is the consequence of all previous Facts, it makes sense to look for an implementation where these facts are represented. Such an implementation would be easier to translate into the reality, and vice versa. Such an implementation help to describe the essence of software: it is an automated decision maker based on past facts.This implementation is already a reality

The user send a wish into the software (“I’d like to do that…)”, the software takes a decision based on its own reality (i.e. the facts it knows), and it send feedback data to the user to help her find her next wish.

Just replace the world Fact by Event, Wish with Command and User Feedback with Query to find an existing implementation for these concepts.

 

About Inheritance and Composition

Like for dependency injection, heritage and composition are easily misundertsood.

We remember that programs written in Oriented Object Programming (OOP ) are designed by making them out of objects that interact with one another. Technically, we have two possibilities to share code in an OOP style: either composition or inheritance.

why-favor-composition-over-inheritance-in-java

Composition

The purpose of composition is to make wholes out of parts. These wholes (or components) will collaborate to achieve a common goal.
Composition has a natural translation in the real world. A car has 4 wheels. Without the wheels the car is still a car, but it loses its ability to move.
Back to code, a bank account might need a print service. Without the print service, the bank account is still a bank account, but it loses its ability to be printed. It is a “has a” relationship.

composition

Inheritance

Inheritance allows expressing and ordering concepts from generalized to specialized in a classification hierarchy.
The meaning of a class is visible in the inputs and outputs (public contract) of the class. As a child of a class, we are implicitly accepting responsibility for the public contract of the superclass. We are tightly coupled to this superclass: it is a “is a” relationship.
A human being is a mammal. No exceptions, all mammals have a neocortex. Without the neocortex, we are no longer mammals. Back to code, I may design a “human” child class, inheriting a “mammal” base class, both sharing a NeoCortex property.

 inheritance

Common mistake

The problem’s root is that sharing code can be done either by composition or by inheritance, but the impacts are not the same.
Any class can be composed by other classes because it requires their capabilities.
But with inheritance, the key is to decide if we accept responsibilities from the public contract of the superclass. If our parent has some capabilities/properties we don’t need, we deny a part of the responsibility. The “is a” relationship is broken as soon as there is something in the parent that isn’t true for the child. Adding responsibilities in the parent because “some children might need it” is not ok. All children need it, or we need another abstraction, or we need composition.
It is a problem because inheritance implies tight coupling. A refactoring of a capability can impact all the children of a base class. If one of the children does not use the refactored capability, it should not be impacted.

 images15e67y3x

Example

Lots of modern languages use the concept of ViewModel, even if it may be called otherwise. It is appealing to build a ViewModelBase with everything any children might need, like the ability to be printed, or to show a dialog box.
What happens when a child inherits this ViewModelBase but doesn’t need to be printed or to show dialogs? It accepts responsibilities that does not make sense for it. The signature and the meaning of the class are blurred. Without these printing or show dialog ability, the ViewModel is still a ViewModel.

On the other hand, implementing a RaisePropertyChanged function in ViewModelBase makes sense, because any ViewModel is by definition glue between the business logic and the view. It needs the ability to inform the view when a property is updated. Without this ability, it’s no longer a ViewModel. choosing-the-best-local-seo-company

How to choose?

The mantra “favor composition over inheritance”  is helpful, but as every mantra it is limited. It is true because sharing behaviours is always possible by composition, and will be more decoupled, but it is not always the wiser choice.

I think the “has a” vs “is a” relationship, and the reminder that every children must take the full responsibility of the parent in case of inheritance is enough to help choosing the best option.

 

 

 
IP Blocking Protection is enabled by IP Address Blocker from LionScripts.com.