Note about this chapter:
The material here is very much in-progress. It needs more explanations, some reorganization and cleaning up the redundancies with Chapter 5. Please keep this in mind.
The technical aspects of our work that have business significance. You can use these to check the financial effects of code/system level changes. It involves 5 different areas:
- Prerequisite: Platform
- Code & Codebase
- Software product
- Software system
- Development process
This is a prerequisite because we have no control over this in 99.9% of the time. We can make a choice but that's all. High level goals are to match the user needs and meet business goals by choosing the platforms that offer the right business opportunities and customer experience.
- User base
- DX (Developer experience)
- Performance characteristics
- Releasing - easy to do frequently
- Business model
- Legal fit
- Monitoring / observability options
Here you will learn the universal, high level properties of code and their effects. It's important to keep the software - code duality in mind. We are looking purely at the code side now, which only indirectly serves the user needs.
The main business goals of code optimization is to maximize developer productivity and utilization.
The single most important attribute of a codebase in order to reach that is: to be easy to work with. The essence of that is a duo of properties: easy to understand and easy to change. These are the most important properties of any codebase and our main goals when choosing how to write code. To achieve them the tools we choose must make it easy to perform all the possible actions over code.
- Writing - the process of creating it
- Refactoring / Changing
- Reading - visually parsing the code
- Searching - navigation in the codebase
- Understanding - what the code does
- Processing - by a computer
- Assessing - the quality in some manner
- Reviewing - literally code review
- Testing - with unit and integration tests
Code is easy to change when it's structure matches it's function. Meaning the way it's organized (the breakdown of responsibilities into code and of code to files, especially their relationship with each other — e.g. dependencies ) is aligned with how the functional and non-functional features depend on each other, enabling us to more effectively work on the implementation. To unpack it further, the different responsibilities are distributed in the code in a way that is aligned with how the modelled real-life objects and processes work and likely change.
Every best practice you know, like SOLID, DRY, KISS, low coupling - high cohesion, naming strategies, size limitations, formatting rules, all of them are considered good because they make it easy to perform these actions and ultimately make code easy to work with. We should always take the planned lifetime of a project into account and evaluate these factors over the whole period. The general aim should be maximizing the sustainable development speed and minimizing the required effort to deliver a request.
So the ultimate goal of code optimization is to enable low effort, high speed development, without sacrificing the code, product or service quality.
Here are the technical attributes of code that influence these goals. (You can toggle the items for more details)
On all scales from cross platform support to the function/method/procedure level.
Adherence to project standards and conventions
To increase control and lower some wastes.
If there are multiple ways to do the same thing nobody should ever wonder which one is the way to go on the project.
Prevents programmer errors. This is a matter of both the technical properties of the tools and the adopted best practices in using them.
The code is both self-documenting and covered by standard documentation to the appropriate level.
Good separation of concerns
SRP, DI, low coupling, high cohesion and the rest of the 4 dimensions of code structure.
No premature (code) optimizations
Eg. overengineering. Strive for:
- Low complexity
- Small size
- Appropriate level of abstraction - no unnecessary generalization nor fine-tuning.
Uniform solutions are used for the same or similar issues across the whole codebase (DRY code - but this applies on more abstract levels too, like programming paradigm, domain modeling methodology, naming conventions, etc)
Are as few as possible and trusted
Concise / Expressive
As opposed to bloated, verbose or cluttered and also to cryptic, magical or hacky. The code conveys the ideas of the programmer in the simplest yet easy to understand way.
- Declarative - showes the what, instead of the how.
Reading the code says what it does in terms of business logic. Value and expression names are the key to this.
Matches the use case
- Abstraction: Generalization to improve code reuse vs specialization which is often required for optimization.
- Expressiveness: Verbose vs succinct implementation of the same functionality. Closely related is the imperative vs declarative approach.
- Complexity: High or low number of used tools, concepts, elements, philosophies/approaches. Complex vs simple solutions.
- Readability: Easy vs hard to understand what the code is supposed to do in real-life terms. Has to do with naming, documenting and structuring the different elements.
- Safety: Easy vs hard to make programmer errors with the available tools.
- Findability: Logical vs illogical organization of the different parts of the code.
- Coupling: Shared code dependencies.
- Cohesion: Real life relationship of the implemented functionalities
- Colocation: Codebase/filesystem location
- Ownership: Organizational location. (Who's responsible for what)
It has two main concerns: How will it serve the user needs? How will it serve the business goals?
Ultimately it affects customer experience and business opportunities.
This nicely underlines the existence of the software - code duality as this complements the set of delivered business values of code to all of them.
- Performance (of it's functions)
- Blocked interval (loading/saving)
- Brand conforming
- Data integrity
- Reliable (chance of running without failure over a given period of time)
- Threat free (virus, malware, spyware, ransomware etc...)
- Observability - Collects enough logs, metrics and error reports
- Cross platform (when applicable)
- Updating (is seamless)
- Extensible (when applicable)
- User generated content
- Customizable (when applicable)
- Visibility (SEO, presence on marketplaces)
- Integration (with other tools)
- Safe (doesn't endanger its users or its environment)
- Useful error messages
- Privacy protection
- Feedback opportunities
- Engaging - endorsing interaction with the company and participation in activities.
It's the combination of code and software in terms of influence. Its structure affects our productivity and utilization and its quality attributes have to meet the user needs and business goals to create the expected customer experience and business opportunities.
- Extensible (with components)
- Integration (with other systems)
- Isolation (the individual parts are well separated)
- Architecture - It matches the intended functionality of the system.
The high level goals of this is the same as that of the codebase. To maximize developer productivity and utilization.
- Employee engagement
- Community engagement
- Workflow - seamless and fast
- Tools - that support this, like project and task management
- Feedback loop - fast, internal and external as well: compile and deploy processes, from monitoring tools, from the users
- Best practices - are checked, applied and enforced
- Tech debt management - track and schedule pay back
- Quality assurance - code review, TDD, etc...
- Version control hygiene - easy to follow history. Linkage with project management tools.
- Measured - bug statistics, release statistics, user and organization surveys
- Compliant - with the regulatory or policy standards.
- Onboarding process - planned and supported