抽象工厂模式

抽象工厂模式

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

首先给出抽象工厂模式的通用类图:

                                                 

在我第一次看到这个类图的时候,“我靠,这和工厂方法模式有啥区别,多了一个场景类Client?”。这个类图是《设计模式之禅》中的一张图,看完之后明白了这张图。

抽象工厂模式简单理解:抽象工厂模式的工厂接口定义了“一组方法”,而工厂方法模式的工厂接口定义了“一个”方法。(作为初学者,这样理解比较简单)

抽象工厂接口中的“一组”方法,用来创建定义中说的“一组”相关或相互依赖的对象

怎么理解相关和相互依赖呢?也可以简单的理解外在代码层面有关或无关的对象。代码层面无关,不代表它两真的无关。

举个栗子

假设有一个程序,其中包含了对文件的操作,假设当前的操作系统是windows,现在要将这个程序迁移到linux。如果使用抽象工厂模式,只需要修改工厂对象即可(如果写在配置文件中,只需要把工厂类的类名修改即可),如下图:

                

package AbstractFactory;

interface IOFactory {
    InputStream getInputStream();
    OutputStream getOutputStream();
}

interface InputStream {
    void write();
}

interface OutputStream {
    void print();
}

class WindowsIOFactory implements IOFactory {

    @Override
    public InputStream getInputStream() {
        return new WindowsInputStream();
    }

    @Override
    public OutputStream getOutputStream() {
        return new WindowsOutputStream();
    }

}

class WindowsInputStream implements InputStream {
    @Override
    public void write() {
        System.out.println("Windows输入流");
    }
}

class WindowsOutputStream implements OutputStream {
    @Override
    public void print() {
        System.out.println("Windows输出流");
    }
}


public class Client {
    IOFactory factory = new WindowsIOFactory();
    InputStream input = factory.getInputStream();
    OutputStream output = factory.getOutputStream();
}

现在,要将Windows的IO流变为Linux的IO流;只需要按照上面的类图,实现一个Linux的工厂,用来创建Linxu的IO流,然后在实现Linux的产品(Linux的IO流),对于场景类,仅需要修改创建的工厂就。

这样就完美了吗?如果上层的依赖很多,一句一句的改是有风险的,所以,可以再次进行改进,客户端可以不关心IOFactory的具体类型,想到了什么?还可以用工厂方法模式来创建这个工厂,我们试着用简单工厂模式进行解耦。

       

假设有这样的配置文件

<bean>
    <interface>IOFactory</interface>
    <class>WindowsIOFactory</class>
</bean>

简单工厂模式就可以读取这个文件,来创建对应的工厂对象,所以,对于上面的迁移问题,修改这里的具体类就可以。

用伪代码实现一下:

public class CreatFactory {
    public static getFactory(){
        //读取配置文件
        //找到IOFactory接口对应的具体类的类名className
        //通过反射创建对象
        IOFactory factory = Class.forName(className).newInstance();
            //现在newInstance()已经不推荐使用了,伪代码不必要纠结
        return factory;
    }
}

如果场景类使用这个简单工厂模式,则不用关心具体的实现类,实现解耦,更换操作系统时代码都不用修改了。

public class Client {
    IOFactory factory = CreatFactory.getFactory();
    InputStream input = factory.getInputStream();
    OutputStream output = factory.getOutputStream();
}

回过头来看定义

额,扯远了,再回来看抽象工厂模式。

通过上面的例子,应该理解了“创建一组相关对象”,上面例子中的相关对象就是输入流对象和输出流对象,输入流和输出流的相关关系就是它们的对应的操作系统相同。对于不同的操作系统,就会有不同的工厂来创建相应的一组对象。

产品族和产品等级

                        

如图,同一个工厂生产的一组对象构成一个产品族;不同工厂生产的同类产品构成一个产品等级。上面的例子中,Windows平台下的WindowsInputStream对象和WindowsOutputStream构成一个产品族。

抽象工厂模式的优缺点

优点

  1. 封装性和隔离性。和工厂方法模式一样,上层模块只关心接口,不关心对象创建细节,也不关心对象的具体类型。
  2. 对产品族进行扩展很简单,实现新的工厂和新的产品即可(就像上面的那个例子)

缺点

产品等级扩展困难,扩展时破坏开闭原则。

使用场景

  1. 产品族多余一个,系统每次只使用一个。
  2. 属于同一个产品族的产品一起使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值