第三章 设计模式--工厂模式 之抽象工厂模式

本文深入解析抽象工厂模式的定义、适用场景、优缺点,并通过代码示例展示了如何创建一系列相关或相互依赖的对象,同时讨论了产品族和产品等级结构的概念。

抽象工厂模式

定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。

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

优点:
1、代码隔离,我虚关心具体实现细节。
2、将一系列的产品族统一到一起创建。

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

下面来一下,抽象工厂中的 产品等级结构和产品族

在这里插入图片描述
这个图主要描述了,产品族和产品等级结构的联系和区别:

产品族:主要表示一个类中包含多个方法或属性。
产品等级结构:主要表示多个类中相同的 方法或属性。

我们可以举例来看,例如:

联想公司的产品可以生产联想电脑,也可以生产联想软件,也可以生产联想 洗衣机。
惠普公司的产品可以生产惠普电脑,也可以生产惠普软件,也可以生产惠普 洗衣机。
在上述中 联想公司的 3 个产品(电脑、软件、洗衣机)就是产品族;联想公司的电脑、惠普公司的电脑 属于一类产品,属于同一个产品等级结构。

下面我们用代码来模拟 抽象工厂模式:

1、抽象工厂及其实现的2个子类:

抽象工厂类:
/**
 * @program: adpn-pattern->ComputerFactory
        * @description: 生产电脑工厂类
        * @author: Jstar
        * @create: 2019-11-17 11:34
        **/
public abstract  class ComputerFactory {
    public abstract Software getSoftware();
    public abstract Computer getComputer();
}
联想工厂类:
public class ThinkpadComputerFactory extends ComputerFactory {
    @Override
    public Software getSoftware() {
        return new ThinkpadSoftware();
    }
    @Override
    public Computer getComputer() {
        return new ThinkpadComputer();
    }
}
惠普工厂类:
public class HpComputerFactory extends ComputerFactory {
    @Override
    public Software getSoftware() {
        return new HpSoftware();
    }
    @Override
    public Computer getComputer() {
        return new HpComputer();
    }
}

2、电脑抽象类及其实现的2个子类:

电脑抽象类:
/**
 * @program: adpn-pattern->Computer
 * @description: 电脑类
 * @author: Jstar
 * @create: 2019-11-17 11:18
 **/
public abstract class Computer {
    public abstract void process();
}
联想电脑:
public class ThinkpadComputer extends Computer {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产联想电脑");
    }
}
惠普电脑:
public class HpComputer extends Computer {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产惠普电脑");
    }
}

3、软件 抽象类及其实现的2个子类:

软件抽象类:
/**
 * @program: adpn-pattern->Software
 * @description:
 * @author: Jstar
 * @create: 2019-11-17 20:58
 **/
public abstract class Software {
    public abstract void process();
}
联想软件:
public class ThinkpadSoftware extends Software {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产联想--软件");
    }
}
惠普软件:
public class HpSoftware extends Software {
    @Override
    public void process() {
        System.out.println("这里可写业务代码,但我们模拟--生产惠普--软件");
    }
}

4、下面我们来模拟一下客户端调用:

/**
 * @program: adpn-pattern->Test
 * @description: 测试类
 * @author: Jstar
 * @create: 2019-11-17 11:42
 **/
public class Test {
    public static void main(String[] args) {
        ComputerFactory thinkpadComputerFactory = new ThinkpadComputerFactory();
        Computer computer = thinkpadComputerFactory.getComputer();
        Software software = thinkpadComputerFactory.getSoftware();
        computer.process();
        software.process();
        System.out.println("------两种产品族-----分割线");
        HpComputerFactory hpComputerFactory = new HpComputerFactory();
        Computer computer1 = hpComputerFactory.getComputer();
        Software software1 = hpComputerFactory.getSoftware();
        computer1.process();
        software1.process();
    }
}

5、运行测试类的结果:

这里可写业务代码,但我们模拟--生产联想电脑
这里可写业务代码,但我们模拟--生产联想--软件
------两种产品族-----分割线
这里可写业务代码,但我们模拟--生产惠普电脑
这里可写业务代码,但我们模拟--生产惠普--软件

从结果看,两个工厂产品族互不影响,各自完成生产电脑和生产软件的方法,没有出现交叉的问题。

我们来看一下上述代码的UML图调用关系:
在这里插入图片描述

功能扩展:

假如我们想扩展一个苹果的厂商生产产品,即扩展一个产品族。我们只需在原来的基础上做横向扩展即可,即添加苹果工厂的实现类,苹果生产电脑的类,苹果生产软件的类,在客户端做调用即可, 不影响之前的功能,满足开闭原则。
但是如果我们想扩展,一个生产洗衣机的功能,这个在上述的模拟中就很难实现了,需要在工厂接口中添加 获取洗衣机的方法,且该接口的每个实现都得进行改动,有很大的侵入性,违背了 开闭原则。
所以,一类的模式有它的优点,也有它存在的不足,使用时要根据实际的业务场景进行使用。

抽象工厂在jdk源码中的使用:

1、java.sql.Connection 是数据库的连接接口,我们从接口中可以看到

在这里插入图片描述
从图中我们可以看到,不论方法是 返回 Statement 还是 PreparedStatement ,这两者都属于一个产品族。

2、再来看一下,mybatis 中的 SqlSessionFactory ,是如何创建 SqlSession的。

在这里插入图片描述
可以看到抽象工厂中也是返回了两种产品,属于一个产品族。
在这里插入图片描述
可以看到,返回的是 抽象的 SqlSession ,但具体的实现是 DefaultSqlSession ,这是典型的抽象工厂模式。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值