Programmer's Path to Cultivation Improving Design Skills

Programmer’s Path to Cultivation Improving Design Skills #

Hello, I’m Zhang Shaowen. Today I want to share an article written by my friend Chang Yuan about the path to improving design ability. The column has entered the architecture evolution module. Since everyone has different understandings of architecture, we also encounter various architectural design problems in our work. Many times, our architectural design ability is improved through continuous theoretical learning and practical design exploration. Therefore, on the road to becoming a design expert, we definitely have some of our own experiences and insights, and of course, some pitfalls. Today, Chang Yuan shares his path to improving design ability, hoping to share his experience with you. You can refer to his path to strengthen your own design ability and avoid unnecessary detours on the road to becoming a master.

Whenever I finish an internal design training, I often have colleagues ask me: How can I quickly improve my design ability? I think this question is very representative and represents the voices of many programmers on their arduous path to improvement. Today, I would like to share the path to improving design ability as I understand it, and I welcome you to leave a comment and share your own thoughts and experiences.

1. Coding Practice

Code experience is a very important thing. When you have less than 10,000 lines of code experience, if you ask me how to improve your design ability, I can only tell you not to worry too much and focus on the theory for now. Just start by writing code.

On average, a programmer writes about 200-300 lines of code per day. You may say, “I write at least 1,000 lines of code a day, right?” Don’t forget, after you finish coding, you still need time for testing, debugging, optimization, and bug fixing. You cannot keep coding all the time.

I won’t go into coding conventions too much. If your code is still messy, it’s better to focus on getting the basics right before talking about design and architecture.

In addition, as a “code cleanliness sufferer,” I recommend that instead of doing batch formatting or manually organizing your code after writing it, each character you type should already conform to the conventions. Habits really matter. Sometimes, during recruitment interviews, I really want to add a section where candidates have to write a program to complete a simple but error-prone task on the spot, in order to assess their basic coding skills.

2. Theoretical Study

Simply put, it means reading books and blogs, and learning from all the resources available to you, but with the condition that the content has high quality. For example, for books, I recommend “Refactoring: Improving the Design of Existing Code,” “Agile Software Development: Principles, Patterns, and Practices,” “Applying UML and Patterns,” “Design Patterns,” etc. You also need to learn principles of object-oriented design (the five SOLID principles).

“Design Patterns” is a rather old book, only about 200 pages long. But it might be the most difficult book to understand—it might take you a month to finish it (if you read a novel, you could finish 200 pages in 3 hours). And even if you finish reading it, you won’t understand everything, and it’s very likely that you’ll understand less than 30% of the content. What I want to say is, it’s okay if you don’t understand everything, just read it carefully. Don’t get too hung up on it, because this doesn’t signify a problem.

Additionally, I want to mention that multithreading is something that programmers must master and fully understand. Advanced technologies like Grand Central Dispatch (GCD) can hide the issue of insufficient understanding of multithreading because they are too easy to use. Also, don’t say that you have completed complex projects without writing any multithreading code, and don’t say that there haven’t been any problems with the multithreading code you casually wrote. You can try showing your code to a technically skilled colleague and they will likely be able to write a demo that causes errors or crashes in just a few minutes. 3. Practice

Now that you have gained some coding experience and have learned enough theoretical knowledge, it is time to get hands-on. Take the time to think about how to apply the theoretical knowledge you have learned to your projects. Through practical application, make sure to fully understand those theories and use them as a guide for your practice. During the practical process, you need to set aside your previous confidence, first negate your previous methods, and ensure that each thing you create shows improvement and progress compared to before.

4. Review Theory

You can already see your progress and realize that you have done better than before. However, you still feel that it’s not enough, as if there is a bottleneck. Congratulations, you can already see your future potential.

Pick up your books again and review those things that seemed unclear before. You will find that what you couldn’t understand before now becomes clear, and you no longer feel the perplexity that you once had. Even for content that you thought you already understood, reviewing it again usually brings new insights.

5. Practice Again

At this stage, you have mastered a lot of knowledge, and not only do you have abundant practical experience, but you can also handle various theories with ease. However, you find that your designs are still not professional enough, and when you look back at code you wrote in the past, you will be surprised: Oh my, who wrote this code, how could it be like this! And then, let’s not say any more… At this point, you have entered a stage of self-reflection, mastered the learning methods that suit you, and anything new you learn in the future will no longer trouble you.

6. Summary

Don’t get too complacent yet (don’t believe it? Try giving a lecture to your team), you still need to summarize - summarize your learning methods, summarize your project experience, and summarize your knowledge of design theory.

If you can have your own unique understanding and not just stick to using mature design patterns, if you can summarize some design principles based on your own experiences and lessons learned, that would be great.

7. Sharing

Sharing is the best catalyst for learning. When you are preparing for a training session or sharing a lecture, you will find that things you thought you already understood are not completely clear, because you can’t explain them well. In fact, you still need to delve deeper into your studies. This will force you to study again in order to truly master the topic before you can confidently step onto the stage. Otherwise, when others ask questions, you won’t be able to answer them. Above are the stages that I believe every programmer must go through on the path of cultivation. Now, I will share a few other methods that are very important for improving design skills.

  • Develop the habit of designing before coding.

Almost all programmers at first are unwilling to write documentation or put effort into careful design. They can’t help but let their restless hands start typing on the keyboard, thinking that success and the correct work posture can only be achieved by writing code line by line.

My suggestion is to avoid coding until the requirements have been thoroughly discussed, otherwise you will definitely have to redo the work.

  • Design is more important than coding, and interfaces are more important than implementations.

The process of creating interfaces is itself a design process. Interfaces must be carefully considered and simplified as much as possible, striving for simplicity while meeting the requirements.

Also, don’t brainstorm alone. You can create a simple prototype first and then discuss it with the users until they are satisfied. Don’t design interfaces solely based on user requirements. Refer to the MVVM pattern, where the ViewModel is a further encapsulation of the Model based on the needs of the View. It is inappropriate to directly design these interfaces into the Model.

  • Don’t blindly follow design patterns.

Design patterns are just a set of methods for problem-solving. You can also have your own methods. Of course, if you use design patterns well, your design will appear professional and elegant. After all, the hard work of predecessors is very valuable. However, if they are misused, they can also lead to more serious problems and even disasters. I think the principles of object-oriented design are more important, and some principles must be followed (such as single dependency, SRP, etc.). Design patterns themselves adhere to these principles, and some patterns are designed to comply with certain principles.

Abstraction is not omnipotent. Use it when appropriate and carefully consider it. When there is a better solution that doesn’t require abstraction, try to avoid it. I have seen too many cases of excessive abstraction and over-design, which increases maintenance costs too much and is not as natural to write as the most natural way.

  • Be open-minded, learn from peers, stand on the shoulders of giants and others.

When someone shares their opinion, accept it (whether you agree with it or not).

Many programmers have a “problem”; they think they are extremely skilled and are unwilling to accept the opinions of others, especially negative opinions. However, whether it is theoretical learning or coding practice, learning from peers has the greatest impact (three people walking together must have my teacher).

I often benefit from discussions with team members. When I can’t figure out a problem, I throw it out for discussion, and usually, the best solution emerges.

In addition, discussing with other team members has another benefit: when your design involves compromise or lacks professionalism, others won’t question the code because they have also participated in the discussion. You don’t have to spend so much time explaining.

It is essential to have discussions with others during the design phase. I have always been against the approach where one person completes the design and writes the documentation, and then gathers everyone for a review meeting. Although it does have an effect, it is not optimal. Because everyone did not participate in the design, they may not have a deep understanding after a single meeting. Most importantly, if design issues are discovered during the meeting, but they are not fatal, they usually won’t be sent back for redesign.

On the contrary, if there is enough discussion in the early stages, and everyone knows your ideas and plans, and there is a design document in the end, when others read your code, they don’t need your guidance at all. This will make future work handovers very smooth, why not do it?

Finally, I want to appeal that when you are modifying and maintaining someone else’s code, it is best to have in-depth discussions and communication with the module owner. Let them understand your requirements and solutions, and ask for their help in evaluating the feasibility of the solutions and whether there are any pitfalls. If you happen to be the module owner, exercise your power and refuse to accept problematic code submissions that do not meet the requirements.

Feel free to click “Share with a friend” to share today’s content with your friends and invite them to learn together.