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

1.抽象工厂模式动机

        在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器设备工厂,它可以生产电视机、电冰箱、空调等设备,而不只是生成某种类型的电器。

        因此我们引入了一个新的设计模式:抽象工厂模式。

        抽象工厂模式定义:抽象工厂模式是工厂方法模式的泛化版,工厂方法模式是一种特殊的抽象工厂模式。在工厂方法模式中,每一个具体工厂只能生产一种具体产品,而在抽象工厂方法模式中,每一个具体工厂可以生产多个具体产品。在实际的软件开发中,抽象工厂模式使用频率较高,

        下面将深化抽象工厂模式的学习。

2.抽象工厂模式结构

 2.1模式类图

抽象工厂模式包含如下角色:

1.AbstractProduct(抽象产品)

        抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。

2.ConcreteProduct(具体产品)

        具体产品定义具体工厂生产的具体产品对象,实现抽象接口产品接口中定义的业务方法,

3.AbstractFactory(抽象工厂)

        抽象工厂用于声明生成抽象产品的方法,在一个抽象工厂中可以定义一组方法,每一个方法对应一个产品等级结构。

4.ConcreteFactory(具体工厂)

        具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品成了一个产品族,每一个产品都位于某个产品等姐结构中。

3.抽象工厂模式实例与解析

题目:电脑配件生产工厂生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据下面的“产品等级结构-产品族”示意图,使用抽象工厂模式实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现。

3.1结构类图

3.2实例代码及解释

1.抽象产品类 CPUCPU类

public interface CPU {

    public void paly();

}

        CPU作为抽象产品类,它可以是一个接口也可以是一个抽象类其中包含了所有产品都具有的业务方法play().

2.具体产品类MacCPUMacCPU类

public class MacCPU implements CPU{

    @Override

    public void paly() {

        System.out.println("MacCPU正在运行中。。。");

    }

}

        MacCPU是抽象产品CPU接口的子类,它是一种具体产品实现了在CPU接口中定义的业务方法paly()。

3.具体产品类PcCPUPcCPU类

public class PcCPU implements CPU{

    @Override

    public void paly() {

        System.out.println("PcCPU正在运行中。。。");

    }

}

        PcCPU是抽象产品CPU的另一个子类。

4.抽象产品类 RAMRAM类

public interface RAM {

    public void work();

}

        RAM作为抽象产品类,它可以是一个接口也可以是一个抽象类其中包含了所有产品都具有的业务方法work().

5.具体产品类MacRAMMacRAM类 

public class MacRAM implements RAM{

    @Override

    public void work() {

        System.out.println("MacRAM正在运行中。。。");

    }

}

        MacRAM是抽象产品RAM接口的子类,它是一种具体产品实现了在CPU接口中定义的业务方法work()。

6.具体产品类PcRAMPcRAM类

public class PcRAMimplements RAM{

    @Override

    public void work() {

        System.out.println("PcRAM正在运行中。。。");

    }

}

        PcRAM是抽象产品RAM的另一个子类。

7.抽象工厂类ComputerFactory(电脑工厂类

public interface ComputerFactory {

    public CPU produceCPU();

    public RAM produceRAM();

}

        ComputerFactory类是抽象工厂类,其中定义了抽象工厂方法针对每一个产品族的产品都提供了一个对应的工厂方法

8.具体工厂类MacFactoryMac工厂类

package abstract_factory_pattern;



public class MacFactory implements ComputerFactory{

    @Override

    public CPU produceCPU() {

        System.out.println("已生产MacCPU");

        return new MacCPU();

    }



    @Override

    public RAM produceRAM() {

        System.out.println("已生产MacRAM");

        return new MacRAM();

    }

}

        MacFactory是ComputerFactory的一个子类,实现了在ComputerFactory中定义的工厂方法用于创建具体产品对象MacFactory所生产的具体产品构成了一个产品族

9.具体工厂类PcFactoryPc工厂类

package abstract_factory_pattern;



public class PcFactory implements ComputerFactory{

    @Override

    public CPU produceCPU() {

        System.out.println("已生产PcCPU");

        return new PcCPU();

    }



    @Override

    public RAM produceRAM() {

        System.out.println("已生产PcRAM");

        return new PcRAM();

    }

}

        PcFactory是ComputerFactory的另一个子类实现了在ComputerFactory中定义的工厂方法用于创建具体产品对象PcFactory所生产的具体产品构成了一个产品族

        MacFactory、PcFactory和ComputerFactory构成了一个工厂等级结构

3.3辅助代码

  1. XML操作工具类XMLUtil
package abstract_factory_pattern;

import org.w3c.dom.*;

import javax.xml.parsers.*;

import java.io.*;



public class XMLUtil {

    public static Object getBean(){

        try {

            //创建DOM文档对象

            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;

        }

    }

}

2.配置文件config.xml





abstract_factory_pattern.MacFactory

3.客户端测试类Client

package abstract_factory_pattern;

public class Client {

    public static void main(String[] args) {

        ComputerFactory factory;

        CPU cpu;

        RAM ram;

        factory = (ComputerFactory) XMLUtil.getBean();

        cpu = factory.produceCPU();

        cpu.paly();

        ram = factory.produceRAM();

        ram.work();

    }

}

3.4结果及分析

   如果在配置文件中将节点中的内容设置为:abstract_factory_pattern.MacFactory包名.类名则会输出结果如下

  如果在配置文件中将节点中的内容设置为:abstract_factory_pattern.PcFactory,则会输出结果如下

4.抽象工厂模式总结

4.1抽象工厂模式的优点

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

(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。

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

4.2抽象工厂模式的缺点

        在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。

你可能感兴趣的:(设计模式,java,抽象工厂模式)