Information hiding principle

Information hiding is a principle of object-oriented design, which is a generalization of a higher dimension of encapsulation and modularization. The principle of information hiding is embodied in the entire access restriction design of Java. The various access modifiers: public, Protect, and private. When designing a class, we have to decide what is exposed and what is hidden.

As an example, the following code represents a Person class with an incremented ID.

public class Person {

int id;

private static int G_MAX_ID = 0;

public Person() {

this.id = ++G_MAX_ID;

}

}

What’s wrong with the class design above? It violates the principle of information hiding and directly exposes the way ids are assigned, which causes a lot of problems for later maintenance: what happens when you want to limit the range of ids? What happens when you use ++G_MAX_ID to assign ids in all your code and suddenly need to change the ID assignment algorithm? Do I need to change all the places where ++G_MAX_ID appears? A better design would be to hide the ID assignment algorithm.

public class Person {

int id;

private static int G_MAX_ID = 0;

public Person() {

this.id = NewId();

}

private int NewId() {

return ++G_MAX_ID;

}

}

At first glance, it just writes ++G_MAX_ID to a method, but it hides the ID assignment algorithm so that the caller doesn’t need to care about the implementation, and it controls changes so that whatever the ID assignment algorithm changes doesn’t affect the rest of the code. The more information the caller knows, the greater the impact, and information hiding can reduce complexity and control the scope of change.

The above example is just a simple application of information hiding. Here are some other examples:

Why not use magic values (i.e., undefined constants)? : This is a clear violation of the principle of information hiding. When you write literals directly into the code, you expose the information directly, and when you need to modify them later, once you change the literal in some place, the bug will appear.

Circular dependencies (where A calls B and B calls A) : Circular dependencies between classes or methods break information hiding. One immediate effect is that both A and B need to be ready to test at the same time, without mocking either side.

Use global variables: Needless to say, information is exposed when everyone has access to you, and global variables are not used at all.

Consider the performance penalty: Sometimes we break the information hiding principle and globalize some variables for performance reasons, which is not worth the performance gain but the maintenance cost.

Finally, to summarize the benefits of information hiding:

Hiding information hides complexity and reduces the programming burden.

Hiding information hides the underlying changes in order to control the changes locally.

Some less common programming tricks

The choice between functions and procedures

Let’s first look at the difference between functions and procedures:

Function: a method that returns a value

Procedure: Method that does not return a value

Usually, we do not distinguish between functions and procedures in programming. When to use functions and when to use procedures, we do not have too much consideration. A rule of choice is to use functions when the purpose of your method is to return a value that matches the name of your method, and procedures otherwise

For example, I have seen many XXProcessor interface methods are XX process(), strictly speaking, such a name does not comply with the above rules, process is

A name that has no meaning, but has a return value, and is properly named if it has no return value.

Of course, the above rule is for reference only, nothing is absolute, it is case by case, when you do not know whether to use a function or a procedure, you can refer to this rule.

Use Boolean values to comment programs

If you see an if statement that has a lot of conditions, it’s very difficult to understand. For example:

if ( ( elementIndex 0 ) || ( MAX_ELEMENTS elementIndex ) || elementIndex == lastElementIndex) {

do….

}

But if you annotate an if statement with the name of a Boolean value, it makes sense.

finished = ( ( elementIndex 0 ) || ( MAX_ELEMENTS elementIndex ) );

repeatedEntry = ( elementIndex == lastElementIndex );

if ( finished || repeatedEntry ) {

.

}

conclusion

How to write high quality code is a big topic, here is just beginning, many principles of object-oriented design to be able to actually writing the code to provide guidance to us, writing code, I will always remember and apply, not perfunctory, professional software engineers will need to be able to write good code.