A question with no simple answer, because the notion of good code varies from coder to coder, from team to team and from project to project. Also, there are many criteria for determining the quality of written code. Let me give you a few examples: actual code size, number of units, time needed to write, memory usage, request handling, practices employed etc.
As you can see, there are a myriad of criteria which play a significant role when considering the "overall goodness" of your written code and furthermore, if attempting to evaluate your code using these guidelines, you will quickly find out that the result is relative to each project, at best.
This was a concept that stuck in my head for some time now, mainly because I'm always interested in improving the quality of the projects I'm involved in, by writing improved code. I'm talking about both professional and personal projects.
First, let's consider the fact that in order to classify the code written, we need to have a solid basis for evaluating a task relative to the project it belongs to, because the same task can have varying difficulty in different projects. And here is the core of the issue. Normally, adding the feature (i.e. doing a task) to an existing project, should have the same difficulty regardless of the overall project complexity. You may not fully agree with this concept, but if you disregard project-specific data structures and keep in mind only the flow or functionality, then it might make more sense.
This is precisely why I tend to believe that "code goodness" can be determined by the amount of changes (to the already existing code) needed in order to complete the task. So, we cannot determine how well some code was written, until we see how flexible it is, in the sense that it must be flexible enough so we can add new things, without altering it. Now, that might sound weird, counter-intuitive, but it makes sense if you think about it.
Here's an example. Let's say we are implementing an application for managing songs (add / edit / delete). It might be simple enough, but there are many ways to go about it, so let me give you a quick example: We have an object that manages songs by building queries based on input data and then executes them to update the records. Now, we need to extend the functionality a bit, and add the possibility to manage videos in the same way. You can see the fact that although the data structure might have changed, the functionality itself did not. So, if we were to change the way songs are managed, just so we can manage videos as well, then that would be a sign that the code we have previously written, was not flexible enough. In more technical terms, the model was tightly coupled with the business logic. Therefore, the controller does not allow new functionality to be added without altering its previous code. We could also clone the functionality for the video manager, but it still would be far from perfect since we have two objects that exhibit the same behavior.
On the other hand, if our controller was written in such a way that it can manage varying data structures, then we know it is good. A more flexible example would be to separate the database operations manager from the input parser. The way to do that would be to have some object for gathering the data, then another for building queries based on the current data structure, and finally, one to manager the database connection and execute a query.
Now that's a lot better! We can add a whole lot of new data types, like books for instance and we can focus solely on the code needed to handle books, not songs or videos.
In conclusion, we can only determine how good code a segment of code is, after we have written it, and used it, by determining the amount of code we need to change in order to implement new requirements. Of course, this means a smaller value corresponds to a higher rating.
Also, it is generally a good idea, when designing the architecture of a project, to take into account things that resemble the requirements, but haven't been explicitly requested, this way you can help improve the flexibility of your code dramatically, and in time, it will become like a reflex. The direct result of this habit is that the code you write will be more abstracted, and therefore handle additions without too much (and later hopefully none) code changes.
Niciun comentariu:
Trimiteți un comentariu