抽象工厂模式表示定义一个接口或抽象类来创建一系列相关(或依赖)的对象,但不指定它们的具体子类。这意味着抽象工厂允许一个类返回一个工厂类。因此,抽象工厂模式比工厂模式更高一个层次。

抽象工厂模式也被称为Kit

抽象工厂模式的优点

  • 抽象工厂模式将客户端代码与具体实现类隔离开。
  • 它便于交换对象家族。
  • 它促进了对象之间的一致性。

抽象工厂模式的使用场景

  • 当系统需要独立于对象的创建、组合和表示时。
  • 当必须一起使用一组相关对象时,这种约束需要被强制执行。
  • 当你想提供一个对象库,而不显示其实现,只揭示其接口时。
  • 当系统需要配置为一个对象家族中的一个时。

抽象工厂模式的 UML

  • 我们将创建一个Bank 接口和一个Loan 抽象类及其子类。
  • 然后我们将创建AbstractFactory类作为下一步。
  • 接着,我们将创建具体类BankFactoryLoanFactory,它们将扩展AbstractFactory类。
  • 然后,AbstractFactoryPatternExample类使用FactoryCreator获取AbstractFactory类的对象。
  • 请仔细看下面的图示:

2-1.jpg

抽象工厂模式示例

在这里,我们将计算不同银行(如 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 结束

输出

2-2.jpg

标签: Design Patterns, Design Patterns教程, 设计模式, 软件设计, 结构型模式, 行为型模式, 单例模式, 工厂模式, 观察者模式, 中介者模式, 访问者模式