We are constructing a behavior framework that simplifies your Code and makes it scalable.
We are primarily focusing on problem decomposition, status tracking, initial construction, and refactoring.
Check Self-Aware Software Artisan: Deep Work.
If you are looking for a palette of tools, languages, frameworks to quickly bootstrap projects, while having scalability and ease of development in mind, check Self-Aware Software Artisan: Product Artisanship.
🏆 Your progress 🌏 🏄♂️
After you’re done reading: check the ⬇️ bottom of the page — you’ll find next parts of this series that cover diverse set of related topics!
📣 Coming soon!
I’m continually refactoring this series.
Subscribe to receive a single-page Manifesto: Scalable Software Development distilled to the ultimate truths; from the viewpoint of an Software Artisan.
Author’s experience
Data Sculptor, Architect of Systems and Products.
Founded startups in the fields of Education and Sports and led teams of up to ten people.
Worked, as a Systems Architect, Frontend, and Backend Developer, for a product company, a digital agency, and as a remote freelancer.
For more information, check my Personal Website.
🎷 Background song
Looking at the bigger picture — The Ecosystem
Software Artisan doesn’t just care about the code, but the whole ecosystem:
- from your body, mind,
- git messages,
- scope of your commits,
- variable, function, file naming,
- chunking methods into smaller units,
- your relationship with people in your team,
- accepting requests for work and
- delivering it in a fashion that is document-able, and understandable by you and others, now and in the future.
Don’t get overwhelmed by all the things before-mentioned, with time, as your skills progress, and your body has less friction in movements you do, your mind will calm itself down, and these things will be approached intuitively by you and others.
It is important, however, to know what we are aiming at, to know how much we are approaching or moving away from it throughout time.
Software Artisans as Writers and Editors
“Margaret Heafield Hamilton is an American computer scientist, systems engineer, and business owner. She was director of the Software Engineering Division of the MIT Instrumentation Laboratory, which developed on-board flight software for NASA’s Apollo program.” — Wikipedia Source
Document everything
We strive to organize information in our development environment.
Focus on naming things properly and grouping them — putting them in the appropriate place (i.e. file, directory, docs, readme, file, task tracker) etc.
Express yourself through:
- tasks — with full-blown comments in tasks (not just (NOT)COMPLETED statuses, but whole essays about what is on your mind about the task),
- code (so you don’t have to write comments),
- comments (when you don’t know how to express yourself through the code, or you legitimately have other things to do with greater priority),
- docs (Readme, specific-online-docs-software).
Can’t express problems and solutions in the code? At least express yourself in the comments
It is better to have a problem described in natural language (English) than to have a “hole” in understanding and leave only complicated/bad code, without any explanation.
Coherent code
Bible: Cross-referencing. Source. Jordan B Peterson Video.
The code is cross-referencing itself all the time. The more coherent the relationships are, the more understandable the code is.
We grade a developer by the cohesion one leaves behind himself in the code
A developer is like a gardener, planting flowers, fruits, vegetables in different places of the field; having a grouping of items in mind. When you look at the garden from the sky, you could see how much colors complement each other.
Tools for creating cohesion in the code:
- (re-)naming (variables, functions, classes),
- (re-)grouping (code in a function, class, …),
- not repeating yourself (don’t have two things doing the same thing, under different names),
- connecting parts of the code properly with each other.
Use the tools outlined above as much as you can to save yourself hassles down the road.
The cohesion of the code is influenced by the:
- experience and will of the developer,
- complexity of the assignment and,
- constraints of any sort (time/priority, intersection ratio with the existing code, …).
If you are constrained by any factor and don’t know how to express yourself in the code, leave comments. You will be valued for at least admitting lack of proper or complete implementation and leaving breadcrumbs for easier problem solving later on.
Git messages and The Code: The dance
We are always trying to trickle down the work we do into smaller chunks.
Git messages are here to re-articulate what you’ve actually done
You will find potential flaws in your approach while writing a git message.
If you cannot write a simple and precise git message as a recap — you don’t understand what you have done.
Too deep in the complexity? Re-articulate current state in the git commit, stage changes and move forward!
When you are unable to implement thoroughly, use git message as a means of documentation. Stage the changes to mark parts that are explained in the git commit.
e.g. you could have a bigger number of files that are being changed, and you are in the middle of working on the functionality, and being stuck with it… It is a good time to go to git and describe everything you’ve done the best you can, in the form of bullet points or an essay where necessary.
It is better to document a solution with comments, than moving away from the code and getting back to the half-implemented functionality with 20 changed files and no overall description for it.
Constantly switch back and forth between Git message construction and the code.
WIP and TODO tags
Leave WIP: and TODO: annotations in the git message — associated with the individual files or the functionality you are accenting.
Functions: Parameters and Naming
The purpose of the function needs to be the smallest possible. It will allow you to easier rename it and fix it.
Keep the body of your function (logic) simplest possible, as well as its arguments list.
Refactoring the code
To be able to do the refactoring properly, we need to understand what the environment of the feature we are refactoring is made of. That means having all the pieces of the puzzle visible and knowing how they are connected.
Steps to refactor the code would be:
- splitting larger chunks of code or functionality into smaller ones,
- re-naming variables, methods, files, directories to show what is inside, at a glance,
- re-grouping — moving variables, blocks of code in the methods, whole methods, files, or directories.
What goes into the refactoring:
- doing the work in the smallest possible chunks that are understandable,
- committing the changes,
- documenting any newly found understandings of the inner-workings of the code with comments,
- updating the tasks,
- constantly re-evaluating status of the work.
When to refactor and improve, and when to move onward
If you have a more complex case that needs to be refactored, you could get caught up in changing one of its parts and having to discard everything or mixing that with the previous attempts of refactoring. That’s why it’s important to do the refactoring in the smallest steps possible.
Move forward when you see the cost of context switching too high.
If the refactoring takes a lot of time, and it expands, without having the ability to chunk it up — it’s too late, you’ve gone too far. It is important to stop, comment on everything you see and try to move as swiftly as possible.
Do the work in advance, don’t sandbag yourself into days or weeks of refactoring, if possible.
Handle one problem at the time
A person can truly handle only one or two problems having in his head. Do not stretch it to two, three, or more.
If:
- you are implementing a feature A) and
- you find a bug that is not directly connected to the feature A).
Then:
- above the function, piece of function, class, or file ADD: TODO: message
- add a new Issue to your task tracker.
Why:
- cost of context-switching is too high,
- so that all potential bugs and possible improvements are on the task list and get solved when the time is right.
Refactoring: Search&Replace in one sweep
Have a system (a convention) of naming variables, methods, files.
Even if you were wrong, you’ve done it in a systematical way — and you can search&replace in one sweep!
Think about searching and replacing in the future (changing the variable, method names, …).
How will you organize your files, directories? Know everything, develop a system for it. Evolve it with time. The more systematic you are with it, the easier you’ll evolve it.
So, even if you’re “wrong” with a convention, you are better off being wrong in the same way across the code base — as you will be able to search & replace in one sweep.
You can use basic commands in your IDE (e.g. VSCode):
- match case sensitive,
- match whole words,
- match via regex.
Testing
As with anything, there is a good balance that needs to be struck.
We are going about it by prioritizing issues. Test individual units of code, as well as — parts that integrate them into bigger pieces.
Focus more on testing the business logic, than testing features that you expect your language, framework, or library to handle properly.
Can’t solve the problem? Getting out of the rot
Sometimes, just sitting on it makes sense.
You can try a different angle of looking at the problem in your mind (you will try to get new information and solve the puzzle from another viewpoint, while remaining glued to the monitor, the pen or whatever).
That could work.
Most of the time sitting behind a monitor isn’t optimal — gather information and get away!
If you are deep into the complexity of the newly encountered problem… If you feel you are not looking at it from different angles or moving through your mind by analyzing and getting new views in your mind, and the time just passes by… Gather information, go and do another activity to break up the monotony.
Running, being on the sun, eating, walking around, drinking, sitting under a tree, or whatever — will give you new information through your eyes, nose, ears (…); thus re-configuring your mind, and shocking it to re-compute problems you’re tackling.
Sleeping on the problem also helps.
This is probably one of the most important aspects of managing yourself while solving difficult problems. To know when to stay, and when to go.
Find this useful?
👏 Clap so more people see the story.
❤️ Support your friends and colleagues at work — share this essay with them!
🚀 Use it as a, Company or Personal, Manifesto! Fork and Adapt on GitHub!
🏆 Your progress 🌏 🏄♂️
Code Artisanship — ✺ You are here.
Finishing up — 👈 Next up!
Top comments (0)