如何修正违反接口隔离原则的Abstract Factory设计模式示例
修复抽象工厂模式违反接口隔离原则的问题
问题分析
原示例的核心问题在于单一抽象工厂接口承担了两类产品的创建职责,导致Bank_Factory被迫实现不需要的get_Loan()方法并返回null,Loan_Factory被迫实现不需要的get_Bank()方法并返回null,直接违反了接口隔离原则(ISP)——客户端不应该依赖它用不到的接口。
修改方案
- 拆分抽象工厂接口:将原
Abstract_Factory拆分为两个独立的接口,分别负责一类产品的创建。 - 调整具体工厂实现:每个具体工厂只实现对应产品的创建接口,消除冗余方法。
- 适配客户端调用逻辑:确保客户端仅获取并使用所需的工厂接口,避免依赖无关方法。
修改后的完整代码
import java.util.Scanner; // Bank相关类保持不变 class Governmental_Bank implements Bank { private final String bank_Name; public Governmental_Bank() { this.bank_Name = "NBP"; } @Override public String get_Bank_Name() { return this.bank_Name; } } class PrivateBank implements Bank { private final String bank_Name; public PrivateBank() { bank_Name = "HBL"; } @Override public String get_Bank_Name() { return bank_Name; } } public interface Bank { String get_Bank_Name(); } // Loan相关类保持不变 public class Education_Loan extends Loan { @Override public void get_Interest_Rate(double rate) { this.rate = rate; } } public class Business_Loan extends Loan { @Override public void get_Interest_Rate(double rate) { this.rate = rate; } } public class Home_Loan extends Loan { @Override public void get_Interest_Rate(double rate) { this.rate = rate; } } public abstract class Loan { protected double rate; abstract void get_Interest_Rate(double rate); public void calculateLoanPayment(double loanamount, int years) { double EMI; int n; n = years * 12; rate = rate / 1200; EMI = ((rate * Math.pow((1 + rate), n)) / ((Math.pow((1 + rate), n)) - 1)) * loanamount; System.out.println("your monthly EMI is " + EMI + " for the amount " + loanamount + " you have borrowed"); } } // 拆分后的抽象工厂接口 public interface BankFactory { Bank get_Bank(String bank); } public interface LoanFactory { Loan get_Loan(String loan); } // 调整后的具体工厂 class Bank_Factory implements BankFactory { @Override public Bank get_Bank(String bank) { if (bank == null) { return null; } if (bank.equalsIgnoreCase("GovernmentalBank")) { return new Governmental_Bank(); } else if (bank.equalsIgnoreCase("PrivateBank")) { return new PrivateBank(); } return null; } } class Loan_Factory implements LoanFactory { @Override public Loan get_Loan(String loan) { if (loan == null) { return null; } if (loan.equalsIgnoreCase("Home")) { return new Home_Loan(); } else if (loan.equalsIgnoreCase("Business")) { return new Business_Loan(); } else if (loan.equalsIgnoreCase("Education")) { return new Education_Loan(); } return null; } } // 补充原代码中缺失的Factory_Creator类 class Factory_Creator { public static BankFactory getBankFactory() { return new Bank_Factory(); } public static LoanFactory getLoanFactory() { return new Loan_Factory(); } } // 调整后的主类 class Abstract_Factory_Pattern { public static void main(String args[]) { Scanner input = new Scanner(System.in); System.out.print("Enter Bank name (GovernmentalBank/PrivateBank): "); String bankName = input.nextLine(); System.out.print("\n"); System.out.print("Enter loan type (Home, Business, or Education) : "); String loanName = input.nextLine(); BankFactory bankFactory = Factory_Creator.getBankFactory(); Bank bank = bankFactory.get_Bank(bankName); System.out.print("\n"); System.out.print("Enter the interest rate for " + bank.get_Bank_Name() + ": "); double rate = input.nextDouble(); System.out.print("\n"); System.out.print("Enter the loan amount you want to take: "); double loanAmount = input.nextDouble(); System.out.print("\n"); System.out.print("Enter the number of years to pay your loan amount: "); int years = input.nextInt(); LoanFactory loanFactory = Factory_Creator.getLoanFactory(); Loan loan = loanFactory.get_Loan(loanName); loan.get_Interest_Rate(rate); loan.calculateLoanPayment(loanAmount, years); } }
说明
修改后:
- 每个工厂只负责一类产品的创建,不再需要实现无关方法,完全符合接口隔离原则。
- 客户端代码通过明确的
BankFactory和LoanFactory接口获取对应产品,逻辑更清晰,避免了对冗余方法的依赖。
内容的提问来源于stack exchange,提问作者ABU-ZHAR
相关产品推荐
相关产品推荐

