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.
Here are some rules for a better design.
- Modular: a system is an aggregation of multiple sub-systems. The sub-systems collaborate and communicate using messages and rules.
- 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.
- Holistic Thinking. A good system must define terminology and principles for definition of components and relations between them.
- Conceptual Brilliance. A system architecture may be elegant, but architects must 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 projects. These help you to have 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 composite 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 separator lines and 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 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.
method main(Logic: situation):
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. However do not apply automatic formatting and then add some other changes to the code and then check-in or push. Later, will make code review impossible.