全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

七、与其它模式的关系

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

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

八、模式优缺点

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

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


# java  # 设计模式  # 抽像工厂  # Java设计模式之桥接模式实例详解  # Java设计模式之单例模式实例详解【懒汉式与饿汉式】  # java 设计模式(DAO)的实例详解  # java设计模式之模板方法模式详解  # java设计模式之代理模式(Porxy)详解  # Java中的设计模式与7大原则归纳整理  # 快速理解Java设计模式中的组合模式  # 提供一个  # 都是  # 相互依赖  # 客户端  # 开闭  # 是一个  # 就可以  # 我们可以  # 很强  # 关联关系  # 只有一个  # 不支持  # 只需要  # 要对  # 样例  # 如下图  # 这是  # 这一  # 我要  # 很好 


相关文章: 如何在万网自助建站中设置域名及备案?  南宁网站建设制作定制,南宁网站建设可以定制吗?  建站之星代理平台如何选择最佳方案?  如何制作网站标识牌,动态网站如何制作(教程)?  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  如何通过.red域名打造高辨识度品牌网站?  做企业网站制作流程,企业网站制作基本流程有哪些?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  清除minerd进程的简单方法  网站制作壁纸教程视频,电脑壁纸网站?  MySQL查询结果复制到新表的方法(更新、插入)  义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?  建站主机与虚拟主机有何区别?如何选择最优方案?  金*站制作公司有哪些,金华教育集团官网?  安云自助建站系统如何快速提升SEO排名?  如何使用Golang安装API文档生成工具_快速生成接口文档  如何快速搭建高效可靠的建站解决方案?  单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?  建站之星代理如何获取技术支持?  如何选择域名并搭建高效网站?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  定制建站哪家更专业可靠?推荐榜单揭晓  淘宝制作网站有哪些,淘宝网官网主页?  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  如何通过IIS搭建网站并配置访问权限?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  建站主机如何安装配置?新手必看操作指南  定制建站方案优化指南:企业官网开发与建站费用解析  常州企业网站制作公司,全国继续教育网怎么登录?  网站按钮制作软件,如何实现网页中按钮的自动点击?  建站168自助建站系统:快速模板定制与SEO优化指南  如何自定义建站之星网站的导航菜单样式?  如何选择高效稳定的ISP建站解决方案?  如何在阿里云通过域名搭建网站?  建站主机选哪种环境更利于SEO优化?  建站与域名管理如何高效结合?  制作国外网站的软件,国外有哪些比较优质的网站推荐?  建站主机服务器选购指南:轻量应用与VPS配置解析  北京网站制作的公司有哪些,北京白云观官方网站?  Swift中循环语句中的转移语句 break 和 continue  广州美橙建站如何快速搭建多端合一网站?  建站之星安装提示数据库无法连接如何解决?  广东企业建站网站优化与SEO营销核心策略指南  公司网站制作价格怎么算,公司办个官网需要多少钱?  Python如何创建带属性的XML节点  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  如何快速生成ASP一键建站模板并优化安全性?  微网站制作教程,不会写代码,不会编程,怎么样建自己的网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。