This chapter is about learning the mindset of the most effective developers. Along the way, it defines the core principles of Full Context Software Development. We will examine some of our fundamental assumptions about the nature of programming, with the goal of discovering the "axioms" - the elementary ideas - that lead to making the best tech decisions. These are much more than simple technical guidelines. They define a unique perspective about the goal of our work. What we will do in the rest of the book is simply following where the logical consequences of these axioms take us. We should begin by asking a question most of us would never bother thinking about.
I would like you to answer this question. "What software really is?" To have the most benefit from this part, it's best if you write down the answer before continuing. Open an app, grab a piece of paper, or use the text box down below. Give it a few minutes, then continue from here.
In my experience, we just take our concept of software for granted. That's no wonder, a surface level understanding completely suffices to do our job. However, that's not the case here. I realized there's a simple, yet profound relationship between our concept of software and the way we make tech decisions. If your concept is purely technical, things are as we all know it. Choices generally boil down to which tools are the most productive and which lead to more maintainable code bases while meeting the usual, project specific requirements. (and of course what everyone is hyped about...) However, from the big picture, software is much more than the technical and our development choices reflect how much of that more we understand. Our common comprehension of the overall goal of the project gets embodied in the product and validated by the market.
What you value highest about software is what you ship to users.
The way we make tech decisions shows what matters the most to us. Examine the things you really want to optimize while making choices. In practice, those aspects define software for you. The chapter will expand upon these ideas. Now, the definition is a good starting point. (Open the toggle if you already finished your answer)
The Full Context definition of software:
In its essence, software is a solution.
I found that most experienced developers converge on adapting a similar mindset, yet many of us don't see the full implications of this statement. It was the same with me.
In my case, grasping this concept took 5 years. Over that period, I thought about software as a combination of complex systems built from components using architectural and design patterns, written in a programming language, usually using some frameworks or SDKs, a set of libraries, compiled by a compiler and executed by a CPU. Sure, I knew people use it in the end, but if I were honest, deep down, software was
code art to me. The intellectual adventure of solving hard problems and producing eloquent code at the same time. It made me proud (and a bit addicted) when I succeeded in doing that. All I needed was an "excuse" to write the most epic code I was capable of producing. Of course, this is something I only see clearly in hindsight. At that time, I thought I'm simply doing what software engineers are supposed to do. Can you relate?
It changed when I started preparing to step up into a technical leadership role. When you are in charge of tech stack decisions, and money is on the line, especially if it's the money of somebody else, the context of software becomes much wider. You start to take a lot more non-technical variables into the equation that, in the end, will need to be translated even to everyday development practices. I worked in outsourcing, there you often face questions like: "What technologies should we use to give the most benefit to our customer, for the best price while also generating the most profit for us?" It's a question I was never taught to answer during my CS studies, nor the bootcamp I did. I bet nor you. We could wonder why is this the case, but that's not he point now. In this setup, it's easy to see why software is first and foremost a solution. It wouldn't be created if there were no problems that need to be solved for somebody. Often for somebody who's willing to pay for the effort. There can be other kinds of motivations than business ones, like curiosity, social incentives or an ideological objective (e.g. the open-source-software movement) but there's always something more behind creating it than the journey itself. No big news right? However, this hints at a much deeper, underlying truth:
We as developers are not paid to code, we are paid to create experiences and capabilities.
This might sound outrageous. Perhaps you say "writing code is in my job description", yet the reason there's a job in the first place is not because people enjoy reading our code like poetry. Some of us struggle to accept this reality and value "coding excellence" above real-world applications but all that leads to is unnecessary suffering for those who eventually have to align the "perfect code" with the real needs of the project. Those who can embrace it however, will see our job in a much different light. They can focus on the effects we create with software instead of the ways we create software. But this is not enough to get to the bottom of this topic. We must go deeper to face another mind bending realization:
Nobody needs software.
Yes, you read it right. The fact that we create software to solve problems means what actually matters is a solution, not specifically a software solution. What people really want are the experiences and the capabilities, not the tools that provide them. If we would magically invent something better to fill the same needs, people would abandon software just as they replaced horses with cars.
Part of me felt hurt while writing these down. I love my profession and would never say that software is irrelevant. On the contrary, it's a crucial building block of our society and human progress. What I want to achieve here is aligning our perspectives on the goal of our work. I believe this is the highest level point of view that can be used as the foundation of successful tech decisions. We first need to clearly see the main purpose of what we do, and that is to solve human problems.
Ultimately, we solve human problems.
I would like to let that sink in. Over time, this can transform how we assess anything related to software, and that is a necessary transformation if we want to deliver amazing solutions, not barely excellent code.
However don't get me wrong here. I'm not advocating for a profession change at all. (Who would read the rest of the book then...) Software developers are mainly technical contributors in delivering the solutions. We should be first and foremost experts in building software systems. That's the tool of our trade. But its role stops there. Coding is only a tool. Like the scalpel for a surgeon. - Who cares how expertly they used it during an operation if they solved the wrong problem in the process? In reality, doctors take great care to learn how to identify the problems based on their symptoms and to know exactly what to do with their skills to fix them. We programmers should work more like them. If our task is to provide solutions, we should know the potential problems and our options to fix any of them. We are well covered from the technical aspect, how about the human and business perspectives?
If you are working at a big company, you have might thought, hey that's the job of the business analysts, UX researchers and the managers. What do I have to do with this? We should just get the requirements and implement them in the best way possible. - Sure, no developer should pick up those roles in your situation, however I will show you in Chapter 8, there are roles in the process of planning software functionality, that can only be filled by developers. Your unique insights and skills are required to optimize the solutions, even on the conceptual level. There are question nobody else can answer. Even questions nobody else would ask. When we don't take part, the companies and users will miss out on improvements. Also, even if we are implementing ideal requirements, we can totally ruin the outcomes in ways that other professions can never fix. In a nutshell, your participation is indispensable to create the best software solutions.
If you work as a freelancer, as an employee at a small company or you have your own product, finding the best solutions (and sometimes even the problems) are on your shoulders by default. I'm sure you know it firsthand how hard it is to ensure a tool or approach is a good fit for a task and that other people don't care about the code at all. They just want their wishes fulfilled and the means to provide it - up to a certain extent - are irrelevant.
We can sum up this part with the first axiom of the Full Context approach.
Axiom: Software is a solution to human problems. Our job is to solve (some aspects of) those problems through code.
This is why people buy software, this is why companies make software and this is the real reason we get paid. It's the most fundamental reference point. Every decision we make should ultimately be evaluated in this light. This is how the most effective developers think about our job.
Let me be honest with you. I was not especially happy when I first realized this. As a technically minded individual, what I love the most is solving hard logic problems and building beautiful structures. It's much easier to find that in programming than in people. Like beyond comparison. However, my expectations turned completely around after some research. I soon found out, there are actual laws and principles driving the human dimension, too. We are much more similar than different. Our problems are generic, just as the ways of solving them. From a high level perspective, there are only a couple of ways software can affect us and all of these can be combined into a system that you can easily understand. This is exactly why the topics I'm covering are timeless in nature. I explored the related problem- and solution spaces and mapped them to our everyday developer life so the hard part is done. All that remains is taking the knowledge away with you and applying it to make better software for everyone.
Because some of you might be inclined to think otherwise, I want to emphasize it's better for everyone and that includes you. This book is not only about the users, there are many people involved with our work, having unique problems and we will cover all of them. Next up, you will see the first two.
If you wrote down your definition of software, now is a good time to look at it again. Does that definition seem narrow in perspective? If the answer is yes, I'm really glad because the context of software got wider for you. A transformation has begun! If it was in line with your vision, read on to see if I found the same consequences as you. If it doesn't make much sense now, just keep going. You will see that everything falls nicely into place as the material unfolds.
As software engineers, we instinctively imagine the overview of software delivery similar to the above picture. It's an ongoing, large scale construction. There are many folks busily working on different levels of the operation, from investors and managers to architects down to the construction workers. I want to show you that the Full Context view of the landscape is much different, way more simple and leads to meaningful conclusions. (Open the toggle below)
The Full Context overview of the software delivery landscape
There are only two elements in the scene:
- Client - who has an unsolved problem, they are the users or customers of the product
- Provider - who offers the solution or will create it, they are the vendors of the product
Interpreting this takes redefining software a step further. What's happening here is essentially an exchange between two parties. This way software is a solution to two problems at the same time. It helps the users to achieve their goals, every developer knows that. It also helps to run the business producing it. Which is a much less understood aspect of our work. How do you contribute to the success of the company? Do you know exactly how to tell if a tech decision will have a positive or negative financial impact? Are you aware of the ways your everyday tasks influence the project outcomes? How much do you think about such questions? Most regular developers simply don't do that. And why would they? This is traditionally a concern that other professions like to keep to themselves. Of course it's not true at every company. Some of the biggest players like Spotify, Netflix, SoundCloud and many others have thinking about real-life impact on their promotion criteria list for software engineers.
We are sustaining a business with our work. This is a fundamental part of its nature.
I believe, to make the best tech decisions, we need to adopt a mindset where this is actually a part of our job. Do you think about it that way? We should learn to connect even our everyday decisions with their financial results and consider them accordingly. To a degree, caring about the financial performance of the companies is already the standard approach. Many developers try to improve workplace attractiveness and reputation, hiring opportunities, company culture and development effectiveness, among other factors that all concern the business's success. However, we rarely go beyond and look at things like customer experience, quarterly revenue growth, or a project's return on investment. Freelancers think more about how to create additional value for their clients with the goal of build lasting partnerships and business owners strive to gain deep insight into the financial domain, yet we still lack a simple system that connects these two dimensions: tech choices and business results. We software engineers have a firm grip and a dedicated role on the first. Who else could align development decisions and finances then if not us? Not exclusively us, of course, but given some business goals and budget considerations, it's our job to find the technical ways that will deliver those financial results within the set constraints. These ideas form the foundation of:
Axiom: The developers have direct responsibility for the full impact of their work.
Whether that's on the lives of our users or the lives of the businesses, it's part of our job to make sure we are delivering improvements (and to know what is an improvement in the first place). If we can't see the connection between these effects and our work, we can't make the best tech decisions ever. It's a key to become an effective developer and the best of us own all their actions even in this sense. In the coming chapters, I will show you in detail the general business and user needs and all the tools we have to handle them through tech. This is actually a big deal! I wish I could've learned this before I became a lead. For some positions, handling these responsibilities is an explicit requirement, but even small, every-day decisions can add up over time to great effects. We can all benefit from learning about these relationships.
Before we move on, I want to clean up a common misconception. This will be important later on. Do you agree that software and code are not the same thing? Pause reading and give it a thought, then continue from here. Did you have some ideas racing through your mind that are trying to contradict the question? Like, what else would software be? It IS code. It has to be written then executed. Software is just that, executed code. Do you completely agree? Better not, because that's not the entire story! It's a distinction I only had made after I started writing this book. Code and software are deeply connected, but depending on which one you look at, the effects are drastically different and their interests are sometimes opposed. I found no better explanation than an example: Think about yourself working on a product. What do you see? Are you looking at the source code? Maybe sometimes checking the app if the modifications you made are really working out as expected? What do you think about? The internal connections of the codebase? The best way to implement something? Ways how to debug that annoying issue that just doesn't want to go away? Whatever is the case, I bet you spend most of your work time with the code. (OK, maybe with meetings) Now think about the user. How do they interact with the product? Are they filling in forms? Or simply tapping and scrolling away? Maybe they are having fun or doing their daily job. Any way, I'm sure they are not looking at your latest commits and how beautifully you applied those design patterns or functional programming techniques in it. It's obvious that from the perspective of these two sides, code and software are totally different things. Code is what you see when developing the product, and software is what you see when using the product. But here comes the catch! They are actually the same thing! Software is executed code. I said it's not the entire story. This leads to a conflict of interests we usually aren't aware of. We often get praised and recognized for our technical prowess, and we are also hungry for new development challenges. That means we are incentivized and biased to create great code, not so much to create great software. The sad truth is that quality of code can but doesn't necessarily correlate with product success. In some situations, the opposite is true. By lowering the bar for code quality, you can focus more on improving the product's quality from your customers' perspective. Sure, it's a fine balance with temporary gains and long-term consequences, but it highlights the duality of software and code. Because of this nature, we have to win a war on two front lines at the same time.
We are responsible for producing good code that executes as good software.
Our profession holds the necessary knowledge to optimize a code base or a system architecture, but can you honestly say you know how to optimize software as a product? In that sense, we are much less software engineers than we are code engineers. The takeaway is this: Do not think that high-quality code automatically creates high-quality software or leads to business success. We need to consider all these factors separately but at the same time.
The third axiom of full context software development is a summary of these ideas.
Axiom: Software and Code are different views of the same thing, with distinct concerns and interests. It's our job to care about (some aspects of) both.
Software is what you see when you use the product, and code is what you see when you create the product. This means we are usually planning software with the users in mind and writing code with our own concerns in mind. By realizing this duality, you took a step towards internalizing a wider perspective of our work, that can help you adjust your focus between technical and real-life considerations.
To make well-grounded tech decisions, it's essential to understand all consequences of a choice. It means we have to know about the full context of software development. You already saw its 2 major components: the user and the business. By taking a closer look at the latter, I found it's best to handle 2 aspects of it separately. This gives us 3 key areas:
- the business aspects of the company we work for
- the organizational structures and processes it has in place
- and the life of our users or customers.
To really understand what software is, we have to examine it from all of these perspectives. The rest of the book will focus on exploring these contexts and our influence over them. I came up with a nice name that helps to memorize these building blocks.
Business, Organization, User → B O U → B y On d U → Beyond You
In a sentence:
The full context is: beyond you.
It has a meaningful implication because we developers rarely think about these areas too highly, so it's beneficial to remind us about all effects of our action. On the other hand, it feels somewhat exclusive, which I'm not really fond of, as our concerns are actually included in the full context of software development. I covered them as part of the organizational aspect.
These ideas form the basis of the Full Context perspective. They show the basic issues I wanted to tackle. Our lack of insight into how our work relates to the connected areas of life and an industry wide need to have a simple system to navigate these connections. Adopting a mindset based on the 3 axioms will transform the way you work for life and the impact of that work for the better. Let's start to explore the details in the next chapter!
Summary: Software, in its essence, is a solution to human problems. First is the problem of the user, the reason why they need the product. The second is the problem of the business, a means to achieve their mission. The third is the problem of the developer, their love for the profession and need for a living. Accordingly, we have 3 jobs, to solve the user's problems and sustain the business all while taking care of our own needs. How do our choices affect these? We will explore that through the 3 major concerns of technology decision making: Business Value, User Value and Organization Value. Notice there's no mention of programming among our jobs. This is because in the full context view of our profession, code is simply a tool we use to get the real tasks done. The most important takeaway: We can only do our real job if we realign our focus according to these goals. In addition to the technical details we should put effort into understanding:
- The user needs and finding ways to fulfill them ~ with code.
- How the company works and what's our part in making it successful ~ with code.
- The long term effects of tech decisions over our life and of our colleagues. ~ by code.