Most languages are capable of self documented source code, using comments and annotations. It is important to know, some annotations can be parsed by a special program and converted in HTML pages.
To achieve greater software quality, the source code must have specific attributes. There are many attributes to consider. Here we are talking about source code.
|1||comprehensive||readable, modular, consistent|
|2||maintainable||refactoring friendly, easy to debug|
|3||documented||use comments and annotations|
Note: Source code quality do not imply performance or reliability, nor efficiency or business value. Indeed these are attributes to consider but they are related to final product not to source code.
When you design an application or a system you should describe some of your design principles. Here are some good principles for a good design. If you do not have time to make your own principles use these generic principles:
- Modular: a system is an aggregation of multiple sub-systems. The sub-systems collaborate and communicate using messages and rules. If your system is monolithic it will be harder to build and maintain.
- KISS (Keep it Simple Stupid): just design the features that you need. Architectures that are more complex than necessary will result in sub-optimal systems. Breaking this rule is called over-engineering.
- Holistic Thinking: A good system must define terminology and principles for definition of components and relations between them. A metaphor could help for building a theory using existing therms and analogy from real life.
- Conceptual Brilliance: A system architecture must be elegant, but architects should not be blinded by the beauty of creation, and always review features with a pragmatic and detail-oriented eye.
We describe these rules that you can use in your future project. These help you to establish built-in quality. Some of these principles are using common sense and look obvious but some may surprise you even if you are experienced developer.
- If the code is difficult to read it is wrong;
- Never release or deploy untested software;
- Store testing code and application code together;
- Save and version control your configuration files;
- Split complex problems into simple parts;
- When you are not sure, create parameters;
- Start your source files with a short comment;
- Do not stay astray from left side of the screen;
- Short lines of code are better than long lines;
- Group global variables and constants in records or structures;
- Create a local scope if possible. Local is better then the global;
- It is better to define global constants than to use magic literals;
- Put a separator line or comments between regions or subroutines;
- Do not repeat yourself. Reusable code should be organized in subroutines;
- Create subroutines only if you need to. Subroutine call can be expensive;
- Avoid unnecessary data movement by using references;
- Favor explicit declarations against type inference or gradual types;
- Favor explicit loop and stacks over recursive functions;
- Favor different identifiers over subroutine overloading;
- Do not be afraid of long identifier names for subroutines and variables;
- Do not be afraid of long processes: create subroutines only when necessary;
- Do not be afraid do to refectory whenever you think is necessary;
- Do not create functionality that is not required: let the future to care about itself;
- Favor declarative programming over imperative programming;
- Favor imperative programming over functional programming;
- Favor functional programming over object oriented programming;
- Avoid deep class trees. They are hard to understand and debug;
- Avoid classes with features and favor mix-in classes or traits instead;
- Favor precondition checking over exception handling;
- Favor efficient algorithms over parallel computing;
The name of identifiers in a language can support several characters. In most languages identifier name usually starts with lowercase letters (a..z) or capital letters (A..Z) followed by one or more characters or numbers. No special characters or spaces are permitted in the name except underscore (“_”).
A variable name can start or terminate with underscore or can contain underscores. The underscore is equivalent to space. So the identifiers that have space in a JSON or in a database can be mapped to internal variables that use an underscore instead of a space as identifier.
These are invalid identifiers
1a, 31_, c-3
These are valid identifiers
a, b, c, i, k, m, n, p, q, t
Variables usually have a meaning or a purpose therefore variable must have a proper name. Variables can’t use as names the language reserved keywords. Therefore we advise for variables to use a prefix all the time.
“v_” is a good prefix for variables; “p_” is a good prefix for parameters;
Using prefix is good but sometimes this is not good enough. When this is the case, you can give creative names to variables to make your code even more readable.
Example: In next EVE example we name a logical variable: URGENT and use “=” operator. By not using a prefix for logical variable we make a very readable program.
when situation = URGENT do
print("this is an emergency");
print("this is a normal situation");
Avoid it! It can cause a disaster when your code is versioned. Automatic formatting is available for some languages and is a program that modify your source code to look nice. I strongly advice against it. You can be fired if you do not listen this advice.
Doing automating formatting for totally new code can be beneficial for learning how your code should look like. Never apply automatic formatting then add some other changes and then check-in or push. Later, code review will be impossible. I advice you to do only manual code formatting.
I hope you enjoy this reading. Post comments on forum if you do!