|     java code complete code style   |    

数据的封装

把一组相关的,描述特殊意义的数据封装起来,明确数据关系

C语言和C++里的结构体struct就是指组合起来的一组不同的数据类型。比如,

struct PERSON { // delcare PERSON struct type
    int age;
    long id;
    char name[25];
} family_member; // Define object of PERSON

编程的本质其实就是关于数据和过程的封装。收拢好数据,可以使数据间的关系变得更加清晰。而且可以减少代码量,传递的参数量。

Java这种面向对象的编程语言,使用类来封装数据和过程。没有成员方法,只有成员字段的类,就和C和C++里的结构体很像。

public class Person {
    private int age;
    private long id;
    private char[] name;
    public Person(int a, long i, char[] n) {
        age = a;
        id = i;
        name = n;
    }
}

指针(引用)

指针的本质就是内存中的一个起点,以及对其后特定长度的数据的解释

指针不光只是指向一个地址,还包括数据的长度和解释的方式,这是有指针的积累性(base type)决定的。 数据的本质都是一串01。比如下面的几个例子里指针指向哪怕指向的都是内存中的同一个地址,此字节存储的是16进制0x0A。指针指向的数据就包含在这个地址后面的一连串01流中。

0A 61 62 63 64 65 66 67 68 69 6A ... ...

解释方式:String[10]     >>> abcdefghij
解释方式:双字节整数       >>> 24842
解释方式:四字节浮点数     >>> 4.17595656...
解释方式:四字节整数       >>> 1667391754

Java虽然禁止使用指针,但变量都是基于引用,所以本章的很多最佳实践仍然适用。

在靠近变量声明的地方为该变量赋值

养成习惯,同时声明和赋值变量.

Dog dog = new Dog();

使用变量前先检查

这条不用赘述。

尽量简化对变量的使用

比如在LinkedList的代码里,对节点的操作尽量应该避免出现下面这种多次跳转的情况,

currentNode.next.previous = newnode;

全局变量

两大原则:程序模块化,信息局部化

人的智力有限,管理一个大型程序唯一的办法就是把它拆成几个部分,从而可以在同一时间只考虑某个局部。

全局变量阻碍程序的模块化。如果我们想重用的模块读或写了全局变量,我们就无法简单地把它插到新的程序里。全局变量是这件事变得复杂了。所以我们要坚持信息局部化。

全局变量的缺点

阻碍模块化

这点刚才已经说了

初始化顺序的麻烦

C++中,如果在初始化一个文件中的全局变量的时候使用了在另一个文件中初始化的全局变量,要确保两个变量能按照正确的顺序初始化就变得麻烦了。

所有变量先全部设为局部变量,尽量避免使用全局变量

层次是这样的:

  1. 变量优先设计成子程序(类的成员方法)中的局部变量。
  2. 必要时才升级成private或protected修饰的成员字段。
  3. 最后万不得已才设成全局变量。Java可以设成类的静态字段,用static修饰。

万不得已必须使用全局变量的时候做好保护

尽量使用访问器子程序

尽量用类似get(), set()这样的访问器子程序来访问变量,避免直接操作变量。

为全局变量使用同一的名字

比如g_xxx在名字前面加一个g_前缀。

别忘了给全局变量加互斥锁

并发的场景并不少见。有多个线程访问全局变量的时候,加上互斥锁是最基本的保护手段。比如Java使用synchronized关键字修饰访问公共资源的子程序。或者至少山寨一个checkin(),checkout()这样的子程序,在每次调用和使用完毕全局变量的时候都打个卡。

最好为全局变量列一份清晰的注释

该用全局变量还得用!不要为了不用全局变量,把所有数据放进一个大对象到处传递