The Productive Developer
Everyone has a different set of goals and objectives and hence, the expected value vary depending on the individual.
It is hard to know if you are productive at all.
Productivity is the delivery of value, and value is not all about writing code or delivering an API faster than your coworker. Is about making decisions that could not make you a better programmer but improve you as a developer.
Directions
I have encountered numerous colleagues and coworkers who frequently ask themselves questions like, “What should I be doing right now?”, "Should I focus on fixing the system that crashes every 24 hours?" or "Do we need to rewrite this system?" In an attempt to justify their jobs, but in a wrong way.
Developing isn't always about writing code, there is some value delivery that can come in all shapes and sizes, from composing an email, placing a phone call, or even deleting code.
The ability to find those opportunities is the hardest part that I will talk about in the next.
Those opportunities should be very clear to you because if you happen to be dealing with an issue within your organization's software, you might find that simply adjusting certain parameters would resolve it. It could be as simple as adding a cache layer to deal with problems associated with memory in the code. On the other hand, if it is due to an increase in user traffic on the website, you might try writing a piece of code specifically tailored to better manage increased demand but could be easier just setting up a cache system.
Those potential solutions are hard to be taken because it sounds like you are lazy or you are a bad engineer, but I'm going to try to show you the importance of delivering code that you don't want.
There are some cases that you must keep in mind that the best resolution may not always be the most obvious one, like rewriting the system to something like microservices to handle more traffic where it could be as simple as adding a few lines of code to the existing system. This is where the concept of "productivity" comes into play.
Root cause
When it comes to software development, we usually put the fault on the current stack or the current systemic issues. It's because we have too many options of frameworks and libraries to choose from. We are always looking for the next big thing, but we never stop to think about the productivity of the current stack.
If your team knows how to program in that stack and that decision is already made, then it's just unfair to put the fault in that decision. It's more plausible that the programmers that are complaining about the current stack are just not motivated enough to work in the company. Developers should care about value delivery but most of them have an issue with a wider look at the project and they are not able to focus on the task at hand, we will discuss this in detail in the next sections too.
To make those decisions wisely you should have already taken some experience, but I'll try to pass some tips on measuring the future to make those decisions more assertive.
Measuring
It's foolish to measure your productivity by the amount of code you write, commits you to make, or bugs you fix. Not only is this approach dangerous to your culture but it can lead to a lot of frustration and resentment.
Unfortunately, many times managers are unable to recognize the true value of the employee and this leads to frustration and resentment. It may even further lead to a loss of motivation. This feeling of inferiority and comparison with others can hurt the productivity of the employees. Therefore, it is essential to create a culture that values each individual’s contribution and rewards them accordingly.
Managers must understand that a team is built to share the responsibilities and workload and it requires collaboration and collective efforts to achieve the goals. Therefore, team members should not be judged on individual performance but rather on the collective achievements of the team. This will help in creating a conducive working environment and foster productivity.
It is also important to identify the areas of improvement, rectify them and set realistic deadlines to complete tasks. Managerial support and guidance should be provided to employees to ensure that productive and sustainable work is done over the long term. Additionally, clear communication should be established between the client and the employees. This would ensure that the goals and objectives are being met satisfactorily and help in tracking progress.
Productivity is not just about getting things done faster rather it is about delivering value while ensuring quality. It is up to the management to recognize and reward the effort of each employee and provide the right environment for them to thrive. As an employee, one should strive to add value to the organization, take initiative, and develop a positive attitude toward work. This would ensure that productivity is maintained and sustained.
Be scared of writing code
Writing code is dangerous, you create dependency of the code that you write event without develivering to your client. Everytime that you write a PRODUCT you are creating a unlikely to break experience to your client. You are creating a dependency that you will have to maintain for the rest of your life or until the company dies.
That is a hard phrase but it's true.
When you are creating a new experience, even the better one, you are creating something with some level of friction, without exceptions. So, If you are changing tons of code, be sure that this is the best approach to solve your client's problem.
Let your client be your guide
One of the most important lessons that a programmer can learn is to never assume what their client wants but to ask them instead. Asking the right questions allows you to better understand the problem, and write code that effectively solves it, nothing less, nothing more. Doing so will also save you time by avoiding writing code that may not be needed - something that is often a huge waste of resources and can lead to frustration for both parties.
- Tip 1: less code -> less maintenance -> fewer bugs -> more productivity -> more value delivered!
- Tip 2: Assume that for every line that you write, you will find a bug in the future, so don't try to make perfect code every time.
Good communication with your client is essential. Take time to comprehend the problem and details about the solutions that your client requires. Explain the pros and cons of various approaches to problem-solving.
Programmers with doubts about the product are usually more frustrated with the project since they are not able to provide the real value that the client desires.
While fulfilling client requests can be straightforward, a programmer's true satisfaction lies in solving problems. Understanding and addressing the client's core needs is the most challenging, yet rewarding, aspect of development. Those focused solely on code elegance, and not client outcomes, miss the distinction between a programmer and a true developer.
Prioritize client value, and you'll often find that your previous complex solutions were the source of technical debt. Embrace the Pareto principle (80/20 rule) to deliver maximum impact with minimal effort
Tech debt, the good and the bad
Small product + few users + low capacity = add features
Big product + few users + high capacity = cut features
Small product + lots of users + low capacity = improve stability -> refactor code -> add architectural capabilities
Big product + lots of users + high capacity = Why are you still here?
Having too many users can be an issue. If a product is having success and is introducing more and more users, it's essential that the system remains stable and reliable for them all while continuing to add relevant features and updates. However, doing so can bring up a problem: scalability.
When adding new features, keeping up with numerous users, or incorporating new elements in the system, it's very important to keep in mind the costs and risks associated with this process. It might be tempting to try and scale up as quickly as possible, but if it isn't done correctly, it can lead to a huge mountain of technical debt that will be difficult to pay off.
Though it might make sense to try and become the next Google or Facebook, this could be a dangerous ambition. These companies did not start out as huge juggernauts; they had to start small and stay focused on the right elements to reach such heights. Rather than trying to get too ambitious too quickly, it is fundamental to stay focused on what really matters.
Tech debt, or 'bad code', is something all programmers can relate to. It's that accumulated result of taking shortcuts and compromises when writing code in order to get a project finished quickly, often at the expense of code quality. This can lead to decreased productivity, decreased code readability and reusability, and a range of other issues in the long run. But, smart use of tech debt can allow for faster development of working prototypes and proof of concepts, catching bugs in a shorter amount of time, or even fixing existing code faster than would otherwise be possible.
It's hard to see, but some tech debt would not even exist if you simplify the code enough to be able to quickly replace it entirely with a new one that fits your needs. With that said, I always would prefer to write replaceable code that solves my client's problems instead of taking twice or triple the time to create something that would not be perfect the first time and could cause maintainability issues in the near future.
You create the real tech debts
Programmers can feel the pressure from the management, clients, or even themselves, to add more features and not ask enough questions. Doing this can lead to tech debts, which is a vicious cycle that will only result in creating a bad product that fails to solve the intended problem.
In trying to please the client, small actions are taken that lead to satisfaction from their side. However, this squanders time and energy away from actually solving the problem and attending to the next one. This is why it is important for the client to be aware of the exact solution being provided. Failing to do so puts the programmer in a difficult situation; needing to make what the client requests for the sake of preserving them as a client.
Having foresight and understanding the potential costs and risks that come with increasing complexity in a project are key to reducing tech debt. Asking questions and finding out more information from the client can aid in preventing time and energy from being wasted on features that could have been avoided altogether.
It is also important to recognize that some tech debts are overrated, and as a programmer, one must decide on whether to take a shortcut or not, based on their values and preferences.
When making big decisions like whether to create a new abstraction layer or microservice to address a problem, it is important to analyze the cost of each option. Creating a new abstraction or microservice might seem like a good idea but often leads to an increase in tech debt. This is because when attempting to solve a problem, it is tempting to build something that attempts to handle all possibilities (because it's common for you to try to find ways to write less code in the future), rather than focusing on solving the immediate issue at hand.
Your code should be replaceable, should be clean, and straightforward, while still easy to understand. Doing this will minimize any time and effort that needs to go into fixing and continuing the code in the future.
Symptom of Delivered Value
Forget about tech debt being your fault, as a signal of a bad code writer. When a tech debt is taken with responsibility, it should be seen as a shortcut to the value.
Tech debt isn't just about taking the easy way out to get something done. It's about making smart decisions that follow team principles and bring value to the customer. When tech debt is intertwined with the value that you are bringing, it's usually not hard to maintain or refactor. It's always clear which team made that decision.
However, some tech debs are not poster able. A simple example would be the case where you could save time by skipping tests, but you need to be mindful that refactoring the code at the end of the project may take longer than writing them in the first place.
That being said, the main goal of your company should always be to deliver value to their customers, not perfect code, if you try to rewrite an entire system to achieve a better design that nobody needs to maybe improve the productivity of the team on create repeated tasks, that usually creates a barrier to deliver different kinds of value to your client.
Domain Knowledge
The more you understand about the domain you're working in, the more likely you are to be able to write code that is both clean and maintainable.
If your code is well written according to the domain of the product, it's hard to turn in legacy code. Just some minutes talking with your stakeholder should explain why that code was written in that certain way.
Increasing the relationship with the "domain experts" from the project, such as business users, design experts, and other developers, can save time and energy, allowing you to focus on the important tasks at hand. And solve more real problems.
For example, if your boss says something like:
'We need to add a new feature to the system that allows users to upload their images.'
You should ask questions like:
- What type of images are allowed to be uploaded?
- How are we going to store the images?
- Who is going to be responsible for approving the images?
Asking questions makes your decision and can then decide on the best way of solving it. You might even find that someone else has already solved the same problem, saving you the effort of writing your code.
Understanding your problem domain means that you can write less code, and more efficiently!
Don't be a Perfectionist
As programmers, it's easy to get caught up in the details and try to create something perfect. But in reality, perfection is impossible—the possibilities are infinite. Instead, it's better to think of perfection as when you can no longer find a single change that will provide more value.
To create something that meets the standards of your client, you need to iterate on the code. Make mistakes and then build on them. Take feedback from the client and use it as a guide for the development process. Don't be afraid to release something that isn't perfect, and don't sweat the small stuff. Identify what's necessary for the client and deliver it. Know when to draw the line and move on to the next task.
At the end of the day, progress is more important than perfection. So don't let perfectionism stand in the way of your success and getting things done.
Care About the Understanding of Your Code, Not Just the Beauty
Writing code is all about communicating your intentions to both the computer and other programmers. It's essential to make sure that your code is understandable; otherwise, it can lead to confusion and frustration when someone else tries to comprehend it.
Beauty should be a secondary priority when writing code. While the syntax and layout should still look neat and organized, it should not be the main focus. Instead, aim to make sure your intentions and purpose for each part of the code are clear.
To make sure your code is comprehensible and easy to read, use descriptive names for variables, functions, and classes. Additionally, add comments to explain any complex logic or tricky concepts. By doing this, other developers will find it much simpler to understand your code.
Finally, keep your code organized. Break up longer sections into smaller chunks and use proper indentation to make it easier to read. Doing this will help maintain the clarity of your code and avoid any confusion.
How to Start Coding
Are you starting a new project and feeling overwhelmed with questions? You need to know what to do, how to do it, and how to deliver it. It's exciting to start a project, but you also need to be aware of the risks that come with answering those questions. That's why it's important to keep it simple and focus on the value you're delivering.
Here are some questions you may want to consider:
What is the language my team is the most comfortable with?
What is the framework my team is the most comfortable with?
What is the IDE my team is the most comfortable with?
Which design patterns can save us time?
What architecture can save us time and deliver value?
Are we replacing a system the size of Netflix or Google, enough to justify using microservices architecture?
How much time can we spend delivering value to the client?
What is the main goal of the client?
What is the MVP we can deliver?
How can we create a delivery pipeline to save us time?
Answering these questions will help you get started on your coding journey. With a little bit of effort and some creative problem-solving, you'll be well on your way to success!
What Can We Learn From Agile, Lean, and XP?
Agile, Lean, and XP are all popular approaches to software development, each with its own set of strengths and weaknesses. It's important to understand the basics of each before deciding which one to use on your project.
Agile emphasizes rapid development cycles, customer feedback, and teamwork to produce quality software. It works well for projects that call for frequent changes and adjustments.
Lean focuses on reducing waste and maximizing output through iterative improvements. It takes a "just enough" approach, meaning teams should only do what is needed to get the job done, keeping costs to a minimum.
XP (Extreme Programming) relies heavily on automated tests to ensure code quality and encourages frequent releases to get the software to customers as soon as possible. It also encourages a team-oriented approach where everyone communicates constantly.
Though each approach has different philosophies, techniques, and tools, they all share some basic principles: start with what you know, keep the end in mind, don't make things more complicated than necessary, be simple and pragmatic, and refactor for yourself, not the next programmer.
When you keep those principles in mind, the choice between Agile, Lean, and XP becomes much easier. You can simply ask yourself which will provide the most value. And with that, you'll be well on your way to success!
You Need the Mindset From TDD
If you want to be truly successful in development, you need to understand the mindset behind Test Driven Development (TDD). It's true, TDD is sometimes overkill, but it's important to realize the power it can give you.
Start by outlining your code and try to use the simplest way to solve the problem. This will help you stay focused on the main goal. Plus, TDD forces you to think about all the different use cases that might come up.
TDD can save you tons of time and help you avoid common mistakes. By writing tests for the important parts of the code that could lead to major problems if they don't work as expected, you can prevent yourself from rewriting the same code multiple times and be more productive.
And, even though TDD is a great tool, it's important to note that it is not a silver bullet. You still need to have a strong understanding of coding and be able to troubleshoot issues if they arise. With the right mindset, however, you will be able to utilize TDD to its full potential and make your coding life a little bit easier.
Your Code Is Not Your Baby
You should never be afraid to delete code that's no longer needed or refactor it if it's not working as expected. It can be tempting to fall in love with the code you write, convinced that it's just perfect and should never be changed. But that's a dangerous attitude to have when coding.
Think of code as a tool used for solving problems—not a child. It's important to take an agile approach and iterate on your code as necessary. After all, somebody else is likely going to be reading and maintaining your code, so make sure it's easy to understand and follow.
You Need to Be an Exceptional Communicator
Software development relies heavily on effective communication. You need to be aware of the work your team is doing and be able to explain decisions to both developers and non-developers.
It's essential to have the ability to explain technical concepts in a way that everyone can understand. Also, you should be able to ask the right questions to ensure the project is heading in the right direction.
It's equally important to identify any confusion or misunderstanding quickly and take steps to resolve them. This is especially important when working with clients, as it can help you deliver the value they need more quickly.
Moreover, you should always set clear expectations with your client. Make sure you are clear about what you can and cannot do, and let them know when something isn't possible.
Good communication skills are essential to successful programming, and it takes practice and dedication to develop them. To find the time to hone your communication skills, and you'll soon be an exceptional communicator!
After the Storm Comes a Calmer Seas
Your team has reached the MVP, gotten investment or venture capital, and you have many active users - growth is accelerating! You're now in the phase of scaling your system, and it's time to take on new challenges.
The main challenge at the moment is how to refactor your code to make it more maintainable while also reducing tech debt. It's important to understand the philosophy behind refactoring; it's not about rewriting code to make it aesthetically pleasing, it's about making sure the code is easy to read, interpret, and maintain.
Rather than making major changes, small incremental modifications will have the greatest impact in the long run. Start by fixing typos, improving variable and function names, and reducing the complexity of code, opting for the simplest solution instead.
The goal of refactoring should always be to ensure the code is still working as expected but is easier to understand and maintain. Automated tests are a great way to do this, ensuring that the code performs as expected after refactoring is complete.
By taking the time to refactor your code, you can get your system ready to scale up and handle more users and requests without any hiccups. So make like a sailor and set sail for smoother seas!
Never Stop Growing
Having a deep understanding of the language and platform you're using is essential to writing good code. That means not only understanding the fundamentals of the language, such as data types, control flow, and memory management, but also familiarizing yourself with best practices and industry standards like coding conventions, readability, and scalability.
Debugging your code is an unavoidably important part of software development. Having the ability to identify problems quickly and accurately and take corrective action is what ensures that your applications are running as they should.
To become a great software developer who can write code that's functional and maintainable, it's important to never stop learning, growing, and seeking out new experiences.
Finally, collaboration with your team and peers is an essential part of creating successful software. Listening to others' opinions and understanding their perspectives will help you find the best possible solutions to any problem. Communication is key in software development - understanding what your colleagues have to say and explaining your ideas just as clearly. So, don't be afraid to speak up and make sure everyone's voice is heard!
Writing Code That is Elegant and Understandable
Software development is all about creating functional applications that solve problems, so careful attention must be paid to the design and readability of the code you write. After all, if you're working on a project with a large team or with a client who will be reviewing your work, your code needs to be easily understood and navigated.
Of course, aesthetic beauty is also important - but it should never compromise the functionality of your code. Writing code that is both elegant and understandable can be tricky. Fortunately, there are techniques you can use to help make your code more readable, such as using meaningful variable names, indenting correctly, and writing comments throughout your code. With a little bit of effort, it's possible to strike a balance between elegance and readability that will make your code a joy to look at and a breeze to understand.
Ending the Journey
Software development is an ongoing journey that never ends; with new technologies and methods being constantly introduced, there is always something new to learn. As you progress in your career, it's important to stay engaged and motivated by setting personal goals and challenging yourself.
Organization and staying up-to-date are also key; attending conferences and seminars, reading up on industry publications, and maintaining relationships with peers and colleagues can help make sure you don't miss out on any important news. It's also essential to practice collaboration and communication regularly.
By keeping abreast of the latest technologies and trends, and applying your knowledge to real-world projects, you can ensure that you remain a productive and effective developer. With hard work and dedication, you can improve the value and produce the best applications possible.
At the end of this journey, you should strive to create code that is clean, efficient, secure, and maintainable without the hassle of using the latest technology possible. With the right skills and the right mindset, you can be confident that you will continue to develop quality applications and make a positive impact on your work. So here's to the journey ahead—may it be filled with exciting successes and rewarding challenges!