用几乎完全重复的代码重构功能,但对其他方法的调用不同

时间:2018-08-16 11:34:45

标签: java intellij-idea methods refactoring code-duplication

我正在学习Java,并且正在学习在线课程,并且正在进行其中的一种编码练习,并且意识到我的两种方法之间存在很多重复之处,如下所示:

private static void addCustomerTransaction() {
    System.out.println("Enter the branch name:");
    String branchName = scanner.nextLine();

    System.out.println("Enter the customer name:");
    String customerName = scanner.nextLine();

    System.out.println("Enter the transaction");
    while (!scanner.hasNextDouble()) {
        scanner.next();
    }
    double transaction = scanner.nextDouble();

    bank.addCustomerTransaction(branchName,customerName,transaction);

}

private static void addCustomer() {
    System.out.println("Enter the branch name:");
    String branchName = scanner.nextLine();

    System.out.println("Enter the customer name:");
    String customerName = scanner.nextLine();

    System.out.println("Enter the transaction");
    while (!scanner.hasNextDouble()) {
        scanner.next();
    }
    double transaction = scanner.nextDouble();

    bank.addCustomer(branchName,customerName,transaction);
}

现在,这两个函数之间唯一的区别显然是对bank类对象的方法调用-最终执行不同的操作。

我想知道如何重构这些方法,以减少重复。我知道了:

private static void addCustomerTransaction() {
    customerInput();

}

private static void addCustomer() {
    customerInput();
}

private static void customerInput() {
    System.out.println("Enter the branch name:");
    String branchName = scanner.nextLine();

    System.out.println("Enter the customer name:");
    String customerName = scanner.nextLine();

    System.out.println("Enter the transaction");
    while (!scanner.hasNextDouble()) {
        scanner.next();
    }
    double transaction = scanner.nextDouble();

    bank.addCustomerTransaction(branchName,customerName,transaction);
}

但是我不知道如何启用代码来更改方法调用(当前为bank.addCustomerTransaction(branchName,customerName,transaction);  在customerInput函数中进行调用,具体取决于哪个函数正在调用customerInput

有人可以建议下一步吗?

4 个答案:

答案 0 :(得分:1)

这里是一种选择。

为最后一个方法创建接口:

@FunctionalInterface public interface CustomerOperation {
  void apply(Bank bank, String branch, String customer, String transaction);
}

然后您的常用方法如下所示:

private static void customerInput(CustomerOperation operation) {
  //common code here
  operation.apply(bank, branchName, customerName, transaction);
}

您这样称呼它:

private static void addCustomerTransaction() {
  customerInput((bank, branchName, customerName, transaction) ->
      bank.addCustomerTransaction(branchName, customerName, transaction));
}

private static void addCustomer() {
  customerInput((bank, branchName, customerName, transaction) ->
      bank.addCustomer(branchName, customerName, transaction));
}

或使用方法引用:

private static void addCustomerTransaction() {
  customerInput(Bank::addCustomerTransaction);
}

private static void addCustomer() {
  customerInput(Bank::addCustomer);
}

答案 1 :(得分:1)

如何创建一个包含用户输入的类?

public class TransactionInfo {

  private String branchName;
  private String customerName;
  private Double transaction;

  public TransactionInfo(String branchName, String customerName, Double transaction) {
    this.branchName = branchName;
    this.customerName = customerName;
    this.transaction = transaction;
  }

  ...
}

private static TransactionInfo customerInput() {
  System.out.println("Enter the branch name:");
  String branchName = scanner.nextLine();

  System.out.println("Enter the customer name:");
  String customerName = scanner.nextLine();

  System.out.println("Enter the transaction");
  while (!scanner.hasNextDouble()) {
    scanner.next();
  }
  double transaction = scanner.nextDouble();

  return new TransactionInfo(branchName, customerName, transaction);
}

private static void addCustomerTransaction() {
  TransactionInfo transactionInfo = customerInput();
  bank.addCustomerTransaction(transactionInfo.getBranchName(), transactionInfo.getCustomerName(), transactionInfo.getTransaction());
}

private static void addCustomer() {
  TransactionInfo transactionInfo = customerInput();
  bank.addCustomer(transactionInfo.getBranchName(), transactionInfo.getCustomerName(), transactionInfo.getTransaction());
}

如果您可以控制bank的类,则可以考虑使addCustomeraddCustomerTransaction方法接受TransactionInfo作为参数。

此外,该类的名称可能比TransactionInfo好。但我希望你能明白。

您有正确的想法将通用代码提取到方法中。可以看到,与您的方法相比,我的解决方案基本上只为客户输入添加一个类,以用作customerInput方法的返回值。祝你好运:)

答案 2 :(得分:1)

private static double readTransaction() {
    System.out.println("Enter the transaction");
    while (!scanner.hasNextDouble()) {
        scanner.next();
    }
    double transaction = scanner.nextDouble();
    return transaction;
}

private static String readCustomerName() {
    System.out.println("Enter the customer name:");
    String customerName = scanner.nextLine();
    return customerName;
}

private static String readBranch() {
    System.out.println("Enter the branch name:");
    String branchName = scanner.nextLine();
    return branchName;
}

private static void addCustomer() {
    String branchName = readBranch();
    String customerName = readCustomerName();
    double transaction = readTransaction();
    bank.addCustomer(branchName,customerName,transaction);
}

private static void addCustomerTransaction() {
    String branchName = readBranch();
    String customerName = readCustomerName();
    double transaction = readTransaction();
    bank.addCustomerTransaction(branchName,customerName,transaction);
}

此外,您可以通过制作一个包含分支机构名称,客户名称和交易的类来Preserve Whole Object,并执行以下操作:

class Receipt {
    private String customerName;
    private String branchName;
    private double transaction;

    //Getters and setters...

    public void populateReceipt () {
        customerName = readCustomer();
        branchName = readBranch();
        transaction = readTransaction();
    }
}

后跟...

private void addCustomer (Receipt receipt) {
    //Modify the method to take in a receipt, rather than its 3 components
    bank.addCustomer(receipt);
}

private void addCustomerTransaction (Receipt receipt) {
    //Modify the method to take in a receipt, rather than its 3 components
    bank.addCustomerTransaction(receipt);
}

答案 3 :(得分:0)

您可以使它们成为一个函数,并带有另一个参数,以定义是否要将其设为addCustomerTransaction或addCustomer,如下所示:

private static void addCustomer(boolean transaction) {
System.out.println("Enter the branch name:");
String branchName = scanner.nextLine();

System.out.println("Enter the customer name:");
String customerName = scanner.nextLine();

System.out.println("Enter the transaction");
while (!scanner.hasNextDouble()) {
    scanner.next();
}
double transaction = scanner.nextDouble();

if( transaction ) {
       bank.addCustomerTransaction(branchName,customerName,transaction);
  } else {
      bank.addCustomer(branchName,customerName,transaction);
  }
}