Design patterns : The best exercise for reducing burnout

I try to write a program the minute I find a new programming language. I do this with no prior experience or knowledge of said language. Later on, I’d revisit the language’s basics and design patterns. The first attempt felt like writing on gravel with a piece of stone. The latter felt natural. It was easier to make and validate changes. I do this to gain a greater understanding of why a language’s design patterns.

I see design patterns as a form of social learning, in the sense that I’m learning from another developer’s behavior towards a programming language. To validate a developer or organisation’s pattern, I’d refer to the size of their code and the number of contributors they have. While writing, I mix and match patterns. I pick a pattern based on the requirements of the project. Some of the most frequent ones I’ve used are Flyweight and Adapter structural patterns. With each type, I’ll refer to how the pattern has had an impact with my work and code performance.

Flyweight pattern

I worked on a MMORTS back in 2018. The backend was written with Go. The initial TCP implementation consisted of making a custom object. This object had 3 attributes : the user ID, TCP connection and authentication token. This model did not last and failed after 1000+ connections were made. The server started to slow down. Although a user had 1 active connection, the server was counting 10. The 9 being previous connections. Another issue was that closed connections weren’t properly removed which ultimately caused memory leaks.

To refine this, I implemented a single instance object with a map as an attribute. This map used a user ID string as the key and the connection as the object.

Now each user ID was restricted to one connection, with the previous one being overwritten with a new connection. You can also check out the performance of this upgrade by playing the actual game here :

Adapter pattern

I wrote a database management tool a few years back. This tool was built to simplify interacting with mongodb. After years of existence, it only supports just MongoDB. This is due to the fact that the code was written in an archaic manner. You can find the contraption here :

I’ve implemented this pattern with interfaces on Go. The interface acts as a contract to validate if a struct has all the necessary functions. With this in mind, I’d start a version 2 of db with the following code :

The interface declared will ensure that each struct will have a connect and insert one item function. MongoDB and SQL are two different databases. Each one has it's own methods of authentication and data insertion. These cases can be isolated and implemented within their own struct type.

If I wanted to implement a client I wrote previously I'd adapt it for this library. Hence the name Adapter pattern. This will consist of writing a data type that meets the dbc contract while invoking the functions of the previous client. The package I've listed above fails to perform this. It would be impractical to write and have developers use a different function name for each database they wanted to query. It is also important to note that having an interface is crucial for this to work.

In conclusion, design patterns aren't a one way street, they also enable your code to be correctly interpreted as well. This may not seem like a big deal, but it improves the quality of your code by increasing its lifespan. I've heard countless people in the past say terrible things about certain products exported from China. The products are appealing to usher a purchase but they have a short lifespan. Don't let your code be that product from China. I've written chaotic code for numerous projects on my Github. I did this to cut corners to release my concept faster. Yet, there are people capable of fixing bugs found in my flying ramen noodles monster. This post is not any form documentation, but rather something to reflect on.

Additional resources:

Buy Everyday Golang