设计模式-抽象工厂

定义

抽象工厂提供了一个创建一系列相关或相互依赖对象的接口。
无需指定它们具体的类。
类型:创建型。

适用场景

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

抽象工厂-优点

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

抽象工厂-缺点

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

抽象工厂-产品等级结构和产品族

在这里插入图片描述
如上图所示,横坐标代表的是产品等级,例如空调、洗衣机、冰箱等,纵坐标代表的是产品族,如美的、海尔、海信等。那横着来看,第一行都是美的的产品,第二行都是海尔的产品,第三行都是海信的产品,每一行是同一品牌的不同产品。竖着来看,第一列都是空调,第二列都是冰箱,第三列都是洗衣机,每一列都是同一产品,不过品牌不同。可以简单理解为产品等级就是不同的产品,而产品族可以理解为一个工厂,生产一些列的产品。
在这里插入图片描述

代码示例

我们以制作课程为例,制作课程可能包括录制视频和制作手记两个产品。
抽象课程的工厂

public interface CourseFactory {
    Video getVideo();
    Article getArticle();
}

抽象视频产品

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

抽象文章产品

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

假如我们要制作java相关的课程,那我们只需新增java的课程工厂,
java课程工厂

public class JavaCourseFactory implements CourseFactory {
    @Override
    public Video getVideo() {
        return new JavaVideo();
    }

    @Override
    public Article getArticle() {
        return new JavaArticle();
    }
}

同时新增具体的java视频产品和具体的java手记产品
java视频产品

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Java课程视频");
    }
}

java手记产品

public class JavaArticle extends Article {
    @Override
    public void produce() {
        System.out.println("编写Java课程手记");
    }
}

如果后期我们又新增了python的课程,添加相应的工厂和具体的产品即可
python课程工厂

public class PythonCourseFactory implements CourseFactory {
    @Override
    public Video getVideo() {
        return new PythonVideo();
    }

    @Override
    public Article getArticle() {
        return new PythonArticle();
    }
}

python视频产品

public class PythonVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Python课程视频");
    }
}

python手记产品

public class PythonArticle extends Article {
    @Override
    public void produce() {
        System.out.println("编写Python课程手记");
    }
}

对于应用层而言,想获取某一产品族的产品,只需要知道产品族的工厂即可,而不需要关心具体的实现细节,代码如下

public class Test {
    public static void main(String[] args) {
        CourseFactory courseFactory = new JavaCourseFactory();
        Video video = courseFactory.getVideo();
        Article article = courseFactory.getArticle();
        video.produce();
        article.produce();
    }
}

后续新增不同的产品族,只需要新增相应的工厂和产品实例即可,可以灵活的扩展,满足开闭原则。

源码解析

例如java.sql.Connection接口,里面定义了获取Statement、PreparedStatement方法,Statement、PreparedStatement是两个抽象的产品,假如我们使用了mysql的数据库连接,那获取的Statement、PreparedStatement,也都是mysql这个产品族的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那如果我们引入的是oracle的数据库连接,那通过connection获取的Statement、PreparedStatement就属于oracle这个产品族。

总结

通过抽象工厂,定义了工厂和产品的接口契约,规范了接口的定义,更具有通用性和扩展性,使软件的架构更加清晰,但是也增加了系统的抽象性和理解难度,在日常工作中,需要按情况进行使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值