Lately I participated in a couple of interviews. During those interviews, the interviewers tried to classify me as either a medium level developer or a senior developer. That's when it occurred to me to think about the progress that I made in the past 6 years or so since I have been professionally developing commercial software.
Honestly, over the course of these years I have learned to look from the perspective of other developers when writing code. Equally as important, I learned that when I have a complex problem to solve, my job isn't actually to solve that problem directly. But rather my job is to find out ways to make that complex problem more simple and then to come up with a series of simple functionalities which add up to a simple solution. This has a lot of consequence on the way I develop software.
For example, if you need to develop a big application, you can think of that application as a series of smaller applications that need to collaborate together to do what the initial big application is supposed to do. You can think of this more expressively as me knowing how and where to cut a big application to get smaller applications which are more easy to manage. This is actually a general idea that is applicable almost anywhere. If you are designing a website and you are applying this principle, you will probably end up with some microservices. If you are developing a desktop application, you will end up with multiple modules for that application. One important aspect here is how to do these cuts so that they remain stable when the client changes the requirements or wants to implement some new functionality. Otherwise you will need to spend extra effort to do these cuts again and to move functionalities from the old modules into the new modules resulted from the new cuts. Ideally you should only change things inside these cut parts of the application or website and not recreate or change the cuts themselves. Why is it helpful to have these cuts? Because you will isolate changes in the application. If you need to change something in one of the cuts, the changes won't propagate further into other cuts. And these cuts can be developed in parallel by separate developers. They can be in a specific direction such as horizontal, separating the layers in the application. Or they can be vertical to separate the modules in the application. And they can be also mixed. So you can have separate modules in your application and each module will have its own separate layers.
Another important thing that I became better at is assigning responsibilities to various components which can be classes too. A lot of people say that one of the hardest things in programming is naming things. And they are right. But why is it hard? Because we don't really know clearly what a class or component should do. This happens because we haven't assigned a clear responsibility to that class that we can understand. Naming a class actually means naming the responsibility assigned to that class or component. A well designed class or component makes logical sense to any developer looking at it. Because it has a meaning and sense to him, he can remember that component much more easier. If all the components in a code base are like this, even if the code is huge, it makes it easier to understand and remember.
I also became better at figuring out these responsibilities from the specifications and requirements of the client. This is because I can figure out clearer, the necessary steps that he computer needs to execute to achieve what the client wants. What this actually means is that I can create a workflow diagram directly in my head which contains all the required decisions and processes. I don't actually need a whiteboard anymore to sketch my ideas on it because I can do this directly inside my head. Knowing this diagram I can start to group logically elements of the diagram into specific groups which have a precise role, better said responsibility, which then will be coded into an actual class.
Furthermore, I became better at establishing better interactions between the components that I create. Now I can classify components into low level ones and high level ones. The low level ones work and manipulate the data directly. Data in this case can mean a lot of things but it mostly refers to entities from the domain of the application. The higher level components just orchestrate and consume the lower level components to perform more complex operations that each of the low level components. An hierarchy of components is actually established here. Between the highest level components and the lowest level ones there can be any layers of intermediate components. This hierarchy should be reinforced. If a high level component handles the data directly then it does something wrong. It should delegate that responsibility to a lower level component which actually enforces the single responsibility principle in a way.
For the things mentioned above, there is no secret or hack to achieve them. No amount of reading and studying will improve the aspects mentioned above. There aren't an shortcuts because it's a mindset, a way of thinking. You learn a new mindset by practicing it.
In the end all that I said above boils down to one thing. This is to be able to split something big and complicated into smaller and more simple bits and then combine those bits together to achieve what that big thing is supposed to do. So this is actually more of a composition thing. I also used to do 3d models and 3d art in my free time. One of the key principles of 3d art was being able to figure out some simple things that you need to combine together to achieve something that looks complex and like a whole thing. Well, it's the same thing with software engineering too. All the software is composed out of many bits and the tricky part is to figure them out and then figure out how to combine them. So from this perspective you can consider software engineering as an artistic process too, applications as a piece of art and us being the artists :) .
Honestly, over the course of these years I have learned to look from the perspective of other developers when writing code. Equally as important, I learned that when I have a complex problem to solve, my job isn't actually to solve that problem directly. But rather my job is to find out ways to make that complex problem more simple and then to come up with a series of simple functionalities which add up to a simple solution. This has a lot of consequence on the way I develop software.
For example, if you need to develop a big application, you can think of that application as a series of smaller applications that need to collaborate together to do what the initial big application is supposed to do. You can think of this more expressively as me knowing how and where to cut a big application to get smaller applications which are more easy to manage. This is actually a general idea that is applicable almost anywhere. If you are designing a website and you are applying this principle, you will probably end up with some microservices. If you are developing a desktop application, you will end up with multiple modules for that application. One important aspect here is how to do these cuts so that they remain stable when the client changes the requirements or wants to implement some new functionality. Otherwise you will need to spend extra effort to do these cuts again and to move functionalities from the old modules into the new modules resulted from the new cuts. Ideally you should only change things inside these cut parts of the application or website and not recreate or change the cuts themselves. Why is it helpful to have these cuts? Because you will isolate changes in the application. If you need to change something in one of the cuts, the changes won't propagate further into other cuts. And these cuts can be developed in parallel by separate developers. They can be in a specific direction such as horizontal, separating the layers in the application. Or they can be vertical to separate the modules in the application. And they can be also mixed. So you can have separate modules in your application and each module will have its own separate layers.
Another important thing that I became better at is assigning responsibilities to various components which can be classes too. A lot of people say that one of the hardest things in programming is naming things. And they are right. But why is it hard? Because we don't really know clearly what a class or component should do. This happens because we haven't assigned a clear responsibility to that class that we can understand. Naming a class actually means naming the responsibility assigned to that class or component. A well designed class or component makes logical sense to any developer looking at it. Because it has a meaning and sense to him, he can remember that component much more easier. If all the components in a code base are like this, even if the code is huge, it makes it easier to understand and remember.
I also became better at figuring out these responsibilities from the specifications and requirements of the client. This is because I can figure out clearer, the necessary steps that he computer needs to execute to achieve what the client wants. What this actually means is that I can create a workflow diagram directly in my head which contains all the required decisions and processes. I don't actually need a whiteboard anymore to sketch my ideas on it because I can do this directly inside my head. Knowing this diagram I can start to group logically elements of the diagram into specific groups which have a precise role, better said responsibility, which then will be coded into an actual class.
Furthermore, I became better at establishing better interactions between the components that I create. Now I can classify components into low level ones and high level ones. The low level ones work and manipulate the data directly. Data in this case can mean a lot of things but it mostly refers to entities from the domain of the application. The higher level components just orchestrate and consume the lower level components to perform more complex operations that each of the low level components. An hierarchy of components is actually established here. Between the highest level components and the lowest level ones there can be any layers of intermediate components. This hierarchy should be reinforced. If a high level component handles the data directly then it does something wrong. It should delegate that responsibility to a lower level component which actually enforces the single responsibility principle in a way.
For the things mentioned above, there is no secret or hack to achieve them. No amount of reading and studying will improve the aspects mentioned above. There aren't an shortcuts because it's a mindset, a way of thinking. You learn a new mindset by practicing it.
In the end all that I said above boils down to one thing. This is to be able to split something big and complicated into smaller and more simple bits and then combine those bits together to achieve what that big thing is supposed to do. So this is actually more of a composition thing. I also used to do 3d models and 3d art in my free time. One of the key principles of 3d art was being able to figure out some simple things that you need to combine together to achieve something that looks complex and like a whole thing. Well, it's the same thing with software engineering too. All the software is composed out of many bits and the tricky part is to figure them out and then figure out how to combine them. So from this perspective you can consider software engineering as an artistic process too, applications as a piece of art and us being the artists :) .
Comments
Post a Comment