声明:
本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。
本博客已标明出处,如有侵权请告知,马上删除。
1. 抽象工厂讲解
- 定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口
- 无须指定它们具体的类
- 类型:创建型
- 适用场景
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
- 优点
- 具体产品在应用层代码隔离,无须关心创建细节
- 将一个系列的产品族统一到一起创建
- 缺点
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
- 增加了系统的抽象性和理解难度
产品等级结构与产品族的区别:
工厂方法模式针对的就是产品等级结构,而抽象方法模式针对的就是产品族。
从理论上来说:当一个工厂可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,那这个时候,抽象工厂模式要比工厂方法模式要更为简单,更有效率。
2. 抽象工厂 Coding
业务场景和前一章的工厂方法一样,现在提出了新的要求:每一个课程不仅仅要有视频,还要有对应的手记。
如果用工厂方法的方式来进行扩展的话 ,这个时候,既要有 Java 的手记类,Python 的手记类,还有手记的抽象类,手记的工厂,Java 的手记的工厂,Python 的手记的工厂,FE 的手记的工厂,这个时候,就很容易出现类爆炸的现象。
现在我们使用抽象工厂,将同一产品族产品同一到一起创建:
-
创建课程和手记抽象类
public abstract class Video { public abstract void produce(); }
public abstract class Article { public abstract void produce(); }
-
创建课程工厂接口
public interface CourseFactory { Video getVideo(); Article getArticle(); }
-
创建 Java 课程类和手记类
public class JavaVideo extends Video { @Override public void produce() { System.out.println("录制Java课程视频"); } }
public class JavaArticle extends Article { @Override public void produce() { System.out.println("编写Java课程手记"); } }
-
创建 Java 产品族的课程工厂
public class JavaCourseFactory implements CourseFactory { @Override public Video getVideo() { return new JavaVideo(); } @Override public Article getArticle() { return new JavaArticle(); } }
-
测试类
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课程视频 编写Java课程手记
-
现在拓展一个 Python 的产品族
public class PythonVedio extends Video { @Override public void produce() { System.out.println("录制Python课程视频"); } }
public class PythonArticle extends Article { @Override public void produce() { System.out.println("编写Python课程手记"); } }
public class PythonCourseFactory implements CourseFactory { @Override public Video getVideo() { return new PythonVedio(); } @Override public Article getArticle() { return new PythonArticle(); } }
现在类图如下所示:
抽象工厂和工厂方法的对比:
- 优点:抽象工厂模式将一个系列的产品族统一到一起创建,比工厂方法模式要更为简单,更有效率。
- 缺点:产品族中扩展新的产品困难,需要修改抽象工厂的接口。比如现在要新增一个源码产品,那么不仅要修改 CourseFactory 接口,还要修改所有的实现类,这样就违反了开闭原则。