函数应该注意些什么?

函数的第一准则是短, 第二准则是比刚才那个函数还要短.

public static String renderPageWithSetupAndTeardowns(
    PageData pageData, boolean isSuite
) throws Exception {
    boolean isTestPage = pageData.hasAttribute("Test");
    if (isTestPage) {
        WikiPage testPage = pageData.getWikiPage();
        StringBuffer newPageContent = new StringBuffer();
        includeSetupPages(testPage, newPageContent, isSuite);
        newPageContent.append(pageData.getContent());
        includeTeardownPages(testPage, newPageContent, isSuite);
        pageData.setContent(newPageContent.toString());
    }
    
    return pageData.getHtml();
}

vs

public static String renderPageWithSetupAndTeardowns(
    PageData pageData, boolean isSuite
) throws Exception {
    boolean isTestPage = pageData.hasAttribute("Test");
    if (isTestPage(pageData)) {
        includeSetupAndTeardownPages(pageData, isSuite);
    }
    
    return pageData.getHtml();
}

只做一件事

这意味这, if, else, while中的代码块应该为一行, 这一行可能是一个函数调用.
这不仅能够让函数变得更小, 由于函数名的存在, 还能增加文档效果.

这也意味着函数不应该支持大的嵌套结构, 函数内部的缩进不应该超过两个.

判断一个函数是否做一件事情的方式是ToParagraph去描述函数

TO RenderPageWithSetupsAndTeardowns, we check to see whether the page is a test page and if so, we include the setups and teardowns. In either case we render the page in HTML.

如果一个函数只包含处于一个层级的一系列步骤的话, 那么他就是干一件事.
毕竟, 函数的存在就是为了将一个概念拆解为下一层级当中的一些列步骤.

减少分支语句

分支语句会让函数变得很大. 尽管无法摆脱, 我们可以保证每一个分支语句是一个更底层的类. 为了做到这一点, 可以使用多态.

public Money calculatePay(Employee e)
throws InvalidEmployeeType {
    switch (e.type) {
        case COMMISSIONED:
            return calculateCommissionedPay(e);
        case HOURLY:
            return calculateHourlyPay(e);
        default:
            throw new InvalidEmployeeType(e.type);
    }
}

这个函数的坏处如下:

  1. 每新增一个对象, 这个函数就会变大.
  2. 它干了不止一件事.
  3. 为非烦了单一职责原则, 因为有不止一个原因去改变这个函数.
  4. 违反了开闭原则, 因为只要有新的类型, 这个函数就必须改变.

解决方案是用一个抽象工厂隐藏这些逻辑.

public abstract class Employee {
    public abstract boolean isPayDay();
    public abstract Money calculatePay();
    public abstract void deliverPay(Money pay);
}
-----------
public interface EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
-----------
public class EmployeeFactoryImpl implements EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
        switch (r.type) {
            case COMMISSIONED:
                return new CommissionedEmployee(r);
            case HOURLY:
                return new HourlyEmployee(r);
            default:
                throw new InvalidEmployeeType(r.type);
        }
    }
}

没有副作用

一个函数应该只做一件由它名字所体现的事情, 不应该有隐藏的逻辑.

命令/查询分离

函数不能即执行命令, 又负责查询.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值