Design Patterns教程-抽象工厂模式
抽象工厂模式表示定义一个接口或抽象类来创建一系列相关(或依赖)的对象,但不指定它们的具体子类。这意味着抽象工厂允许一个类返回一个工厂类。因此,抽象工厂模式比工厂模式更高一个层次。
抽象工厂模式也被称为Kit。
抽象工厂模式的优点
- 抽象工厂模式将客户端代码与具体实现类隔离开。
- 它便于交换对象家族。
- 它促进了对象之间的一致性。
抽象工厂模式的使用场景
- 当系统需要独立于对象的创建、组合和表示时。
- 当必须一起使用一组相关对象时,这种约束需要被强制执行。
- 当你想提供一个对象库,而不显示其实现,只揭示其接口时。
- 当系统需要配置为一个对象家族中的一个时。
抽象工厂模式的 UML
- 我们将创建一个Bank 接口和一个Loan 抽象类及其子类。
- 然后我们将创建AbstractFactory类作为下一步。
- 接着,我们将创建具体类BankFactory和LoanFactory,它们将扩展AbstractFactory类。
- 然后,AbstractFactoryPatternExample类使用FactoryCreator获取AbstractFactory类的对象。
- 请仔细看下面的图示:
抽象工厂模式示例
在这里,我们将计算不同银行(如 HDFC、ICICI、SBI 等)的贷款支付。
步骤 1: 创建一个 Bank 接口
import java.io.*;
interface Bank {
String getBankName();
}
步骤 2: 创建实现 Bank 接口的具体类。
class HDFC implements Bank {
private final String BNAME;
public HDFC() {
BNAME = "HDFC BANK";
}
public String getBankName() {
return BNAME;
}
}
class ICICI implements Bank {
private final String BNAME;
ICICI() {
BNAME = "ICICI BANK";
}
public String getBankName() {
return BNAME;
}
}
class SBI implements Bank {
private final String BNAME;
public SBI() {
BNAME = "SBI BANK";
}
public String getBankName() {
return BNAME;
}
}
步骤 3: 创建 Loan 抽象类。
abstract class Loan {
protected double rate;
abstract void getInterestRate(double rate);
public void calculateLoanPayment(double loanamount, int years) {
/*
计算月贷款支付,即 EMI
rate=年利率/12*100;
n=月分期数;
1年=12个月。
所以,n=年*12;
*/
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("你借的金额为" + loanamount + "的每月 EMI 是: " + EMI);
}
} // Loan 抽象类结束
步骤 4: 创建扩展 Loan 抽象类的具体类。
class HomeLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
} // HomeLoan 类结束
class BussinessLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
} // BussinessLoan 类结束
class EducationLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
} // EducationLoan 类结束
步骤 5: 创建一个抽象类(即 AbstractFactory)来获取 Bank 和 Loan 对象的工厂。
abstract class AbstractFactory {
public abstract Bank getBank(String bank);
public abstract Loan getLoan(String loan);
}
步骤 6: 创建继承 AbstractFactory 类的工厂类,根据给定信息生成具体类的对象。
class BankFactory extends AbstractFactory {
public Bank getBank(String bank) {
if (bank == null) {
return null;
}
if (bank.equalsIgnoreCase("HDFC")) {
return new HDFC();
} else if (bank.equalsIgnoreCase("ICICI")) {
return new ICICI();
} else if (bank.equalsIgnoreCase("SBI")) {
return new SBI();
}
return null;
}
public Loan getLoan(String loan) {
return null;
}
} // BankFactory 类结束
class LoanFactory extends AbstractFactory {
public Bank getBank(String bank) {
return null;
}
public Loan getLoan(String loan) {
if (loan == null) {
return null;
}
if (loan.equalsIgnoreCase("Home")) {
return new HomeLoan();
} else if (loan.equalsIgnoreCase("Business")) {
return new BussinessLoan();
} else if (loan.equalsIgnoreCase("Education")) {
return new EducationLoan();
}
return null;
}
}
步骤 7: 创建一个 FactoryCreator 类,通过传递诸如 Bank 或 Loan 等信息来获取工厂。
class FactoryCreator {
public static AbstractFactory getFactory(String choice) {
if (choice.equalsIgnoreCase("Bank")) {
return new BankFactory();
} else if (choice.equalsIgnoreCase("Loan")) {
return new LoanFactory();
}
return null;
}
} // FactoryCreator 结束
步骤 8: 使用 FactoryCreator 获取 AbstractFactory 以便通过传递类型信息获取具体类的工厂。
import java.io.*;
class AbstractFactoryPatternExample {
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入您想从中获取贷款金额的银行名称: ");
String bankName = br.readLine();
System.out.print("\n请输入贷款类型,例如住房贷款、商业贷款或教育贷款: ");
String loanName = br.readLine();
AbstractFactory bankFactory = FactoryCreator.getFactory("Bank");
Bank b = bankFactory.getBank(bankName);
System.out.print("\n请输入 " + b.getBankName() + " 的利率: ");
double rate = Double.parseDouble(br.readLine());
System.out.print("\n请输入您要贷款的金额: ");
double loanAmount = Double.parseDouble(br.readLine());
System.out.print("\n请输入还款年限: ");
int years = Integer.parseInt(br.readLine());
System.out.println("\n你从 " + b.getBankName() + " 获取贷款");
AbstractFactory loanFactory = FactoryCreator.getFactory("Loan");
Loan l = loanFactory.getLoan(loanName);
l.getInterestRate(rate);
l.calculateLoanPayment(loanAmount, years);
}
} // AbstractFactoryPatternExample 结束