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

3.抽象工厂模式

3.1 概述

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

(无需指定它们具体的类)

类型:创建型

适用场景

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

优点

  • 具体产品在应用层代码隔离,无需关心创建细节
  • 将一个系列的产品族一起创建

缺点

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

一些概念:

产品等级结构和产品族

在这里插入图片描述

比如 美的有生产 电磁炉、微波炉和空调(对应一排中的正方形、圆形和椭圆形),它们同一排颜色相同的是一个产品族;同理第二排理解为海尔的对应的各类电器…也是一个产品族。

在一列中比如第一列,表示不同厂家的电磁炉,它们构成一个相同的产品等级。

在这里插入图片描述

工厂方法针对的是产品等级结构;抽象工厂针对的是产品族,我们在美的的产品族(一个具体工厂)中做取电磁炉操作,就肯定是美的的电磁炉。

3.2 代码理解

场景:

原有需求:教学网站有不同种类的教学视频,Java、Python等,想新增什么教学视频时,从把想要的类型传 给 视频工厂,然后生产出视频。

新增需求:教学网站对不同种类课程需要加入手记,Java视频要配套Java手记;Python视频要配套Python手记才是一门完整的课程。

如果使用工厂方法模式的话,需要创建 手记类、各类课程的手记类、手记工厂类、各类手记工厂类等,可能出现类爆炸的状况。

此时

  • Python视频和Python手记属于Python产品族(才算是完整的Python课程);Java视频和Java手记属于Java产品族(才算是完整的Java课程);
  • Python视频和Java视频属于教学视频产品等级;Python手记和Java手记属于教学手记产品等级。

coding

新建Article手记抽象类:

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:30
 * @Description: 手记抽象类
 */
public abstract class Article {
    /**
     * 生产方法
     */
    public abstract void produce();
}

新建Video视频抽象类:

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:30
 * @Description: 视频类
 */
public abstract class Video {
    /**
     * 生产方法
     */
    public abstract void produce();
}

Java和Python的视频和手记实现类

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:57
 * @Description: python手记类
 */
public class PythonArticle extends Article{
    /**
     * 生产Python手记方法
     */
    public void produce() {
        System.out.println("生产Python手记方法");
    }
}
package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:55
 * @Description: python视频类
 */
public class PythonVideo extends Video{
    /**
     * 生产python视频方法
     */
    public void produce() {
        System.out.println("生产python视频");
    }
}
package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:56
 * @Description: Java手记类
 */
public class JavaArticle extends Article{
    /**
     * 生产Java手记方法
     */
    public void produce() {
        System.out.println("生产Java手记");
    }
}
package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:54
 * @Description:  Java视频类
 */
public class JavaVideo extends Video {
    /**
     * 生产Java视频方法
     */
    public void produce() {
        System.out.println("生产Java视频");
    }
}

课程工厂接口CourseFactory

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:29
 * @Description: 课程工厂接口
 */
public interface CourseFactory {
    /**
     * 获取教学视频
     * @return
     */
    Video getVideo();

    /**
     * 获取教学手记
     * @return
     */
    Article getArticle();
}

JavaCourseFactoryJava课程工厂类

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 13:51
 * @Description: Java课程工厂类
 */
public class JavaCourseFactory implements CourseFactory{
    /**
     * 获取Java教学视频
     *
     * @return
     */
    public Video getVideo() {
        return new JavaVideo();
    }

    /**
     * 获取Java教学手记
     *
     * @return
     */
    public Article getArticle() {
        return new JavaArticle();
    }
}

PythonCourseFactorypython课程工厂

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 14:01
 * @Description: python课程工厂
 */
public class PythonCourseFactory implements CourseFactory {
    /**
     * 获取Python教学视频
     *
     * @return
     */
    public Video getVideo() {
        return new PythonVideo();
    }

    /**
     * 获取Python教学手记
     *
     * @return
     */
    public Article getArticle() {
        return new PythonArticle();
    }
}

此时类图

在这里插入图片描述

应用层Client

package com.gangbb.creational.abstractfactory;

/**
 * @author Gangbb
 * @date 2021/3/29 14:10
 * @Description:
 */
public class Client {
    public static void main(String[] args) {
        CourseFactory courseFactory = new JavaCourseFactory();
        Video video = courseFactory.getVideo();
        Article article = courseFactory.getArticle();
        video.produce();
        article.produce();
    }

}

只需要从课程工厂调用生成方法即可,无需关注内部的生成过程。想要Java视频在Java工厂中获取的肯定就是Java视频。

新增产品族容易,新增产品等级要做较大更改,这也是抽象工厂的弊端。

3.3 开源框架源码使用分析

3.3.1 JDK数据库连接接口抽象工厂示例

java.sql.Connection

3.3.2 Mybatis中SqlSessionFactory

org.apache.ibatis.session.SqlSessionFactory

image-20210330074049760

可以看到这里面的类有返回SqlSessionConfiguration,所以只要通过SqlSessionFactory获取的这两种类型肯定属于同一个产品族,可能是mysqlSqlSessionFactory

也可能是SQL serverSqlSessionFactory,获取的结果肯定是同一产品族。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值