前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >抽象工厂模式浅析

抽象工厂模式浅析

作者头像
孟君
发布2020-07-16 14:31:44
5060
发布2020-07-16 14:31:44
举报

一. 抽象工厂模式的基本介绍

意图

提供一个创建一系列或相互依赖对象的接口,而无需指定它们具体的类。

结构

抽象工厂模式的基本结构如下:

这里涉及到的参与者有如下几种:

  • 抽象工厂(AbstractFcatory)角色
    • 声明一个创建抽象产品对象的操作接口。
  • 具体工厂(ConcreteFactory)角色
    • 实现创建具体产品对象的操作。
  • 抽象产品(AbstractProduct)角色
    • 为一类产品对象声明一个接口
  • 具体产品(ConcreteProduct)角色
    • 定义一个将被相应的具体工厂创建的产品对象
    • 实现AbstractProduct接口
  • 抽象工厂(AbstractFcatory)角色
    • 仅使用由AbstractFactory和AbstractProduct类声明的接口

二. 抽象工厂模式的示例

接下来,我们创建两个产品族,一个是Bank,一个Loan,使用抽象工厂创建银行和贷款对象。

  • 抽象产品Bank和Loan
代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public interface Bank {

  String getBankName();
}

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public abstract class Loan {

  protected double rate;

  abstract void setCustomizeRate(double rate);

  abstract void printLoanPayment(double amount, int year);
}
  • 具体产品

银行类

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class ABCBank implements Bank {

  @Override
  public String getBankName() {
    return "中国农业银行";
  }

}

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class ICBCBank implements Bank{

  @Override
  public String getBankName() {
    return "中国工商银行";
  }

}

贷款类

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class HouseLoan extends Loan{

  @Override
  void printLoanPayment(double amount, int year) {
    System.out.println("*****************住房贷款信息**************");
    System.out.println("贷款金额:" + amount);
    System.out.println("贷款年数:" + year);
    System.out.println("贷款率:" + rate);
  }

  @Override
  void setCustomizeRate(double rate) {
    this.rate = rate;
  }

}

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class BusinessLoan extends Loan {

  @Override
  void printLoanPayment(double amount, int year) {
    System.out.println("*****************商业贷款信息**************");
    System.out.println("贷款金额:" + amount);
    System.out.println("贷款年数:" + year);
    System.out.println("贷款率:" + rate);
  }

  @Override
  void setCustomizeRate(double rate) {
    this.rate = rate;

  }

}
  • 抽象工厂
代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public interface AbstractFactory<T> {

    T create(String type) ;

}

这里为了以后每一种产品都适用,不去为每一种产品创建都指定一个方法,写了泛型,而没有写成如下的方式:

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public interface AbstractFactory {

    Bank createBank(String type) ;

    Loan createLoan(String type);

}
  • 具体工厂

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class BankFactory implements  AbstractFactory<Bank>{

  @Override
  public Bank create(String type) {
    if("icbc".equals(type) ) {
      return new ICBCBank();
    }else if("abc".equals(type)) {
      return new ABCBank();
    }
    throw new IllegalArgumentException("Bank Type is illeagal");
  }

}

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class LoanFactory implements AbstractFactory<Loan> {

  @Override
  public Loan create(String type) {
    if("house".equals(type)) {
      return new HouseLoan();
    }else if("business".equals(type)) {
      return new BusinessLoan();
    }
    throw new IllegalArgumentException("Loan type is ileagal");
  }

}

用于获取抽象工厂实例的静态工厂方法类:

代码语言:javascript
复制

package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class FactoryProvider {

  public static AbstractFactory<?> getFactory(String choice){

        if("Bank".equalsIgnoreCase(choice)){
            return new BankFactory();
        }
        else if("Loan".equalsIgnoreCase(choice)){
            return new LoanFactory();
        }

        return null;
    }
}

测试一下:

代码语言:javascript
复制

package com.wangmengjun.tutorial.designpattern.abstractfactory;

public class Client {

  public static void main(String[] args) {
    AbstractFactory<?> bankFactory =  FactoryProvider.getFactory("Bank");
    Bank icbc =(Bank) bankFactory.create("icbc");
    System.out.println(icbc.getBankName());

    AbstractFactory<?> loanFactory = FactoryProvider.getFactory("Loan");
    Loan houseLoan = (HouseLoan) loanFactory.create("house");
    houseLoan.setCustomizeRate(5.14d);
    houseLoan.printLoanPayment(1000000d, 20);

    System.out.println();
    System.out.println("*****************看看中国农业银行贷款信息*********************");
    Bank abc =(Bank) bankFactory.create("abc");
    System.out.println(abc.getBankName());
    houseLoan = (HouseLoan) loanFactory.create("house");
    houseLoan.setCustomizeRate(5.10d);
    houseLoan.printLoanPayment(1000000d, 20);

    Loan businessLoan = (BusinessLoan) loanFactory.create("business");
    businessLoan.setCustomizeRate(6.14d);
    businessLoan.printLoanPayment(1000000d, 10);
  }
}

输出:

代码语言:javascript
复制
中国工商银行
*****************住房贷款信息**************
贷款金额:1000000.0
贷款年数:20
贷款率:5.14

*****************看看中国农业银行贷款信息*********************
中国农业银行
*****************住房贷款信息**************
贷款金额:1000000.0
贷款年数:20
贷款率:5.1
*****************商业贷款信息**************
贷款金额:1000000.0
贷款年数:10
贷款率:6.14

至此,一个银行贷款的相关的抽象工厂模式示例就完成了。

三. 抽象工厂模式的基本介绍

优缺点

优点

1、它分离了具体的类。Abstract Factory模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。Client通过他们的抽象接口操纵实例。产品的类名也在具体工厂的实现中被分离;它们不出现在客户端代码中。

2、它有利于产品的一致性。当一个系列中的产品对象呗设计成一起工作时,一个应用一次只能使用同一个系列中的对象。这一点很重要。而Abstract Factory很容易实现这一点。

缺点

1、难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为AbstarctProduct接口确定了可以被创建的产品集合。

参考

[1]. 阎宏. Java与模式.电子工业出版社

[2]. Erich Gamma. 设计模式-可复用面向对象软件的基础. 机械工业出版社.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孟君的编程札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 抽象工厂模式的基本介绍
  • 三. 抽象工厂模式的基本介绍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档