设计模式三:抽象工厂模式

抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

在抽象工厂模式结构图中包含如下几个角色:

● AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

  ● ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

● AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。

● ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类,其典型代码如下所示:

abstract class AbstractFactory {
public abstract AbstractProductA createProductA(); //工厂方法一
public abstract AbstractProductB createProductB(); //工厂方法二
……
} 

具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族。对于每一个具体工厂类,其典型代码如下所示:

    class ConcreteFactory1 extends AbstractFactory {
        //工厂方法一
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }  

    //工厂方法二
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }  

    ……
    }  
    //在本实例中我们对代码进行了大量简化,实际使用时,界面组件的初始化代码较为复杂,还需要使用JDK中一些已有类,为了突出核心代码,在此只提供框架代码和演示输出。
    //按钮接口:抽象产品
    interface Button {
        public void display();
    }  

    //Spring按钮类:具体产品
    class SpringButton implements Button {
        public void display() {
            System.out.println("显示浅绿色按钮。");
        }
    }  

    //Summer按钮类:具体产品
    class SummerButton implements Button {
        public void display() {
            System.out.println("显示浅蓝色按钮。");
        }
    }  

    //文本框接口:抽象产品
    interface TextField {
        public void display();
    }  

    //Spring文本框类:具体产品
    class SpringTextField implements TextField {
        public void display() {
            System.out.println("显示绿色边框文本框。");
        }
    }  

    //Summer文本框类:具体产品
    class SummerTextField implements TextField {
        public void display() {
            System.out.println("显示蓝色边框文本框。");
        }
    }  

    //组合框接口:抽象产品
    interface ComboBox {
        public void display();
    }  

    //Spring组合框类:具体产品
    class SpringComboBox implements ComboBox {
        public void display() {
            System.out.println("显示绿色边框组合框。");
        }
    }  

    //Summer组合框类:具体产品
    class SummerComboBox implements ComboBox {
        public void display() {
            System.out.println("显示蓝色边框组合框。");
        }
    }  

    //界面皮肤工厂接口:抽象工厂
    interface SkinFactory {
        public Button createButton();
        public TextField createTextField();
        public ComboBox createComboBox();
    }  

    //Spring皮肤工厂:具体工厂
    class SpringSkinFactory implements SkinFactory {
        public Button createButton() {
            return new SpringButton();
        }  

        public TextField createTextField() {
            return new SpringTextField();
        }  

        public ComboBox createComboBox() {
            return new SpringComboBox();
        }
    }  

    //Summer皮肤工厂:具体工厂
    class SummerSkinFactory implements SkinFactory {
        public Button createButton() {
            return new SummerButton();
        }  

        public TextField createTextField() {
            return new SummerTextField();
        }  

        public ComboBox createComboBox() {
            return new SummerComboBox();
        }
    }  
    import javax.xml.parsers.*;
    import org.w3c.dom.*;
    import org.xml.sax.SAXException;
    import java.io.*;  

    public class XMLUtil {
    //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
        public static Object getBean() {
            try {
                //创建文档对象
                DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = dFactory.newDocumentBuilder();
                Document doc;
                doc = builder.parse(new File("config.xml"));   

                //获取包含类名的文本节点
                NodeList nl = doc.getElementsByTagName("className");
                Node classNode=nl.item(0).getFirstChild();
                String cName=classNode.getNodeValue();  

                //通过类名生成实例对象并将其返回
                Class c=Class.forName(cName);
                Object obj=c.newInstance();
                return obj;
            }
            catch(Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }  
    <?xml version="1.0"?>
    <config>
        <className>SpringSkinFactory</className>
    </config>  
    class Client {
        public static void main(String args[]) {
            //使用抽象层定义
            SkinFactory factory;
            Button bt;
            TextField tf;
            ComboBox cb;
            factory = (SkinFactory)XMLUtil.getBean();
            bt = factory.createButton();
            tf = factory.createTextField();
            cb = factory.createComboBox();
            bt.display();
            tf.display();
            cb.display();
        }
    }  

显示浅绿色按钮。

显示绿色边框文本框。

显示绿色边框组合框。

在抽象工厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦,抽象工厂模式的这种性质称为“开闭原则”的倾斜性。“开闭原则”要求系统对扩展开放,对修改封闭,通过扩展达到增强其功能的目的,对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:

(1)
增加产品族:对于增加新的产品族,抽象工厂模式很好地支持了“开闭原则”,只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改。

(2)
增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,违背了“开闭原则”。

正因为抽象工厂模式存在“开闭原则”的倾斜性,它以一种倾斜的方式来满足“开闭原则”,为增加新产品族提供方便,但不能为增加新产品结构提供这样的方便,因此要求设计人员在设计之初就能够全面考虑,不会在设计完成之后向系统中增加新的产品等级结构,也不会删除已有的产品等级结构,否则将会导致系统出现较大的修改,为后续维护工作带来诸多麻烦。

抽象工厂模式总结

1.
主要优点

抽象工厂模式的主要优点如下:

(1)
抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

(2)
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

(3)
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

       2.
主要缺点

抽象工厂模式的主要缺点如下:

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。

       3.
适用场景

在以下情况下可以考虑使用抽象工厂模式:

(1)
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。

(2)
系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。

(3)
属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束,如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。

(4)
产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

时间: 2024-11-05 22:51:57

设计模式三:抽象工厂模式的相关文章

设计模式三—抽象工厂模式

设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是园丁2的杰作 1.Fruit.java public interface Fruit { /* * 生长 * 收获 * 栽种 */ public void grow(); public void harvest(); public void plant(); } 2.Apple.java publi

设计模式之抽象工厂模式20170803

创建型设计模式之抽象工厂模式: 一.含义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类. 具体来说, 为一组具有相同约束(属性)的对象,提供一个接口,这个接口下有不同的实现,每个实现类对应一种类型的约束(一种具体的属性),同时提供该类型的约束(属性)下所有对象的创建方法 二.代码说明 1.主要有两个角色 1)一组互相影响的产品线(对象),也叫做产品族 2)抽象工厂类及其实现类 抽象工厂类:在N个产品族中,在抽象工厂类中就应该有N个创建方法 实现类:具体实现类是产品族的具体

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

1.定义 抽象工厂模式为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.类图 由于类太多就不上源码了~ 最佳实践: 在一个应用中,需要在三个不同平台(Windows.Linux.Android)上运行,通过抽象工厂模式屏蔽掉操作系统对应的影响三个不同操作系统上的软件功能.应用逻辑.UI都应该是非常类似的,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息. 设计模式之抽象工厂模式(Abstract Factory)

C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

原文:C#设计模式之三抽象工厂模式(AbstractFactory)[创建型] 一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简单工厂]模式所面对的问题,它的问题就是:如果我们增加新的产品,工厂类的方法就要修改本身的代码,增加产品越多,其逻辑越复杂,同时这样的修改也是不符合[开放关闭原则OCP],对修改代码关闭,对增加代码开放.为了解决[简单工厂

设计模式之抽象工厂模式

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需改变具体工厂即可使用不同的产品配置. 他使具体创建实例的过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离. 下面的代码还使用了反射与XML. 代码如下: using System; using System.Collections.Ge

大话设计模式_抽象工厂模式(Java代码)

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类. 简单描述:有多种抽象产品,并且每种抽象产品都有多个具体产品.一个抽象工厂,提供多个具体工厂,每个工厂则提供不同种类的具体产品. 大话设计模式中的截图: 例子代码: AbstractProductA类: 1 package com.longsheng.abstractfactory; 2 3 public abstract class AbstractProductA { 4 5 public abstract v

JAVA设计模式之抽象工厂模式

本文继续介绍23种设计模式系列之抽象工厂模式. 前面已经介绍过简单工厂模式和工厂方法模式,这里继续介绍第三种工厂模式-抽象工厂模式,还是以汽车的制造为例. 例子背景: 随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件.于是这个工厂开始生产空调和发动机,用来组装汽车.这时候工厂有两个系列的产品:空调和发动机.宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机. 概念: 抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象.比如

C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】

一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简单工厂]模式所面对的问题,它的问题就是:如果我们增加新的产品,工厂类的方法就要修改本身的代码,增加产品越多,其逻辑越复杂,同时这样的修改也是不符合[开放关闭原则OCP],对修改代码关闭,对增加代码开放.为了解决[简单工厂]的问题,我们引出了[工厂方法]模式,通过子类化工厂类,解决了工厂类责任的划分,

&lt;十一&gt;读&lt;&lt;大话设计模式&gt;&gt;之抽象工厂模式

学习设计模式有一段时间了,对设计模式有一个体会,就是没那么难,就是设计程序遵循一些原则,让代码可复用,在修改的时候不用涉及太多的类,扩展方便,抽象工厂模式名字听起来抽象,但理解起来一点也不抽象,用语言可能不好理解,我喜欢通过代码理解,然后成为自己的东西. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. <<大话设计模式>>以项目上线时想换另外一个数据库为例子展开的,假如我没原来用的是SqlServer,现在换成access,代码如下: 1.访问数

【设计模式】 抽象工厂模式 Abstract Factory Pattern

简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式相对于简单工厂和工厂方法模式来着更具抽象性. 一.抽象工厂模式演绎 我们先来看一个简单的需求: 甲方要开发一套办公自动化软件,其中有一个非常重要的功能就是要能够导入Word 文档和Excel 文档. 开发人员拿到需求后就开始编码了,  很快代码写完了: public class ImportTool