1、Extract Method:提炼方法
将有些代码单独提取出来放入到一个独立的函数中,并让函数名称来解释该函数的用途。
- public void printOwing(double amount) {
- printBanner();
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
可以写成:
- public void printOwing(double amount) {
- printBanner();
- printDetails(amount);
- }
- /**
- * 描述:打印详情
- */
- public void printDetails(double amount) {
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
当看到一个过长的函数或需要注释才能让人理解的代码,应该考虑将这段代码放到一个单独的独立函数中。
做法:
1、创建一个新的函数,根据函数的意图来命名。
2、将提炼出来的代码从源函数(source)中拷贝到目标函数(target)中。
3、仔细检查提炼出来的代码,看其中是否引用了作用域仅限于源函数的变量。
4、检查是否有仅限于被提炼码的临时变量,如果有,在目标函数中将它申明为局部变量。
5、检查提炼码,看是否有任何局部变量的值被改变,如果有一个临时变量的值被改变,看是否能够将提炼码处理为一个查询,并将结果赋值给临时变量。
6、被提炼码中需要读取的局部变量,通过参数传递给目标函数。
7、处理完所有局部变量后编译,在源函数中替换目标函数,测试。
例子:
- private String name;
- private Vector<Order> orders = new Vector<Order>();
- public void printOwing() {
- Enumeration env = orders.elements();
- double totalAmount = 0.0;
- System.out.println("****************");
- System.out.println("***** test *****");
- System.out.println("****************");
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmout();
- }
- System.out.println("name:" + name);
- System.out.println("amount:" + totalAmount);
- }
提取没有局部变量的函数:
- private void printBanner() {
- System.out.println("****************");
- System.out.println("***** test *****");
- System.out.println("****************");
- }
提取有局部变量的函数:
如果被提炼码只是需要读取这些变量的值,并不修改他们,这时候我们只需要将它作为一个参数传递给目标函数即可,例:
- public void printDetails(double amount) {
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
如果被提炼码对局部变量进行赋值:
1、这个变量只是在提炼码区域中使用,那么可以将这个临时变量的申明式移动到提炼码中,然后一起提炼出去。
2、如果被提炼码之外的代码也使用了这个变量,可分为:
1)、如果这个变量在被提炼码之后未再被使用,只需要在目标函数中修改它的值即可。
2)、如果在提炼码之后还要使用该变量,这个时候就需要让目标函数返回该变量改变后的值。
1、提取getTotalAmount():
- /**
- * 描述:获取总账户余额
- */
- public double getTotalAmount() {
- double totalAmount = 0.0;
- Enumeration env = orders.elements();
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmount();
- }
- return totalAmount;
- }
这个时候的getOwing()可写成:
- public void printOwing() {
- printBanner();
- double totalAmount = getTotalAmount();
- printDetails(totalAmount);
- }
这里如果totalAmount初始值不是0,而有一个初值,这个时候就需要将这个初值传入到目标函数中去。
- public void printOwing(double initAmount) {
- printBanner();
- double totalAmount = initAmount * 1.5;
- totalAmount = getTotalAmount(totalAmount);
- printDetails(totalAmount);
- }
- /**
- * 描述:获取总账户余额
- */
- public double getTotalAmount(double initAmount) {
- double totalAmount = initAmount;
- Enumeration env = orders.elements();
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmount();
- }
- return totalAmount;
- }
临时变量往往很多,这个时候可以考虑Replace Temp with Query(以查询方法替代临时变量),如果这样依旧困难,可以考虑Replace method with method object(以函数变量替换函数)。