`
hhhhh-kk#qq.com
  • 浏览: 58497 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

抽象工厂模式代码

阅读更多


爪哇语言抽象工厂创立性模式介绍



  工厂模式有简单工厂模式,工厂方法模式和抽象工厂模式几种形态。其中简单工厂模式和工厂方法模式已经在前面作过介绍。在这里,我们来介绍抽象工厂模式。

  抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的一种形态。

  抽象工厂模式的定义

  抽象工厂模式是工厂方法模式的进一步扩广化和抽象化。我们给出抽象工厂模式的类图定义如下。


       图1. 抽象工厂模式的类图定义

  从上图可以看出,简单工厂模式涉及到以下的角色

   抽象工厂(AbstractFactory)类或接口

   担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创立对象的工厂类必须实现这个接口,或继承这个类。

   实工厂类 (Conrete Factory)

   担任这个角色的是与应用程序紧密相关的,直接在应用程序调用下,创立产品实例的那样一些类。

   抽象产品 (Abstract Product)

   担任这个角色的类是工厂方法模式所创立的对象的父类,或它们共同拥有的接口。

   实产品 (Concrete Product)

   担任这个角色的类是工厂方法模式所创立的任何对象所属的类。

  怎么这个类图和工厂方法模式的类图看起来是一样的?

  是的,图是一样的,但是含义有很大的不同。必须指出,在抽象工厂模式中,抽象产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个产品族(Product Family)。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。在上面的类图中,只给出了一个产品族,相当于位图中的一个点,而完整的位图应当是三维的,如下图。



     图2. 抽象工厂模式的位图
 
  从位图可以清楚地看到,与纸面垂直的数轴,即第三维轴,是代表产品族的数轴。上面的位图中展示的是有两个产品族,族A和族B的情形。

  在只有一个产品族时,第三维就坍缩掉,位图也就只剩下两维。这时抽象工厂模式就退化得与工厂方法模式一模一样。

  在什么情形下应当使用抽象工厂模式

  在以下情况下,应当考虑使用抽象工厂模式。

  首先,一个系统应当不依赖于产品类实例被创立,组成,和表示的细节。这对于所有形态的工厂模式都是重要的。

  其次,这个系统的产品有多于一个的产品族。

  第三,同属于同一个产品族的产品是设计成在一起使用的。这一约束必须得在系统的设计中体现出来。

  最后,不同的产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节。

  其中第二丶第三个条件是我们选用抽象工厂模式而非其它形态的工厂模式的关键性条件。

  抽象工厂模式在小花果园系统中的实现

  现在,我们在佛罗里达的渡假小屋修整好啦。接下来,一项重要而光荣的工作,就是开发小屋后面的小花园。这意味着,我们有两处小花园需要照料,一处在北方地区,另一处在亚热带地区。抽象工厂模式正好适用于我们的情况。


图3. 抽象工厂模式应用于小花果园系统中。三种不同的背景颜色可以区分工厂类,蔬菜类(第一产品族),和水果类的类图(第二产品族)

   两处花园就相当于两个产品族。显然,给北方花园的植物是要种植在一起的,给南方花园的植物是要另种植在一起的。这种分别应当体现在系统的设计上面。这就满足了应当使用抽象工厂模式的第二和第三个条件。

package com.javapatterns.abstractfactory;

public interface Gardener {}

  代码清单1. 接口 Gardener。


package com.javapatterns.abstractfactory;

public class NorthenGardener implements Gardener
{
 public VeggieIF createVeggie(String name) { return new NorthernVeggie(name); }

 public FruitIF createFruit(String name) { return new NorthernFruit(name); }

}

  代码清单2. 实工厂类 NorthenGardener。


package com.javapatterns.abstractfactory;

public class TropicalGardener implements Gardener
{
 public VeggieIF createVeggie(String name) { return new TropicalVeggie(name); }

 public FruitIF createFruit(String name) { return new TopicalFruit(name); }

}

  代码清单3. 实工厂类 TropicalGardener。


package com.javapatterns.abstractfactory;

public interface VeggieIF {}

  代码清单4. 接口 VeggieIF。


package com.javapatterns.abstractfactory;

public class NorthernVeggie implements VeggieIF
{
 public NorthernVeggie(String name) { this.name = name; }

 public String getName(){ return name; }

 public void setName(String name){ this.name = name; }

 private String name;
}


代码清单5. 实产品类 NorthernVeggie。实产品类 NorthernFruit 与此极为类似,故略去。


package com.javapatterns.abstractfactory;

public class TropicalVeggie implements VeggieIF
{
 public TropicalVeggie(String name) { this.name = name;}

 public String getName(){ return name; }

 public void setName(String name){ this.name = name; }

 private String name;
}

  代码清单6. 实产品类 TropicalVeggie。实产品类 TropicalFruit 与此极为类似,故略去。

  笔者对植物的了解有限,为免遗笑大方,在上面的系统里采用了简化处理。没有给出高纬度和低纬度的水果类或蔬菜类的具体名称。

  抽象工厂模式的另一个例子

  这个例子讲的是微型计算机的生产。产品族有两个,PC(IBM系列)和Mac(MacIntosh系列)。显然,我们应该使用抽象工厂模式,而不是工厂方法模式,因为后者适合于处理只有一个产品族的情形。


图4. 抽象工厂模式应用于微型计算机生产系统中。两种不同的背景颜色可以区分两类产品族,及其对应的实工厂类

   关于模式的实现

  在抽象实现工厂模式时,有下面一些值得注意的技巧。

  第一丶实工厂类可以设计成单态类。很显然,在小花果园系统中,我们只需要 NorthenGardener 和TropicalGardener 的一个实例就可以了。关于单态类的知识,请见<爪哇语言单态类创立性模式>。

  第二丶在实现抽象工厂模式时,产品类往往分属多于一个的产品族,而针对每一族,都需要一个实工厂类。在很多情况下,几个实工厂类都彼此相象,只有些微的差别。

  这时,笔者建议使用原始模型(Prototype)模式。这一模式会在以后介绍,届时作者会进一步阐述这一点。

  第三丶设计更加灵活的实工厂。以微型计算机生产系统为例,PCProducer 是一个实工厂类,它的不灵活之处在于,每一种产品都有一个工厂方法。CPU 有createCPU(),RAM 有createRAM(),等等。如果一个已有的系统需要扩充,比如增加硬盘这一新产品,我们就需要增加一系列的接口 (createHD())丶类(HD, PCHD, MacHD)和方法。这似乎不很理想。

  一个解决的办法是,把createCPU(),createRAM(), createHD()这几个方法合并为一个createPart(String type)方法。这个合并后的方法返还一个Part接口。所有的产品都要实现这一接口,而CPU,RAM,和HD接口则不再需要了。每一个实产品都需要有一个属性,表明它们的种类是CPU,RAM,和HD。

  这样做的结果是,数据类型的丰富结构被扁平化了。客户端拿到的永远是一个Part接口。这对客户端而言不很安全。

  第四丶抽象工厂类可以配备静态方法,以返还实工厂。设计的方法有两种。

  一种是以一个静态方法,按照参量的值,返回所对应的实工厂。静态方法的数据类型是抽象方法类。

  另一种是以每一个实工厂类都配备一个静态方法,其数据类型是该实工厂类。

  问答题

  第1题。如上面的讨论,抽象工厂类可以配备一个静态方法,按照参量的值,返回所对应的实工厂。请把微型计算机生产系统的抽象工厂类按照这一方案改造,给出UML类图和源代码。

  第2题。如上面的讨论,抽象工厂类可以配备一系列静态方法对应一系列的实工厂。请把微型计算机生产系统的抽象工厂类按照这一方案改造,给出UML类图和源代码。

  第3题。如上面的讨论,实工厂类可以设计成单态类。请在第1题的基础上把微型计算机生产系统的实工厂类按照这一方案改造,给出UML类图和源代码。

  问答题答案

  第1题。微型计算机生产系统的抽象工厂原本是接口,现在需要改造成抽象类。


图5. 三种不同的背景颜色可以区分抽象工厂类,两类产品族,及其对应的实工厂类。ComputerProducer 类图中类名为斜体表明该类是抽象的,而getProducer()的下划线表明该方法是静态的

package com.javapatterns.abstractfactory.exercise1;

public class ComputerProducer
{
 public static ComputerProducer getProducer(String which)
 {
  if (which.equalsIgnoreCase("PC"))
  {
   return new PCProducer();
  }
  else (which.equalsIgnoreCase("Mac"))
  {
   return new MacProducer();
  }
 }
}

  代码清单7. 抽象类 ComputerProducer 的方法 getProducer(String which)。

  第2题。略。

  第3题。本题答案是在第1题基础之上的。


图6. 三种不同的背景颜色可以区分抽象工厂类,两类产品族,及其对应的实工厂类。ComputerProducer 类图中类名为斜体表明该类是抽象的,而getProducer()的下划线表明该方法是静态的。MacProducer 和 PCProducer 的构造子是私有的,因此这两个类必须自己将自己实例化。

package com.javapatterns.abstractfactory.exercise3;

abstract public class ComputerProducer
{
 public static ComputerProducer getProducer(String which)
 {
  if (which.equalsIgnoreCase("PC"))
  {
   return PCProducer.getInstance();
  }
  else (which.equalsIgnoreCase("Mac"))
  {
   return MacProducer.getInstance();
  }
 }
}

代码清单8.抽象工厂类ComputerProducer。


package com.javapatterns.abstractfactory.exercise3;

public class MacProducer extends ComputerProducer
{
 private MacProducer() {
}

public CPU createCPU() {}

public RAM createRAM() {}

private static final m_MacProducer = new MacProducer();

}

代码清单9. 实工厂类 MacProducer 是单态类。读过笔者<单态创立性模式>一节的读者应当知道,这里使用的单态类实现方法是饿汉式方法。

package com.javapatterns.abstractfactory.exercise3;

public class PCProducer extends ComputerProducer
{
 private PCProducer() {
}

public CPU createCPU() {}

public RAM createRAM() {}

private static final m_PCProducer = new PCProducer();
}

  代码清单10. 实工厂类 PCProducer 是单态类,使用的单态类实现方法是饿汉式方法。

  各产品类没有变化,因此不在此重复。

分享到:
评论

相关推荐

    抽象工厂模式代码生成工具

    总的来说,"抽象工厂模式代码生成工具"结合C#的三层架构,为开发者提供了一种高效且灵活的代码生成解决方案,减少了手动编写重复代码的工作量,提高了开发效率。学习和掌握这一模式,对于提升软件开发的专业性和生产...

    设计模式-抽象工厂模式(讲解及其实现代码)

    抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体的类。这种模式允许系统独立于如何创建、组合和表示产品对象的细节进行设计,为产品族(一组相关或相互依赖的对象)提供...

    工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式

    工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...

    抽象工厂模式代码示例

    这个压缩包中的内容很可能是用Java语言编写的一系列示例代码,旨在帮助理解抽象工厂模式的工作原理。 抽象工厂模式的核心思想是将产品的创建过程抽象出来,形成一个工厂接口,然后针对不同的产品线,提供不同的具体...

    c++ java 抽象工厂模式代码

    在这个例子中,`factory-eclipse`和`factory-CodeBlocks`可能是两个不同的项目文件夹,分别包含了使用Eclipse或CodeBlocks开发环境实现的抽象工厂模式示例代码。 抽象工厂模式的优点包括: 1. 它提供了一种封装一组...

    C#抽象工厂模式案例代码

    抽象工厂模式是一种面向对象的设计模式,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在C#中,这种模式经常用于软件工程中的框架设计,允许系统独立于具体产品的实现进行扩展和修改。...

    Java工厂模式:简单工厂、工厂方法模式、抽象工厂模式代码示例

    在Java中,工厂模式分为三种:简单工厂、工厂方法模式和抽象工厂模式。 **简单工厂模式** 是最基本的工厂模式,它由一个工厂类根据传入的参数决定创建哪一种产品类的实例。简单工厂容易实现,但违反开闭原则,即...

    工厂方法模式和抽象工厂模式

    在给定的压缩包文件"factory"中,可能包含了一些关于工厂方法模式和抽象工厂模式的示例代码或者教程资料。通过研究这些文件,你可以更好地掌握这两种模式的实现细节,并将其应用于自己的项目中,提升代码的设计质量...

    Android抽象工厂模式demo

    在Android开发中,这种模式尤其有用,因为Android平台有多种设备,每种设备可能有不同的UI控件、硬件特性等,抽象工厂模式可以帮助我们构建与设备无关的代码。 在Android的"AbstractFactoryDemo"中,我们可以看到...

    JAVA简单的抽象工厂模式代码

    现在,客户端代码可以使用抽象工厂模式,无需关心具体的产品类型: ```java public class Client { public static void main(String[] args) { AbstractFactory factory; if (/* some condition */) { factory ...

    走进设计模式之抽象工厂(Abstract Factory)

    3. **模式的应用场景**:博客中可能会讨论何时使用抽象工厂模式,比如当系统需要在不修改现有代码的情况下支持新的产品族时,或者当需要将产品族的创建过程封装起来以便于更换或扩展时。 4. **模式的优势**:抽象...

    简单工厂模式-工厂方法模式-抽象工厂模式

    在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...

    抽象工厂模式+反射技术(抽象工厂模式+简单工厂模式)

    抽象工厂模式是设计模式中的一种,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在软件工程中,当系统需要在运行时选择不同的产品族时,或者想要隔离具体产品的实现细节时,抽象工厂...

    抽象工厂模式案例代码

    抽象工厂模式是一种设计模式,属于创建型模式,它提供了一种创建对象族的接口,而无需指定其具体的类。这种模式的关键在于“族”,它表示一系列相关或相互依赖的对象。在不指定具体类的情况下,抽象工厂模式使得...

    c#工厂模式——简单工厂_抽象工厂实例

    代码中展示了如何使用抽象工厂模式创建不同类型的计算机部件。`ComputerFactory` 类实现了 `ComputerInterface` 接口,该接口定义了创建不同类型部件的方法。具体来说: 1. **接口定义**: - `ICPU` 和 `IRAM` ...

    工厂模式(简单工厂,普通工厂,抽象工厂)代码java

    工厂模式分为三种主要类型:简单工厂模式、普通工厂模式(也称为工厂方法模式)和抽象工厂模式。 1. **简单工厂模式**: - 简单工厂模式中,有一个中心工厂类,它负责根据输入条件(通常是一个参数)来创建具体的...

Global site tag (gtag.js) - Google Analytics