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


    抽象工厂模式(Abstract Factory Pattern)是一种比较常用的模式,其定义如下:

    Provide an interface for creating families of related or dependent objects without specifying their concrete classes。

    为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。


    举一个电脑产品的例子吧:

    IBM,Dell都是著名的计算机生产厂家,他们采用的主板、硬盘及CPU是不相同的,但是配件间、主板与CPU一定要相互兼容,例如下面例子中的微星MSIK7N2G配AMD的CPU;微星MSI865PE配Intel的CPU。

    如图中所示,ComputerFactory是抽象工厂,Dell和IBM是生产产品的工厂;CPU、HardDisk、MainBoard是抽象产品,CPU的型号又分许多种。

    uml关系图如下:

     

    具体实现见代码:

    首先,定义CPU的接口:

    public interface CPU {

    String getCPU();

    }

    定义AMD类,实现CPU接口:

    public class AMD implements CPU {

    @Override

    public String getCPU() {

    return  "Athlon XP 2008+";

    }

    }

    定义Intel类,实现CPU接口:

    public class Intel implements CPU{

    @Override

    public String getCPU() {

    return "奔腾4 3.2C";

    }

    }

    定义硬盘接口:

    public interface HardDisk {

    String getSize();

    }

    定义Maxtor类,实现硬盘接口:

    public class Maxtor implements HardDisk{

    @Override

    public String getSize() {

    // TODO Auto-generated method stub

    return "MaXLine Plus II 200G";

    }

    }

    定义WestDigit,实现硬盘接口:

    public class WestDigit implements HardDisk{

    @Override

    public String getSize() {

    return "WD2500JD 250G";

    }

    }

    定义主板的接口,包含参数为CPU的公共方法Attach():

    public interface MainBoard {

     void Attach(CPU cpu) throws Exception;

    }

    主板微星MSI865PE,支持IntelCPU

    public class MSI865PE implements MainBoard{

     

    @Override

    public void Attach(CPU cpu) throws Exception {

     if(cpu.getClass ().toString ().endsWith("Intel")){

                System.out.println("MSI865PE");

            }

             else{

                throw new Exception("主板MSI865PE只能配IntelCPU");

            }

    }

    }

    主板微星MSIK7N2G,支持AMDCPU

    public class MSIK7N2G implements MainBoard {

     

    @Override

    public void Attach(CPU cpu) throws Exception {

    if(cpu.getClass ().toString ().endsWith("AMD")){

                System.out.println("MSIK7N2G");

            }

             else{

                throw new Exception("主板MSIK7N2G只能配AMDCPU");

            }

    }

     

    }

    定义抽象电脑工厂类:

    public abstract class ComputerFactory {

    CPU cpu;

    HardDisk hd;

    MainBoard mb;

     

    public void show() {

    try {

    System.out.println(this.getClass().getName().toString() + ("生产的电脑配置"));

    System.out.println("CPU:" + cpu.getCPU());

    System.out.println("HardDisk:" + hd.getSize());

    System.out.print("MainBoard:");

    mb.Attach(cpu);

    } catch (Exception e) {

    System.err.println(e.getMessage());

    }

    }

    }

    抽象电脑工厂类派生类IBM,定义其返回的系列配件产品:

    public class IBM extends ComputerFactory {

     

    public IBM() {

    cpu = new Intel();

    hd = new WestDigit();

    mb = new MSI865PE();

    }

     

    }

    抽象电脑工厂类派生类Dell,定义其返回的系列配件产品:

    public class Dell extends ComputerFactory {

    public Dell(){

    cpu = new AMD();

            hd = new Maxtor();

            mb = new MSIK7N2G();

    }

    }

    客户程序调用:

    public class Client {

    public static void main(String[] args) {

    IBM ibm = new IBM();

    ibm.show();

    Dell dell = new Dell();

    dell.show();

    }

    }

    输出结果为:

    Computerworld.IBM生产的电脑配置

    CPU:奔腾4 3.2C

    HardDisk:WD2500JD 250G

    MainBoard:MSI865PE

    Computerworld.Dell生产的电脑配置

    CPU:Athlon XP 2800+

    HardDisk:MaXLine Plus II 200G

    MainBoard:MSIK7N2G

    抽象工厂模式的缺点

         抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产品C,也就是说有产品家族由原来的2个,增加到3 个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个方法createProductC(),然后,两个实现类都要修改,想 想看,这在项目中的话,还这么让人活!严重违反了开闭原则,而且我们一直说明抽象类和接口是一个契约,改变契约,所有与契约有关系的代码都要修改,这段代 码叫什么?叫“有毒代码”,——只要这段代码有关系,就可能产生侵害的危险!

    最佳实践

         一个模式在什么情况下才能够使用,是我刚开始比较困惑的地方,抽象工厂模式是一个简单的模式,使用的场景非常多,在软件产品开发过程中,涉及到不同操 作系统的时候,都可以考虑使用抽象工厂模式,例如一个应用,需要在三个不同平台上运行:Windows、Linux、Android(Google发布的 智能终端操作系统)上运行,你会怎么设计?分别设计三套不同的应用?非也非也,通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功 能、应用逻辑、UI都应该是非常类似,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。

    与工厂模式区别:
    工厂模式只有一个抽象产品类,而抽象工厂模式有多个。  
    工厂模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

     





  • 相关阅读:
    关于数据库的基础知识
    Oracle数据库的上机作业
    PHP表单处理
    EasyUI DataGrid结合ThinkPHP实现增删改查操作———初学者
    Redis crackit
    nodeppt安装后,phantomjs不能运行了 Bad argument
    redis命令
    eclipse编辑web.xml很慢
    客制化jasperreport导出html的过程
    dynamicreport, JFreeChart
  • 原文地址:https://www.cnblogs.com/ut2016-progam/p/5307914.html
Copyright © 2020-2023  润新知