java设计模式之抽像工厂详解

 一、概念

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

二、模式动机

  这一系列对像之间是相互依赖的,相当于一个产品族

 三、模式的结构

通过上图我们可以清楚的看到抽像工厂模式包括以下4个角色:

  1.抽像工厂角色(AbstractFactory):抽像工厂模式的核心,与具体的商业逻辑无关,通常是一个JAVA接口或者抽像类。

  2.具体工厂角色(Concrete Factory):该角色通常与具体的商业逻辑紧密相关,该角色里面的工厂方法依据具体的商业逻辑实例化具体的产品并返回,客户端通过该角色并调用该角色的工厂方法,获得具体产品对像,该角色通常都是一个具体JAVA类来承担。

  3.抽像产品角色:担任这个角色的类是工厂方法模式所创建的产品的父类,或者他们共同拥有的接口,通常是一个接口或者抽像类。

  4.具体产品角色:抽像工厂模式所创建的任何产品都是这个角色的实例,有一个具体JAVA类来承担。

样例代码如下:

public class AbstractProductA
{

  /**
  * @roseuid 59AC05990327
  */
  public AbstractProductA()
  {

  }
}

public class ProductA1 extends AbstractProductA
{

  /**
  * @roseuid 59AC05990359
  */
  public ProductA1()
  {

  }
}

public class ProductA2 extends AbstractProductA
{

  /**
  * @roseuid 59AC05990381
  */
  public ProductA2()
  {

  }
}

public class AbstractProductB
{

  /**
  * @roseuid 59AC059903BA
  */
  public AbstractProductB()
  {

  }
}

public class ProductB1 extends AbstractProductB
{

  /**
  * @roseuid 59AC059A001F
  */
  public ProductB1()
  {

  }
}

public class ProductB2 extends AbstractProductB
{

  /**
  * @roseuid 59AC059A0049
  */
  public ProductB2()
  {

  }
}

public abstract class AbstractFactory
{

  /**
  * @roseuid 59AC05690005
  */
  public AbstractFactory()
  {

  }

  /**
  * @return AbstractProductA
  * @roseuid 59ABFB0103BE
  */
  public Abstract AbstractProductA createProductA() ;

  /**
  * @return AbstractProductB
  * @roseuid 59ABFB3B029D
  */
  public Abstract AbstractProductB createProductB() ;
}

public class ConcreteFactory1 extends AbstractFactory
{

  /**
  * @roseuid 59AC057A02FC
  */
  public ConcreteFactory1()
  {

  }

  /**
  * @return AbstractProductA
  * @roseuid 59ABFB9C00C9
  */
  public AbstractProductA createProductA()
  {
    return new ProductA1();
  }

  /**
  * @return AbstractProductB
  * @roseuid 59ABFBA30011
  */
  public AbstractProductB createProductB()
  {
    return new ProductB1();
  }
}

public class ConcreteFactory2 extends AbstractFactory
{

  /**
  * @roseuid 59AC057A02C0
  */
  public ConcreteFactory2()
  {

  }

  /**
  * @return AbstractProductA
  * @roseuid 59ABFCC701B9
  */
  public AbstractProductA createProductA()
  {
    return new ProductA2();
  }

  /**
  * @return AbstractProductB
  * @roseuid 59ABFCC9001F
  */
  public AbstractProductB createProductB()
  {
    return new ProductB2();
  }
}
public class Client
{

  /**
  * @roseuid 59AC055700AB
  */
  public Client()
  {

  }

  public static void main(String[] args){
      AbstractFactory theAbstractFactory;
    AbstractProductA theAbstractProductA;
    AbstractProductB theAbstractProductB;

    theAbstractFactory=new ConcreteFactory1();

    theAbstractProductA=theAbstractFactory.createProductA();
    theAbstractProductB=theAbstractFactory.createProductB();

  }
}

  跟据上面的模式结构图我们对“提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类”  进行一个简要的分析:

1.相关或相互依赖对像,在这里面ProductA1的实例和ProductB1的实例就是一组相互关联(如内在的关联关系)或相互依赖(如整体和部分)关系,依据业务逻辑,ProductA1

只能和同一产品等级结构AbstractProductB下的ProductB1相互关联而无法与ProductB2关联在一起。

  2.提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类,这里面的接口,即为结构图中的AbstractProductA和AbstractProductB,客户端只依赖这些产品的接口进行编程,而不依赖于具体实现,即符合依赖倒转原则。“无需指定它们具体的类”  即客户端(client)跟本就不知道ProductA1、ProductA2、ProductB1和ProductB2的存在,客户端只需要调用具体工厂的工厂方法即可返回具体的产品实例。

四、模式样例

  我们接着工厂方法模式中的样例进行进一步分析,现在这个生产轮胎的工厂已经不满足只生产轿车轮胎了,他现已经引入了发动机的生产线(EngineLine)、车门(DoorLine)等整个车的各种零部件生产线,可以说他现在可以轻松制造一部Car,但是也并非所有的Car都能制造,比如他现只能生产benz和BMW两种类型的车(这样的工厂也够NX了),比如现在一部车只包含车轮胎、车门和发动机(当然肯定不止这么多),那么这个工厂就可以跟据客户的要求生产BMW和benz车了,如下图:

代码如下:  

public interface Door {
  public void open();
  public void close();
}
public class BenzDoor implements Door {

  @Override
  public void open() {
    System.out.println("奔驰车门开");
  }

  @Override
  public void close() {
    System.out.println("奔驰车门关");
  }
}
public class BmwDoor implements Door {

  @Override
  public void open() {
    System.out.println("宝马车门开");
  }

  @Override
  public void close() {
    System.out.println("宝马车门关");
  }

}
public interface Tire {
  public void getColor();
  public void getLife();
  public void getWidth();
}
public class BenzTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("benz车color");
  }

  @Override
  public void getLife() {
    System.out.println("benz车life");
  }

  @Override
  public void getWidth() {
    System.out.println("benz车width");
  }
}
public class BmwTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("bmw车color");
  }

  @Override
  public void getLife() {
    System.out.println("bmw车life");
  }

  @Override
  public void getWidth() {
    System.out.println("bmw车width");
  }

}
public interface Engine {
  public void start();

  public void stop();

}
public class BenzEngine implements Engine {

  @Override
  public void start() {
    System.out.println("benz车start");

  }

  @Override
  public void stop() {
    System.out.println("benz车stop");

  }

}
public class BmwEngine implements Engine {

  @Override
  public void start() {
    System.out.println("bmw车start");

  }

  @Override
  public void stop() {
    System.out.println("bmw车stop");

  }

}
public interface PartFactory {
  public Door createDoor();

  public Tire createTire();

  public Engine createEngine();

}
public class BenzPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BenzDoor();
  }

  @Override
  public Tire createTire() {
    return new BenzTire();
  }

  @Override
  public Engine createEngine() {
    return new BenzEngine();
  }

}
public class BmwPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BmwDoor();
  }

  @Override
  public Tire createTire() {
    return new BmwTire();
  }

  @Override
  public Engine createEngine() {
    return new BmwEngine();
  }

}
public class Car {
  private Door door;
  private Engine engine;
  private Tire tire;

  public Car(PartFactory factory) {
    this.door = factory.createDoor();
    this.engine = factory.createEngine();
    this.tire = factory.createTire();
  }

  public Door getDoor() {
    return door;
  }

  public Engine getEngine() {
    return engine;
  }

  public Tire getTire() {
    return tire;
  }
}
public class Client {

  public static void main(String[] args) {
    PartFactory partFactory=new BenzPartFactory();
    Car benzCar=new Car(partFactory);

    benzCar.getDoor().open();
    benzCar.getEngine().start();
    benzCar.getTire().getColor();

  }

}

运行结果如下:

  奔驰车门开
  benz车start
  benz车color

跟据上面的类图及运行结果可以做如下分析:

BenzDoor、BenzTire和BenzEngine有很强的关联关系,我们可以说一部benz车,不可能用Bmw的车门,即BmwDoor。这种很强的关联关系通过BenzPartFactory进行了很好的维护。对于客户端来说,如上面的client类,如果客户想要一部benz车,那么我只需要一个生产benz车的工厂即可,这个工厂所有的产品实例,都是benz车的部件。从运行结果我们也可以看出。

试想一下,随着这个工厂的发展,他现在也要生产Audi的车,这时我们只要增加一个audi的车门的类AudiDoor、AudiTire 、AudiEngine和AudiPartFactory就可以了,其它的类不需要做任何的修改。但客户说,我要在车上装一对翅膀呢,堵车时可以飞,这时我们就要对每个工厂都要增加能返回翅膀的工厂方法,要对每个工厂进行修改,这是不符合开闭原则的。所以说抽象工厂对增加产品等级结构方面是不支持开闭原则的,对于产品族维度(如audi车)是支持开闭原则的。

 五、模式的约束

  对于产生一个相互关联或依赖的产品族适用,且支持在产品族方向的扩展,不适用于产品等级方向的扩展。

六、模式的变体与扩展

  1、抽像工厂提供静态工厂方法:抽像工厂可以提供一个静态的工厂方法,通过参数返回具体的工厂实例。

  2、抽像工厂与具体工厂合并:如果在产品族方向上确定只有一个产品族,那么抽像工厂就没有必要了,这时只需要一个具体工厂就可以了,我们可以进一步延深,为这个具体工厂提供一个静态方法,该方法返回自已的实例。

七、与其它模式的关系

  如果只有一个产品等级结构,那么就是工厂方法模式了,如下图:  

  如果有多个产品等级结构,那么抽像工厂里面的每一个工厂方法都是"工厂方法"模式。

八、模式优缺点

  在产口族方向支持开闭原则,在产口等级结构方向不支持开闭原则。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java 设计模式(DAO)的实例详解

    java 设计模式(DAO)的实例详解 应用场景:在Java程序中,经常需要把数据持久化,也需要获取持久化的数据,但是在进行数据持久化的过程中面临诸多问题(如:数据源不同.存储类型不同.供应商不同.访问方式不同等等),请问如何能以统一的接口进行数据持久化的操作? 其实这个我没学号(≧ ﹏ ≦).我的理解就是一个产品面向的用户不是单一的,所以我们要兼容许多情况如前面提到的数据源不同.存储类型不同.供应商不同.访问方式不同等等. ★ 解决方案 DAO的理解: 1.DAO其实是利用组合工厂模式来解决问

  • Java设计者模式简单工厂模式解析

    简介 简单工厂模式 (Simple Factory) 又叫静态工厂方法(Static Factory Method)模式. 简单工厂模式通常是定义一个工厂类,这个类可以根据不同变量返回不同类的产品实例. 简单工厂模式是一种对象创建型模式但是简单工厂模式不属于23种Gof设计模式之一. 实例 如何实现一个具有加减乘除基本功能的计算器? 对于这四种运算来说,都需要两个操作数,差别仅在于返回的结果不同. 由此,我们可以抽象化它们的共性,提炼出一个父类.这个类中包含两个操作数,一个返回结果方法,这个方法

  • java 设计模式之State(状态模式)

    java 设计模式之State(状态模式) 在状态模式中,一个类的行为基于它的状态的改变而改变.状态模式归属于行为型模式. 在下面的实例中,我们创建了一个接口State,定义了一个操作方法,两个实现类StartState和StopState.另外,创建了一个上下文类Context,这个类关联到State类.UML类图如下所示: //状态类 public interface State { public void doAction(Context context); } //实现类StartSta

  • java中设计模式(多例)的实例详解

    java中设计模式(多例)的实例详解 多例:单例设计模式的变形,可以看成是一个缓存池的单例,而缓存池里面可以存多个数据 实例代码: //单例+缓存---没有控制池大小 public class A { //1创建一个单例的池 (private即把池封装成单例了) private static Map<String, A> pool = new HashMap<String, A>(); //池--集合: Map:key-value public synchronized stati

  • Java设计模式之静态工厂模式详解

    本文实例讲述了Java设计模式之静态工厂模式.分享给大家供大家参考,具体如下: 静态工厂模式(static factory)也叫简单工厂模式. 涉及到3个角色:工厂类角色,抽象产品类角色和具体产品类角色. 抽象产品类可以使用接口或者父类来描述产品对象的行为特征. 具体产品类就是某一具体的对象. 静态工厂类有一个静态的方法,含有判断逻辑,决定要创建哪一种具体的产品对象. 其设计模式如下: 抽象产品类  IProduct package org.test.design.sf; public inte

  • java设计模式之抽像工厂详解

     一.概念 提供一个创建一系列相关或相互依赖对像的接口,而无需指定它们具体的类. 二.模式动机 这一系列对像之间是相互依赖的,相当于一个产品族  三.模式的结构 通过上图我们可以清楚的看到抽像工厂模式包括以下4个角色: 1.抽像工厂角色(AbstractFactory):抽像工厂模式的核心,与具体的商业逻辑无关,通常是一个JAVA接口或者抽像类. 2.具体工厂角色(Concrete Factory):该角色通常与具体的商业逻辑紧密相关,该角色里面的工厂方法依据具体的商业逻辑实例化具体的产品并返回

  • Java设计模式之监听器模式实例详解

    本文实例讲述了Java设计模式之监听器模式.分享给大家供大家参考,具体如下: 监听器模式有三个要素--事件源.事件对象.监听器. 事件源:顾名思义,事件发生的源头,比如点击的按钮,属于被监听的对象: 事件对象:这个经常和事件源混淆,它经常被用来包装事件源,切记,它毕竟是个事件,比如点击事件,和事件源的区别自己感受,木有栗子: 监听器:这个是监听器模式的核心,定义事件发生后的动作,通常事件对象作为监听器中定义的函数入参. 下面举个简单的栗子: 故事背景是,小明是个不讲卫生的孩子,他妈妈很担心他的健

  • Java设计模式之策略模式示例详解

    目录 定义 结构 UML类图 UML序列图 深入理解策略模式 策略和上下文的关系 策略模式在JDK中的应用 该策略接口有四个实现类 策略模式的优点 策略模式的缺点 策略模式的本质 在讲策略模式之前,我们先看一个日常生活中的小例子: 现实生活中我们到商场买东西的时候,卖场往往根据不同的客户制定不同的报价策略,比如针对新客户不打折扣,针对老客户打9折,针对VIP客户打8折... 现在我们要做一个报价管理的模块,简要点就是要针对不同的客户,提供不同的折扣报价. 如果是有你来做,你会怎么做? 我们很有可

  • Java设计模式之职责链模式详解

    目录 前言 一.职责链模式的定义与特点 二.职责链模式的结构 三.职责链模式案例 前言 本文简单介绍了设计模式的一种--职责链模式  一.职责链模式的定义与特点 定义: 为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链:当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止. 比如我们的审批制度,低等级的审批不了的,交给上一级审批,依次类推,直到审批结束. 在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处

  • Java设计模式之适配器模式的示例详解

    目录 定义 分类 案例 需求 方案一:类适配器 方案二:对象适配器 方案三:接口适配器 对比分析 方案一:类适配器 方案二:对象适配器 方案三:接口适配器 总结 定义 适配器模式,即将某个类的接口转换成客户端期望的另一个接口的表示,主要目的是实现兼容性,让原本因为接口不匹配,没办法一起工作的两个类,可以协同工作. 分类 类适配器 对象适配器 接口适配器 案例 需求 手机充电,通过手机充电器将220V电压适配为5V 方案一:类适配器 定义220V交流电(被适配者的角色) /** * 220V交流电

  • Java设计模式之外观模式示例详解

    目录 定义 案例 需求 方案:外观模式实现 分析 总结 定义 外观模式为多个复杂的子系统,提供了一个一致的界面,使得调用端只和这个接口发生调用,而无须关系这个子系统内部的细节 案例 需求 看电影的时候需要进行一系列的操作,比如打开播放器,放下屏幕,打开投影仪,打开音响等,这个要怎么进行管理呢 方案:外观模式实现 定义播放器类 public class Player { private static Player player = new Player(); private Player(){}

  • Java设计模式之原型设计示例详解

    目录 简单说一下(定义) 稍微夸一下(优缺点) 顺便提一下(适用场景) 着重讲一下(深.浅克隆) 多多用一下(结构.代码实现) 简单说一下(定义) 什么是原型模式:原型模式是用于创建重复的对象,同时又能保证性能.用一个已经创建的实例作为原型,通过复制该原型对象来创建一个或者多个和原型相同或者相似的新对象 举例说明:我们都玩过打飞机的游戏,敌军的飞机可谓是数不胜数,但是如果每出一架敌机都要重新实例化的话,那么自然我们的功能很复杂.所以这个时候我们的原型模式就派上用场了,只实例化一架飞机出来,其他的

  • java设计模式策略模式图文示例详解

    目录 策略模式 意图 问题 解决方案 真实世界类比 策略模式结构 伪代码 策略模式适合应用场景 实现方式 策略模式优缺点 策略模式优缺点 与其他模式的关系 策略模式 亦称:Strategy 意图 策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换. 问题 一天,你打算为游客们创建一款导游程序.该程序的核心功能是提供美观的地图,以帮助用户在任何城市中快速定位. 用户期待的程序新功能是自动路线规划:他们希望输入地址后就能在地图上看到前往目的

  • Java设计模式中的外观模式详解

    目录 模式介绍 UML类图 外观模式案例: 外观模式的注意事项和细节 模式介绍 外观模式(Facade) ,也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节. UML类图 类图解析: Facade:为调用端提供统一的调用接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象

  • Java设计模式中的门面模式详解

    目录 门面模式 概述 应用场景 目的 优缺点 主要角色 门面模式的基本使用 创建子系统角色 创建外观角色 客户端调用 门面模式实现商城下单 库存系统 支付系统 物流系统 入口系统 客户端调用 门面模式 概述 门面模式(Facade Pattern)又叫外观模式,属于结构性模式. 它提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口.使得子系统更容易使用. 客户端不需要知道系统内部的复杂联系,只需定义系统的入口.即在客户端和复杂系统之间再加一层,这一层

随机推荐