如何写出好的 Java程序 —— 浅谈 API 设计

如何写出好的 Java程序 —— 浅谈 API 设计

很多童鞋觉得写 Java 很简单,只要能写出功能来,效果能实现就好。还有一些培训机构,专门教人写各种“炫酷特效”,以此让许多人觉得这些培训很“牛逼”。然而事实上,能写 Java 和写好 Java 这中间还有很遥远的距离。成为专业,注定在 Java 路途上需要一步步扎实的修炼,没有捷径。

实现一个类似于“交通灯”的效果,让三个不同颜色(红、绿、黄)的圆点每隔 2 秒循环切换。

版本一

有的童鞋说,这个实现还不简单嘛?直接用几个定时器一下切换不就好了:

while (true) {
            System.out.println("黄灯,等待。。。"+new Date());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("红灯,停止。。。"+new Date());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("绿灯,通行。。。"+new Date());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

没错,就这个功能本身,这样实现就 OK 了。但是这样实现有什么问题呢?
首先是过程耦合,状态切换是黄灯->红灯->绿灯 循环,在上面的设计里,实际上操作顺序是耦合在一起的,要先 ‘黄灯’,然后等待 2000 毫秒再 ‘红灯’,然后再等待 2000 毫秒在 ‘绿灯’,这中间的顺序一旦有调整,需求有变化,代码都需要修改。
如果需求不是三盏灯,而是五盏灯、十盏灯呢。
所以我们说,版本一方法虽然直接,但因为抽象程度很低(几乎没有提供任何抽象 API),它的扩展性很不好。如果只能写这样的代码,是不能说就写好了 Java 的。

版本二

将状态[‘黄灯’,’红灯’,’绿灯 ‘]抽象出来:

String[] lights = { "黄灯", "红灯", "绿灯" };
        int i = 0;
        while (true) {
            System.out.println(lights[i]+"。。。" + new Date());
            try {
                Thread.sleep(2000);
                i++;
                if(i == 3){
                    i = 0;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

这一版本比前一版本要好很多,但是它也有问题,最大的问题就是封装性很差,它把 lights 和 i都暴露出来了,而且以全局变量的形式,这么做很不好,需要优化。

版本三

版本三是中规中矩的一版,也是一般我们在工作中比较常用的思路。应该将暴露出来的 API 暴露出来(本例中的 lights )。将不应该暴露出来的数据或状态隐藏(本例中的 i)。
有许多童鞋觉得说写出这一版本来已经很不错的。的确,应该也还不错,但这一版的抽象程度其实也不是很高,或者说,如果考虑适用性,这版已经很好了,但是如果考虑可复用性的话,这版依然有改进空间。

版本四

public static final int YELLOW=1;
    public static final int RED=2;
    public static final int GREEN=3;
    static int lightControl=3;

    public static void main(String[] args) {
        while (true) {
            changeLights();
        }
    }

    private static void changeLights() {
            try
            {
                Thread.sleep(2000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }                   
        change();
    }

    public static void change(){
        if(lightControl == 1){
            lightControl = 2;
        }else if(lightControl == 2){
            lightControl = 3;
        }else if(lightControl == 3){
            lightControl = 1;
        }
        print();        
    }

    private static void print() {
        if(lightControl == 1){
            System.out.println("现在是黄灯!"+new Date());
        }else if(lightControl == 2){
            System.out.println("现在是红灯!"+new Date());
        }else if(lightControl == 3){
            System.out.println("现在是绿灯!"+new Date());
        }       
    }

这一版用的是过程抽象的思路.

好了,上面我们有了四个版本,那么是否考虑了这些版本就足够了呢?
并不是。因为需求是会变更的。假设现在需求变化了:
需求变更:让 黄灯、红灯、绿灯 状态的持续时长不相等,分别改成 1秒、2秒、3秒。
如何写出好的 Java程序 —— 浅谈 API 设计_第1张图片
如何写出好的 Java程序 —— 浅谈 API 设计_第2张图片
那么,我们发现 ——
除了版本一之外,版本二、三、四全都跪了……

那是否意味着我们要回归到版本一呢?
当然并不是。
我们有版本五,版本五需开通vip可获取源码学习。

注意:需要本文源代码可加QQ490647751 回复关键字‘开通vip-如何写出好的 Java程序 —— 浅谈 API 设计’。

设计是把双刃剑,繁简需要权衡,尺度需要把握。
写代码简单,程序设计不易,需要走心。

你可能感兴趣的:(java之路)