Java语言抽象工场创建性模式先容
当前位置:以往代写 > JAVA 教程 >Java语言抽象工场创建性模式先容
2019-06-14

Java语言抽象工场创建性模式先容

Java语言抽象工场创建性模式先容

副标题#e#

工场模式有简朴工场模式,工场要领模式和抽象工场模式几种形态。个中简朴 工场模式和工场要领模式已经在前面作过先容。在这里,我们来先容抽象工场模 式。

抽象工场模式是所有形态的工场模式中最为抽象和最具遍及性的一种形态。

抽象工场模式的界说

抽象工场模式是工场要领模式的进一步扩广化和抽象化。我们给出抽象工场 模式的类图界说如下。

Java语言抽象工厂建设性模式介绍

图1. 抽象工场模式的类图界说

从上图可以看出,简朴工场模式涉及到以下的脚色

抽象工场(AbstractFactory)类或接口

接受这个脚色的是工场要领模式的焦点,它是与应用措施无关的。任安在模 式中创建工具的工场类必需实现这个接口,或担任这个类。

实工场类 (Conrete Factory)

接受这个脚色的是与应用措施细密相关的,直接在应用措施挪用下,创建产 品实例的那样一些类。

抽象产物 (Abstract Product)

接受这个脚色的类是工场要领模式所创建的工具的父类,或它们配合拥有的 接口。

实产物 (Concrete Product)

接受这个脚色的类是工场要领模式所创建的任何工具所属的类。

怎么这个类图和工场要领模式的类图看起来是一样的?

是的,图是一样的,可是寄义有很大的差异。必需指出,在抽象工场模式中 ,抽象产物 (AbstractProduct) 大概是一个或多个,从而组成一个或多个产物 族(Product Family)。 在只有一个产物族的环境下,抽象工场模式实际上退化 到工场要领模式。在上面的类图中,只给出了一个产物族,相当于位图中的一个 点,而完整的位图该当是三维的,如下图。

Java语言抽象工厂建设性模式介绍

图2. 抽象工场模式的位图


#p#副标题#e#

从位图可以清楚地看到,与纸面垂直的数轴,即第三维轴,是代表产物族的 数轴。上面的位图中展示的是有两个产物族,族A和族B的景象。

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

在什么景象下该当利用抽象工场模式

在以下环境下,该当思量利用抽象工场模式。

首先,一个系统该当不依赖于产物类实例被创建,构成,和暗示的细节。这 对付所有形态的工场模式都是重要的。

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

第三,同属于同一个产物族的产物是设计成在一起利用的。这一约束必需得 在系统的设计中浮现出来。

最后,差异的产物以一系列的接口的面孔呈现,从而使系统不依赖于接话柄 现的细节。

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

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

此刻,我们在佛罗里达的渡假小屋修整好啦。接下来,一项重要而庆幸的工 作,就是开拓小屋后头的小花圃。这意味着,我们有两处小花圃需要顾问,一处 在北方地域,另一处在亚热带地域。抽象工场模式正好合用于我们的环境。

Java语言抽象工厂建设性模式介绍

图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 与此极为 雷同,故略去。

#p#分页标题#e#

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 与此极为 雷同,故略去。

笔者对植物的相识有限,为免遗笑大方,在上面的系统里回收了简化处理惩罚。 没有给出高纬度和低纬度的水果类或蔬菜类的详细名称。

#p#副标题#e#

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

这个例子讲的是微型计较机的出产。产物族有两个,PC(IBM系列)和Mac (MacIntosh系列)。显然,我们应该利用抽象工场模式,而不是工场要领模式, 因为后者适合于处理惩罚只有一个产物族的景象。

Java语言抽象工厂建设性模式介绍

图4. 抽象工场模式应用于微型计较机出产系统中。两种差异的配景颜色可以 区分两类产物族,及其对应的实工场类

关于模式的实现

在抽象实现工场模式时,有下面一些值得留意的能力。

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

第二丶在实现抽象工场模式时,产物类往往分属多于一个的产物族,而针对 每一族,都需要一个实工场类。在许多环境下,几个实工场类都相相互象,只有 些微的不同。

这时,笔者发起利用原始模子(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题。微型计较机出产系统的抽象工场原本是接口,此刻需要改革成抽象类 。

Java语言抽象工厂建设性模式介绍

#p#副标题#e#

图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题基本之上的。

Java语言抽象工厂建设性模式介绍

#p#分页标题#e#

图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 是单态类,利用的单态类实现要领是饿 汉式要领。

各产物类没有变革,因此不在此反复。

    关键字:

在线提交作业