使用几乎完全重复的代码但对其他方法的不同调用来重构函数
Refactoring functions with nearly entirely duplicate code but different calls to other methods
我正在学习 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);
}
现在显然这两个函数之间的唯一区别是对银行 class 对象的方法调用 - 最终执行不同的操作。
我想知道如何重构这些方法以减少重复。我得到了:
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
.
有人可以建议下一步吗?
您可以使它们成为一个函数,并使用另一个参数定义您是否要将其作为 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);
}
}
这是一种选择。
为最后一个方法创建接口:
@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);
}
如何创建包含用户输入的 class?
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
的 class,您可以考虑让 addCustomer
和 addCustomerTransaction
方法接受 TransactionInfo
作为参数.
另外,class 可能有一个比 TransactionInfo
更好的名字。但我希望你能明白。
您将通用代码提取到方法中的想法是正确的。您可以看到,与您的方法相比,我的解决方案基本上只为客户输入添加一个 class 以用作 customerInput
方法的 return 值。祝你好运:)
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,然后执行以下操作:
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);
}
我正在学习 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);
}
现在显然这两个函数之间的唯一区别是对银行 class 对象的方法调用 - 最终执行不同的操作。
我想知道如何重构这些方法以减少重复。我得到了:
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
.
有人可以建议下一步吗?
您可以使它们成为一个函数,并使用另一个参数定义您是否要将其作为 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);
}
}
这是一种选择。
为最后一个方法创建接口:
@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);
}
如何创建包含用户输入的 class?
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
的 class,您可以考虑让 addCustomer
和 addCustomerTransaction
方法接受 TransactionInfo
作为参数.
另外,class 可能有一个比 TransactionInfo
更好的名字。但我希望你能明白。
您将通用代码提取到方法中的想法是正确的。您可以看到,与您的方法相比,我的解决方案基本上只为客户输入添加一个 class 以用作 customerInput
方法的 return 值。祝你好运:)
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,然后执行以下操作:
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);
}