【设计模式】抽象工厂模式

  |   0 评论   |   26 浏览

简介

抽象工厂也是比较常用的设计模式,提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类型,是属于创建型设计模式。封装了相同主题的工厂,在使用的时候使用抽象工厂提供的方法来创建对象,不需要关心是怎么获取对象的,将实现细节隐藏起来,使客户端使用变的简单。

适用场景

1、客户端不依赖于产品类实例如何被创建、实现等细节
2、强调一系列相关的产品对象一起使用创建对象需要大量重复的代码
3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现;

优点

1、具体产品在应用层代码隔离,无须关心创建细节
2、将一个系列的产品族统一到一起创建

缺点

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
2、增加了系统的抽象性和理解难度

产品族与产品等级结构

image.png
如上图很好的描述了什么是产品族、什么是产品等级结构?
抽象工厂是对产品族进行封装,在小米工厂里面生产的空调那肯定是小米空调,生产的冰箱也肯定是小米的冰箱,所以如下图:
image.png
而之前的工厂方法是对产品等级结构进行的封装。这个就是工厂方法和抽象工厂的区别。

示例代码

先来看下抽象工厂的类图:
image.png
跟工厂方法不同的是他是对产品族创建了工厂,该示例有华为和苹果两个工厂,他们分别可以生产手机和pad,像HuaweiFactory里面创建出来的都是华为的产品,接下来看看具体的类:
FoxconnFactory接口,定义了创建手机和pad的方法,是抽象工厂。

public interface FoxconnFactory {
    Mobile produceMobile();
    Pad producePad();
}

HuaweiFactory是FoxconnFactory的实现类

public class HuaweiFactory implements FoxconnFactory{
    public Mobile produceMobile() {
        return new HuaweiMobile();
    }
    public Pad producePad() {
        return new HuaweiPad();
    }
}

AppleFactory是FoxconnFactory的实现类

public class AppleFactory implements FoxconnFactory{
    public Mobile produceMobile() {
        return new AppleMobile();
    }
    public Pad producePad() {
        return new ApplePad();
    }
}

Mobile是手机的抽象类

public abstract class Mobile {
    public abstract void produce();
}

HuaweiMobile是Mobile的实现类

public class HuaweiMobile extends Mobile {
    @Override
    public void produce() {
        System.out.println("生产华为手机");
    }
}

AppleMobile是Mobile的实现类

public class AppleMobile extends Mobile{
    @Override
    public void produce() {
        System.out.println("生产苹果手机");
    }
}

Pad是pad的抽象类

public abstract class Pad {
    public abstract void produce();
}

HuaweiPad是Pad的实现类

public class HuaweiPad extends Pad {
    @Override
    public void produce() {
        System.out.println("生产华为pad");
    }
}

ApplePad是Pad的实现类

public class ApplePad extends Pad {
    @Override
    public void produce() {
        System.out.println("生产苹果pad");
    }
}

AbstractFactoryTest为测试类

public class AbstractFactoryTest {
    public static void main(String[] args) {
        FoxconnFactory appleFactory = new AppleFactory();
        Mobile appleMobile = appleFactory.produceMobile();
        appleMobile.produce();
        Pad applePad = appleFactory.producePad();
        applePad.produce();

        FoxconnFactory huaweiFactory = new HuaweiFactory();
        Mobile huaweiMobile = huaweiFactory.produceMobile();
        huaweiMobile.produce();
        Pad huaweiPad = huaweiFactory.producePad();
        huaweiPad.produce();
    }
}

如果新增一个产品族,如小米,那么新增一个小米的实现工厂,小米的手机实现类和pad实现类,这样对扩展是开放的,不用修改原先的代码。此时如果新增一个产品等级结构,如需要生产手表,那么需要在FoxconnFactory里面新增一个创建手表的方法,那么相应的工厂实现类都需要修改,这样就违背了开闭原则,所有在选择抽象工厂的时候,需要考虑你的产品等级结构是不是会经常调整?当然如果只是半年或者一年调整一次,那也是可以考虑使用抽象工厂的。
上面示例源码

源码分析

sql中应用

Connection是抽象工厂,ConnectionImpl创建出来的Statement和DatabaseMetaData是mysql的,OracleConnectionWrapper创建出来的Statement和DatabaseMetaData是oracle的。
image.png

mybatis中应用

image.png
如上类图,可以看出SqlSessionFactory是工厂接口,里面可以创建不同数据库的SqlSession和Configuration,DefaultSqlSessionFactory和SqlSessionManager是工厂的实现,SqlSession和Configuration是相应的产品接口,DefaultSqlSession和SqlSessionManager是产品的实现,不同的数据库可以创建不同类型的工厂。

也可以关注我的公众号:程序之声
图片
关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论