设计模式——创建型模式之抽象工厂模式(四)

模式的定义与特点

  抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

  抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
  • 当增加一个新的产品族时不需要修改原代码,满足开闭原则。

其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

模式的结构与实现

抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。

1. 模式的结构

抽象工厂模式的主要角色如下。

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

抽象工厂模式的结构图如图 2 所示。

        
                  图2 抽象工厂模式的结构图

2. 模式的实现

从图 2 可以看出抽象工厂模式的结构同工厂方法模式的结构相似,不同的是其产品的种类不止一个,所以创建产品的方法也不止一个。下面给出抽象工厂和具体工厂的代码。

  (1) 抽象工厂:提供了产品的生成方法。

interface AbstractFactory
{
    public Product1 newProduct1();
    public Product2 newProduct2();
}

  (2) 具体工厂:实现了产品的生成方法。

class ConcreteFactory1 implements AbstractFactory
{
    public Product1 newProduct1()
    {
        System.out.println("具体工厂 1 生成-->具体产品 11...");
        return new ConcreteProduct11();
    }
    public Product2 newProduct2()
    {
        System.out.println("具体工厂 1 生成-->具体产品 21...");
        return new ConcreteProduct21();
    }
}

模式的应用实例

【例1】用抽象工厂模式设计农场类。

分析:农场中除了像畜牧场一样可以养动物,还可以培养植物,如养马、养牛、种菜、种水果等,所以本实例比前面介绍的畜牧场类复杂,必须用抽象工厂模式来实现。

本例用抽象工厂模式来设计两个农场,一个是韶关农场用于养牛和种菜,一个是上饶农场用于养马和种水果,可以在以上两个农场中定义一个生成动物的方法 newAnimal() 和一个培养植物的方法 newPlant()。

对马类、牛类、蔬菜类和水果类等具体产品类,由于要显示它们的图像,所以它们的构造函数中用到了 JPanel、JLabel 和 ImageIcon 等组件,并定义一个 show() 方法来显示它们。

客户端程序通过对象生成器类 ReadXML 读取 XML 配置文件中的数据来决定养什么动物和培养什么植物。其结构图如图 3 所示。

          
                        图3 农场类的结构图    

程序代码如下:
package AbstractFactory;
import java.awt.*;
import javax.swing.*;
public class FarmTest
{
    public static void main(String[] args)
    {
        try
        {
            Farm f;
            Animal a;
            Plant p;
            f=(Farm) ReadXML.getObject();
            a=f.newAnimal();
            p=f.newPlant();
            a.show();
            p.show();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}
//抽象产品:动物类
interface Animal
{
    public void show();
}
//具体产品:马类
class Horse implements Animal
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Horse()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("动物:马"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/A_Horse.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//具体产品:牛类
class Cattle implements Animal
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Cattle() {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("动物:牛"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/A_Cattle.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//抽象产品:植物类
interface Plant
{
    public void show();
}
//具体产品:水果类
class Fruitage implements Plant
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Fruitage()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("植物:水果"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/P_Fruitage.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//具体产品:蔬菜类
class Vegetables implements Plant
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Vegetables()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("植物:蔬菜"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/P_Vegetables.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//抽象工厂:农场类
interface Farm
{
    public Animal newAnimal();
    public Plant newPlant();
}
//具体工厂:韶关农场类
class SGfarm implements Farm
{
    public Animal newAnimal()
    {
        System.out.println("新牛出生!");
        return new Cattle();
    }
    public Plant newPlant()
    {
        System.out.println("蔬菜长成!");
        return new Vegetables();
    }
}
//具体工厂:上饶农场类
class SRfarm implements Farm
{
    public Animal newAnimal()
    {
        System.out.println("新马出生!");
        return new Horse();
    }
    public Plant newPlant()
    {
        System.out.println("水果长成!");
        return new Fruitage();
    }
}
package AbstractFactory;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
class ReadXML
{
    public static Object getObject()
    {
        try
        {
            DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=dFactory.newDocumentBuilder();
            Document doc;
            doc=builder.parse(new File("src/AbstractFactory/config.xml"));
            NodeList nl=doc.getElementsByTagName("className");
            Node classNode=nl.item(0).getFirstChild();
            String cName="AbstractFactory."+classNode.getNodeValue();
            System.out.println("新类名:"+cName);
            Class<?> c=Class.forName(cName);
              Object obj=c.newInstance();
            return obj;
        }
        catch(Exception e)
        {
               e.printStackTrace();
               return null;
        }
    }
}
程序运行结果如图 4 所示。


图4 农场养殖的运行结果

模式的应用场景

抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件。如 java 的 AWT 中的 Button 和 Text 等构件在 Windows 和 UNIX 中的本地实现是不同的。

抽象工厂模式通常适用于以下场景:
  1. 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
  2. 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
  3. 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

模式的扩展

抽象工厂模式的扩展有一定的“开闭原则”倾斜性:
  1. 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则。
  2. 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。
另一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。


原文地址:https://www.cnblogs.com/yuexiaoyun/p/11846106.html

时间: 2024-11-10 08:14:17

设计模式——创建型模式之抽象工厂模式(四)的相关文章

设计模式系列一创建型之(抽象工厂模式)

1.抽象工厂简介 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时由于需求的变化,往往存在着更多系列对象的创建工作. 如何应对这种变化? 如何绕过常规的对象的创建方法(new)? 如何来避免客户程序和这种“多系列具体对象创建工作”的紧耦合? 然而抽象工厂便可以很好地解决这个问题! 2.意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. 3.适用性 一个系统要独立与它的产品创建.组合和表示时 一个系统要由多个产品系列中的一个来配置时 当你要强调一系列相关的产

【C#设计模式——创建型模式】抽象工厂模式

抽象工厂模式比工厂模式具有更高层次的抽象性.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以选择这种模式.直接进入示例. 示例描述:完成花园的规划,多种花园种类,每个里面多种植物 编写一个基类Garden,Garden就是抽象工厂.它定义了具体类中的方法,并返回一系列相关类中的某个类. public class Garden { protected Plant center, shade, border; protected bool showCenter, showS

java设计模式 -------- 创建模式 之 抽象工厂模式

本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 工厂方法模式和抽象工厂模式不好区分清楚: 工厂方法模式特点: 1. 一个抽象产品类,可以派生出多个具体产品类. 2. 一个抽象工厂类,可以派生出多个具体工厂类. 3. 每个具体工厂类只能创建一个具体产品类的实例. 抽象工厂模式特点: 1. 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类. 2. 一个抽象工厂类,可以派生出多个具体工厂类. 3. 每个具体工厂类可以创建多个

23种设计模式(3):抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,并且无需指定他们的详细类. 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的差别 抽象工厂模式是工厂方法模式的升级版本号,他用来创建一组相关或者相互依赖的对象.他与工厂方法模式的差别就在于,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式则是针对的多个产品等级结构.在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的全部产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类

简单工厂模式、工厂方法模式和抽象工厂模式-设计模式学习

1.简单工厂模式 简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 工厂(Creator)角色 简单工厂模式的核心,它负责实现创建所有实例的内部逻辑.工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象. 抽象产品(Product)角色 简单工厂模式所创建的所有

设计模式系列——三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)

原文地址:http://blog.chinaunix.net/uid-25958655-id-4243289.html 简单工厂模式 当需要加法类的时候,调用工厂类的CreateOperate(),要指定制造的Product 例如在大话设计模式P11给的运算工厂例子: public static Operation createOperate(string operate) { Operation oper = null; 12 switch (operate) { case "+":

易学设计模式看书笔记(4) - 抽象工厂模式

 本文内容来自书上,不懂设计模式,只求混个眼熟. 三.抽象工厂模式 1.动物管理系统的例子 public interface Animal{ public void eat(); } public class Tiger implements Animal { public void eat(){ sysout.out.println("老虎会吃"); }; public void run(){ sysout.out.println("老虎会跑"); }; } pu

深入理解设计模式(五):抽象工厂模式

接着上一次的工厂方法模式讲. 假设目前你的程序里面有三个对象IphoneX.IphoneXs.IphoneXR的尺寸,那么你使用工厂模式就已经足够了,因为她们属于同一个品类,都属于苹果,如果在添加一个IPhone2019产品,也只需要把IPhone2019加入到你的苹果工厂里面就够了. 但是如果你程序里面还需要知道华为mate10或者小米8的尺寸.这时候你怎么来创建这些对象呢?这时候工厂模式明显已经不适用了,因为工厂模式是对象都实现了同一个接口,这时候就可以使用抽象工厂模式了. 一.什么是抽象工

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

简单工厂模式.抽象工厂模式.工厂方法模式,这三种工厂模式都属于设计模式中的创建型模式,它们在形式和特点上也多少有些相似,其最终目的都是帮我们将对象的实例化部分取出来,进而优化系统架构,增强系统的扩展性,也就是说更好的体现开放封闭原则. 简单工厂模式: 概念: 简单工厂模式是类的创建模式,又叫做静态工厂方法模式,是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例,涉及到工厂角色.抽象产品角色以及具体产品角色. 结构图: 分析: 一: 简单工厂类是整个模式的关键所在,包含了必要的逻辑判断,根据

人人都能看懂的工厂方法模式和抽象工厂模式的区别

设计模式中的工厂方法模式和抽象工厂模式一直不知不觉地使用在程序设计中,但是就是经常只有实践没有进行理论指导,所以感觉有一点半路子出家而没有系统学习过的不踏实的感觉.现在总结了一下之前项目中使用过的抽象工厂模式,加强对创建型模式中工厂模式的理解. 先举个栗子感性的理解工厂方法模式和抽象工厂模式这两者的区别. 有一个富商,在深圳开了三个手机厂,分别代工苹果手机,三星手机,华为手机.富商经常视察这3个厂,在苹果手机厂就说"大家要做好苹果手机",在三星厂就说"大家要做好三星手机&qu