美文网首页
几个写出优雅代码的建议

几个写出优雅代码的建议

作者: JokerLinly | 来源:发表于2020-04-07 23:51 被阅读0次

    干程序猿这行快有四个年头了,若是算上大学时代在课程上敲出的那一行行稚嫩的代码,那至今已有八个年头了吧。这八个年头里,大学时代可以说是懵懵懂懂的。仍旧记得课堂上温泉思老师说过,写代码这档子事,是苦学多年未果,而后突然有一天就顿悟了。从此写代码如同行云流水一般畅快。可谓是我手敲我心。

    这个过程里面,无非就是两件事,抄别人的代码,抄着抄着再融化成自己的东西。如同融入骨血一般,从今往后,这项技能除了是你安身立命的存在,可能也是你此生唯一能做好的事情。当然这些要你将来出来工作之后才能体悟到的。我很庆幸刚出来工作实习的时候,遇到一个好老大,做项目的时候会检查我的代码并指出其中的弊病,这一点可能是学校里的师兄师姐无法给你指导的,因为他们的代码也还很稚嫩,也需要有经验的人去建议怎么做才能做好。而课堂上,老师可能只求你能理解,你写的代码能跑通,但能不能放进正式的生产环境,可能就未必能兼顾得来。

    说了这么多,其实我今天只是想写一点写代码的优化建议和规范。未来工作中,很多矛盾其实都是来源于糟糕的代码,由于代码太恶心,随便一个改动都是一堆的工作量,于是乎,跟谁都想撕逼。其实程序员这行的门槛其实是很低的,我遇见过很多人可能在培训班上几个月就出来工作了,几年下来,比我年轻工作经验比我足的人比比皆是。于是乎大部分人写的代码是相当糟糕的,写这些糟糕代码的人还要频繁的跳槽,不留下文档,嵌套一堆 if else,一行代码能解决的事情,非要写上十行。还有纯手写 SQL 这种拥有十几年历史的代码。

    对于个人来说,技术很重要,但是对于工作来说,编码的习惯比技术更加重要。算法、数据结构、设计模式等等如果说是修炼内功心法,那编码习惯就是你行走江湖的口碑了。工作中,会因为你的编码习惯不好,写的代码质量差,代码冗余重复多,很多无关的代码和业务代码搅在一起,导致了你疲于奔命应付各种问题。

    我明明想成为黑客电影里那酷到不行的极客,却天天在收拾别人的烂摊子。于是乎,梦想渐行渐远渐行渐远,直到生活磨圆了我的棱角。

    干掉你的 if else

    image.png

    图片是我从网上找的,if else 这个是所有编码规范中最常见的了,可我却不晓得为什么,明明常见得要紧,却还是有人能写出嵌套了一堆 if else 的代码。

    常见的处理方法,可以 return 出去的,咱先 return 出去。

    糟糕的做法

    public void today() {
        if (isWeekend()) {
            if (isFee()) {
                System.out.println("study Android");
            } else {
                System.out.println("play a game");
            }
        } else {
            System.out.println("go to work");
        }
    }
    

    好的做法

    public void today() {
    
        // 提前过滤掉`特殊情况`
        if (!isWeekend()) {
            System.out.println("go to work");
            return; // 提前return
        }
    
        //提前过滤掉`特殊情况`
        if (isFee()) {
            System.out.println("study Java");
            return; // 提前return
        }
    
        // 更关注于 `核心业务`代码实现。
        System.out.println("play a game");
    }
    
    

    当然如果是更为复杂的业务代码,那复杂度可想而知。那么,如何改善呢?我们可以借助设计模式中的策略模式或者是工厂模式,至于这些模式是怎样的,有兴趣的人可以自己先去思考,或者等我写下一篇稿的时候再给你们讲讲。但凡一个方法的代码超过 100 行,我们就要开始思考,能不能再减少点代码量,亦或者能不能任谁来都能看得懂你的代码在做什么。语义化的代码,编写出非开发人员都能看懂的代码,才是我们追求的目标。

    语义化的代码

    既然提到语义化的代码,我们就提一下。怎么说我们也算是知识分子,设置变量的时候能用 user 就不要用 person,明明返回的是复数的 products 就不要返回 sp 这么难以理解的意思。与其花尽心思给你的代码写注释,还不如对方法或变量写一个描述性的名称。

    不好的做法

    if (age > 0 && age < 18){
        System.out.println("小孩子");
    }
    
    if (number.length() == 11){
        System.out.println("符合手机号");
    }
    
    

    建议的做法

    
    private static boolean isChild(int age) {
        return age > 0 && age < 18;
    }
    
    private static boolean isPhoneNumber(String number) {
        return number.length() == 11;
    }
    
    if (isChild(age)){
        System.out.println("小孩子");
    }
    
    if (isPhoneNumber(number)){
        System.out.println("符合手机号");
    }
    
    

    单一原则

    一个类和一个方法应该只有一个职责。迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解。例如:

    public class Student {
    
        private String name;
    
        public Student(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    public static void main(String[] args) {
    
        Student student = new Student("张三");
    
        // 注意看这里,
        // 这里获取 student的name属性,在根据name属性进行判断
        if (StringUtils.isNotBlank(student.getName()) && student.getName().equals("张三")) {
            System.out.println("我的好朋友是 " + student.getName());
        }
    }
    
    

    建议的做法

     
     public class Student {
    
        ... 省略name代码
    
        // 新增一个 判断是否是我的好朋友方法
        public boolean isGoodFriend(){
            return StringUtils.isNotBlank(this.name) && this.name.equals("张三");
        }
    }
    
    public static void main(String[] args) {
    
        Student student = new Student("张三");
    
        // 根据迪米特法则,把判断逻辑,抽取到 Student 内部,暴露出方法(isGoodFriend)
        if (student.isGoodFriend()){
            System.out.println("我的好朋友是 " + student.getName());
        }
    }
    
    

    不要滥用你用惯了的方法

    我见过最傻逼的代码,就是用 switch case “认认真真” 地把一个几行代码可以搞定的事情,写了十几行。

    public String getResult(int number) {
            switch (number) {
                case 0:
                    type = "零";
                    break;
                case 1:
                    type = "一";
                    break;
                case 2:
                    type = "二";
                    break;
                case 3:
                    type = "三";
                    break;
                case 4:
                    type = "四";
                    break;
                    ......
            }
            return type;
    }
    
    

    正常来讲应该是这样:

    public String getNumberLowercase(int number) {
        int data[] = {"零", "一", "二", "三" ....};
        return data[number];
    }
    

    在我的工作生涯中,还真的遇到过两三个人干过类似这样的事情。想象一下如果这上面是一堆业务代码,那该有多糟心。绝大部分写出类似这种「没有常识」的代码来的人,都是因为优质的代码看得太少,工具书和文档读得太少。这种无知并不能得到谅解,人们会因此判定你是个极其不专业的人。

    善于利用好的工具

    Java 有着极其丰富的类库,这是很多编程语言都望尘莫及的,这也是为什么 Java 能常年位列最受欢迎的十大语言的前三名。写代码的时候更多的去使用社区接受的标准的工具。最好使用内置的功能和社区软件包,而不是其他第三方软件包和工具。因为将来与你的应用程序一起工作的开发人员都需要学习新的工具。另外,使用第三方软件包或工具的话,如果遇到困难,从社区获得帮助的机会会大大降低。不要让任何人为此付出代价!

    写在最后

    如何更好的编写代码,古今中外能寻得到的书籍资料远比我上面罗列出来的要多的多。我举的例子更多的是想强调写优雅的代码这样的追求是猿的基本素养。生活中很多事情,也应该尽可能地去追求完美,得过且过,糊弄了事最终吃亏的还是自己。

    我曾经在博客上翻译过一篇 《Laravel 的 十八个最佳实践》,在博客销声匿迹一年多以后,仍旧只有这篇文章还在被别人收藏和点赞。这也是我写这篇文章的原因,我们需要最佳实践。我们需要别人来告诉我们,什么是好的代码,什么是坏的代码,为什么。我希望每个程序员都能对自己的代码负责,虚心接受别人的抱怨、建议亦或者借鉴别人写的好的地方。

    写代码的时候能多想一想,多为看代码的人想一想,多为用这个产品的人想一想,多为辛苦运营这个产品的人想一想。你一定要多想一想。

    Stay Hungry. Stay Foolish.

    以上内容参考了以下资料:

    相关文章

      网友评论

          本文标题:几个写出优雅代码的建议

          本文链接:https://www.haomeiwen.com/subject/irnmuhtx.html