One very dear colleague has a background in technical writing. I asked him once if he had any advice on how to combat the famous “writer’s block”. He told me that as a matter of fact he did. And told me something which was so simple that I was shocked at first:
What did he mean … “just write”? That was the problem to begin with! “No no”, he said:
Just write something. Anything.
Could it be so simple? It decided to put it to the test on the spot. I think I started to type something like “I am here, not knowing what to write about ” subject so and so. And lo and behold, ideas started popping into my head shortly afterwards. I was “unstuck”!
Reflecting on the material I recently read on books like “Atomic Habits” and “How to be an Imperfectionist” I think that what this “writing anything” does is:
- Give one a place to start. And often the most difficult part is starting.
- Take the focus away from ruminating about the “problem” (being stuck)
- Get one’s mind in the process, in the “flow”. Get one going.
In other words, it is like starting a car and getting it car into motion. Once in motion it is easier to steer it in the right direction. Suffice to say that if it wasn’t in motion at all, it would not be possible to steer it to begin with.
And that’s it. Just write. Anything.
I wonder if this advice applies to other areas in life …
Recently I was reminded of what could be a good strategy to organize a codebase in a back-end web-service consisting of several use-cases. A colleague told me of the problem they had, and how they solved it.
They started separating the application-logic in a class that contained only that: application logic. Accordingly, its name was: AppLogic. The controllers would only talk to the app-logic. This in turn would get the dependencies it needed, and invoke the necessary methods on those dependencies (usually involving the persistence layer).
At the beginning of the project everything was fine. This was an acceptable approach since the uses-cases covered by that app-logic remained within grasp. But of course over time the use-cases started to grow and the amount of methods started to pile up. It didn’t make sense anymore.
The solution they came up with is something I think I saw somewhere before (was it part of DDD maybe?) but as my colleague mentioned it again, it struck me as an excellent idea: they started to organize their use-cases into … use-case-objects!
Each use-case would be encoded in a class. That class would get only the dependencies needed to perform the use-case needed. That class could have its own private helper methods, without polluting other use-cases. The use-case class would have a name reflecting the implemented use-case, and a entry-point method with a similar name.
This not only made a “god class” like AppLogic no longer necessary, but created an opportunity to have a nice overview of the different use-cases supported by the application. I did not see the code, but I can imagine that things like choosing appropriate package-names for these classes would be a nice way of grouping them, if applicable. I can also imagine a more clear testing approach and code as a result.
All in all the idea interested me very much, especially for code like in a web-based back-end, where each request results in the execution of a use-case. It only feels natural to choose an approach like this.
Recently a colleague told me about the problems they run into in their project (a web service). Among them one that stroke me as very interesting was the diminishing return of some kind of tests.
I once explained what refactoring was to a non-programmer. It went like this:
“We software developers (programmers for short) do not only need to write a program that accomplishes a task. That’s the easy part. The difficult part is to change an existing program to adapt to new requirements / problems.
A lot of thought has been put into this problem. Methodologies, advice, tips, books, best-practices arose and continue to arise to address this issue.
Imagine we have code that interacts with external systems. External systems could mean:
- interacting with a database
- interacting with a file-system
- printing something to the console
- interacting with a remote service
- and so on
How do we test a program like this? How do we make sure it does the right thing after we change something in its logic, or its structure, when we add a feafure of fix a bug?
In this post we will look at a general approach to achieve this.