zoukankan      html  css  js  c++  java
  • 写出优美的代码

    (本文思想基本来自于经典著作《重构》一书)

    上一篇 http://www.cnblogs.com/ceys/archive/2012/03/09/2388356.html

    上篇《希望这不是年轻人的蠢话》惹了很多争议,有人踩,有人顶。我说话确实做不到四平八稳,更说不出什么心灵鸡汤。如果要比喻可能有点像辣椒酱,不管你喜不喜欢,这玩意可以帮助下饭。不多说,继续把代码风格这系列写完。

    三、简化条件表达式和函数调用

    条件语句要尽可能简单,分别用独立函数表示它们。

    如果条件表达式根据对象类型不同而选择不同的行为,将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数。

    将查询和修改函数分离。在多线程系统中,赋值前通常需要完成检查。这个时候仍把查询修改分开,在建立一个新函数,调用各自独立的查询和修改函数,并声明为synchronized。如果未被声明为synchronized,应该将她们的可见范围限制在包级别或private级别。

    尽量用函数,对象取代参数。比如常见的数值范围参数,可以用对象取代:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class DateRange {
        DateRange(Date start, Date end) {
            _start = start;
            _end = end;
        }
        Date getStart() {
            return _start;
        }
        Date getEnd() {
            return _end;
        }
        private final Date _start;
        private final Date _end;
    }

    如果在创建对象时不仅仅是做简单的建构动作,将构造函数替换为工厂函数。这样在派生子类的过程中,可以以工厂函数取代类型码。例如:

    1
    2
    3
    4
    5
    6
    7
    static Employee create(String name) {
        try{
            return (Employee) Class.forName(name).newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException("Unable to instantiate" + name);
        }
    }

    当调用者可以预先检查,不要用异常,而是做条件判断。

    四、处理概况关系

    当两个子类有相同的字段,或是有产生完全相同结果的函数,或是本体几乎一致的构造函数,将它们移至超类。

    当若干客户使用类接口中的同一子集,或者两个类的接口有部分相同,将相同的子集提炼到一个独立接口中。类之间彼此互用的方式有若干种:用到某类的所有责任区;只是用类责任区中的一个特定子集;需要与所有协助处理某些特定请求的类合作。对后两种情况,将真正用到的这部分责任分离通常很有意义。在java中可以利用接口实现上述需求。例如,TimeSheet类表示员工为客户工作的时间表,从中可以计算客户应该支付的费用,为了计算费用,TimeSheet需要知道员工级别即是否有特殊技能:

    1
    2
    3
    4
    5
    6
    double charge(Employee emp, int days) {
        int base - emp.getRate() * days
        if (emp.hasSpecialSkill())
            return base * 1.05;
        else return base;
    }

    我们可以针对员工技能级别定义一个接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    interface Billable {
        public int getRate():
        public boolean hasSpecialSkill();
    }
     
    class Employee implements Billable ...
     
    double charge(Billable emp, int days) {
        int base = emp.getRate() * days;
        if (emp.hasSpecialSkill())
            return base * 1.05;
        else return base;
    }

    如有一些子类,其中相应的某些函数以相同顺序执行类似的操作,将这些操作分别放进独立函数中,并保持他们都有相同的签名,于是原函数就变得相同了。然后将原函数上移至超类。

    如何写出优美的代码(四)

    (本文思想基本来自于经典著作《重构》一书)

    上一篇 http://www.cnblogs.com/ceys/archive/2012/03/09/2388356.html

    上篇《希望这不是年轻人的蠢话》惹了很多争议,有人踩,有人顶。我说话确实做不到四平八稳,更说不出什么心灵鸡汤。如果要比喻可能有点像辣椒酱,不管你喜不喜欢,这玩意可以帮助下饭。不多说,继续把代码风格这系列写完。

    三、简化条件表达式和函数调用

    条件语句要尽可能简单,分别用独立函数表示它们。

    如果条件表达式根据对象类型不同而选择不同的行为,将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数。

    将查询和修改函数分离。在多线程系统中,赋值前通常需要完成检查。这个时候仍把查询修改分开,在建立一个新函数,调用各自独立的查询和修改函数,并声明为synchronized。如果未被声明为synchronized,应该将她们的可见范围限制在包级别或private级别。

    尽量用函数,对象取代参数。比如常见的数值范围参数,可以用对象取代:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class DateRange {
        DateRange(Date start, Date end) {
            _start = start;
            _end = end;
        }
        Date getStart() {
            return _start;
        }
        Date getEnd() {
            return _end;
        }
        private final Date _start;
        private final Date _end;
    }

    如果在创建对象时不仅仅是做简单的建构动作,将构造函数替换为工厂函数。这样在派生子类的过程中,可以以工厂函数取代类型码。例如:

    1
    2
    3
    4
    5
    6
    7
    static Employee create(String name) {
        try{
            return (Employee) Class.forName(name).newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException("Unable to instantiate" + name);
        }
    }

    当调用者可以预先检查,不要用异常,而是做条件判断。

    四、处理概况关系

    当两个子类有相同的字段,或是有产生完全相同结果的函数,或是本体几乎一致的构造函数,将它们移至超类。

    当若干客户使用类接口中的同一子集,或者两个类的接口有部分相同,将相同的子集提炼到一个独立接口中。类之间彼此互用的方式有若干种:用到某类的所有责任区;只是用类责任区中的一个特定子集;需要与所有协助处理某些特定请求的类合作。对后两种情况,将真正用到的这部分责任分离通常很有意义。在java中可以利用接口实现上述需求。例如,TimeSheet类表示员工为客户工作的时间表,从中可以计算客户应该支付的费用,为了计算费用,TimeSheet需要知道员工级别即是否有特殊技能:

    1
    2
    3
    4
    5
    6
    double charge(Employee emp, int days) {
        int base - emp.getRate() * days
        if (emp.hasSpecialSkill())
            return base * 1.05;
        else return base;
    }

    我们可以针对员工技能级别定义一个接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    interface Billable {
        public int getRate():
        public boolean hasSpecialSkill();
    }
     
    class Employee implements Billable ...
     
    double charge(Billable emp, int days) {
        int base = emp.getRate() * days;
        if (emp.hasSpecialSkill())
            return base * 1.05;
        else return base;
    }

    如有一些子类,其中相应的某些函数以相同顺序执行类似的操作,将这些操作分别放进独立函数中,并保持他们都有相同的签名,于是原函数就变得相同了。然后将原函数上移至超类。

    当前标签: 代码风格

     
    如何写出优美的代码(二) 大俗人 2012-03-09 22:19 阅读:1835 评论:0  
     
    如何写出优美的代码(一) 大俗人 2012-03-05 01:22 阅读:2829 评论:8  

    当前标签: 算法

     
    数据库-并发控制 大俗人 2012-03-16 18:07 阅读:1464 评论:2  
     
    如何写出优美的代码(三) 大俗人 2012-03-14 01:14 阅读:1924 评论:4  
     
    数据库-查询优化器 大俗人 2012-02-15 10:45 阅读:60 评论:0  
     
    数据库-表达式计算 大俗人 2012-02-14 17:31 阅读:53 评论:0  
     
    数据库-连接运算 大俗人 2012-02-10 16:50 阅读:1071 评论:0  

     

     

  • 相关阅读:
    内存问题定位与解决
    CPU问题定位与解决
    数据库优化案例——————某市中心医院HIS系统
    系统隐形杀手——阻塞与等待
    SQL Server常见问题介绍及快速解决建议
    CVTE实习感想--2014.10秋招
    Spring AOP的理解
    一些Java面试问题
    举几个大数据的例子
    Java中乐观锁与悲观锁的实现
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2477615.html
Copyright © 2011-2022 走看看