码迷,mamicode.com
首页 > 其他好文 > 详细

Clean Code 读书笔记九

时间:2015-07-07 09:32:56      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:code-monster   java   方法   

要点汇总:

一般性问题

方法名称应该准确表达其具体行为
比如:

Date newDate = date.add(5)//加5天?5个月?

最好使用addDaysTo 或increaseByDays 明确方法的行为。

  • 使用多态 代替 switch或if else
    比如:
class RequestHandler {

    public void handleRequest(int action) {
        switch(action) {
            case LOGIN:
                doLogin();
                break;
            case LOGOUT:
                doLogout();
                break;
            case QUERY:
               doQuery();
               break;
        }
    }
}
interface Command {
    public void execute();
}

class LoginCommand implements Command {
    public void execute() {
        // do what doLogin() used to do
    }
}

class RequestHandler {
    private Map<Integer, Command> commandMap; // injected in, or obtained from a factory
    public void handleRequest(int action) {
        Command command = commandMap.get(action);
        command.execute();
    }
}
  • 用命名常量代替魔法数字
    不多说,代码中出现某个数字,如21,你知道什么意思么?
    这样 CommonConstants.AVERAGE_AGE=21,使用更好。

  • 不要再判断中写一堆&& ||的判断
    看看下边那个更易于理解

if (shouldBeDeleted(timer)) 

if (timer.hasExpired() && !timer.isRecurrent())
  • 避免否定性调节:
    肯定性条件比否定性条件更容易理解
    比如下边那一行更易理解呢?
if (buffer.shouldCompact())  
if (!buffer.shouldNotCompact())
  • 方法只做一件事
public void pay() {
    for (Employee e: employees) {
        if (e.isPayday()) {
            Money pay = e.calculatePay();
            e.deliverPay(pay);
        }
    }
}

重构:

public void pay() {
    for (Employee e: employees)
    payIfNecessary(e);
}
private void payIfNecessary(Employee e) {
    if (e.isPayday()) calculateAndDeliverPay(e);
}
private void calculateAndDeliverPay(Employee e) {
    Money pay = e.calculatePay();
    e.deliverPay(pay);
}
  • 让时序耦合的代码更明显
 public class MoogDiver {
    Gradient gradient;
    List < Spline > splines;
    public void dive(String reason) {
        saturateGradient();
        reticulateSplines();
        diveForMoog(reason);
    }...
}

saturateGradient();reticulateSplines(); diveForMoog(reason);
三者的关系并没有很好的突出,更好的重构是:

public class MoogDiver {
    Gradient gradient;
    List < Spline > splines;
    public void dive(String reason) {
        Gradient gradient = saturateGradient();
        List < Spline > splines = reticulateSplines(gradient);
        diveForMoog(splines, reason);
    }...
}
  • 使用枚举代替常量
    不要在用
public static fianl int ....

使用enum代替

  • Don’t Inherit Constants
public class HourlyEmployee extends Employee {
    private int tenthsWorked;
    private double hourlyRate;

    public Money calculatePay() {


        int overTime = tenthsWorked - straightTime;
        return new Money(
        hourlyRate * (tenthsWorked + OVERTIME_RATE * overTime));
    }...
}

TENTHS_PER_WEEK 、OVERTIME_RATE这两个常量来自哪里?

public abstract class Employee implements PayrollConstants {
    public abstract boolean isPayday();
    public abstract Money calculatePay();
    public abstract void deliverPay(Money pay);
}
public interface PayrollConstants {
    public static final int TENTHS_PER_WEEK = 400;
    public static final double OVERTIME_RATE = 1.5;
}

这种通过继承或实现的方式获取常量,是对常量作用域的忽视,怪异的使用。应该用引入静态类的方式在代码中直接使用常量。

import static PayrollConstants.*;

名称与命名

使用描述性名称
名称很重要,一个准确的名称可以大幅度提高代码的可读性。

public int x() {
    int q = 0;
    int z = 0;
    for (int kk = 0; kk < 10; kk++) {
        if (l[z] == 10) {
            q += 10 + (l[z + 1] + l[z + 2]);
            z += 1;
        } else if (l[z] + l[z + 1] == 10) {
            q += 10 + l[z + 2];
            z += 2;
        } else {
            q += l[z] + l[z + 1];
            z += 2;
        }
    }
    return q;
}
public int score() {
    int score = 0;
    int frame = 0;
    for (int frameNumber = 0; frameNumber < 10; frameNumber++) {
        if (isStrike(frame)) {
            score += 10 + nextTwoBallsForStrike(frame);
            frame += 1;
        } else if (isSpare(frame)) {
            score += 10 + nextBallForSpare(frame);
            frame += 2;
        } else {
            score += twoBallsInFrame(frame);
            frame += 2;
        }
    }
    return score;
}

两段代码对比一下即可知道名称的重要。

  • 变量的作用范围越大,越应该重视名称的重要。

  • 不要用名称掩盖了内容。

public ObjectOutputStream getOos() throws IOException {
    if (m_oos == null) {
        m_oos = new ObjectOutputStream(m_socket.getOutputStream());
    }
    return m_oos;
}

更准确的名称应该是: createOrReturnOos

测试

  • 使用测试覆盖工具

  • 测试边境条件
    很多问题都出在边界上,如数组越界等等。注意边境!

版权声明:本文为博主原创文章,未经博主允许不得转载。

Clean Code 读书笔记九

标签:code-monster   java   方法   

原文地址:http://blog.csdn.net/lemon89/article/details/46780247

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!