推荐:​​Java设计模式汇总​​

抽象工厂模式

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

现在看不明白没关系,坚持看到最后,并且把例子看懂,再来多体会几遍就能明白了。

类型
创建型。

产品族与产品等级结构

设计模式-抽象工厂模式(Abstract Factory Pattern)_python


比如说​​正方形代表视频​​​,​​圆形代表手记​​​,​​椭圆形代表源代码​​​,则视频、手记、源代码都是一个产品等级结构,对应的视频、手记、源代码就组成了一个产品族,如果说视频、手记、源代码组成了课程,则​​课程就是产品族​​,由Java视频、Java手记、Java源代码组成的Java课程就是一个具体的产品族,可以将一个产品等级结构看成一个产品(我是这样认为的),产品族是由多个产品组成的,像课程是产品族,而视频、手记、源代码是产品。

可以看出来,我们想要扩展产品族时,是十分困难的,比如说每门课程还需要增加一个资源仓库,我们就不得不修改原来的代码了,也就违背了开闭原则。而增加一个具体的产品族却是比较容易的,比如增加Python课程,只需要增加Python视频、Python手记、Python源代码等相关类即可,不需要修改原来的代码,符合开闭原则。

所以当产品族扩展比较频繁时,抽象工厂模式就不太适用了。

例子

CourseFactory接口,课程工厂,相当于一个产品族的抽象工厂。

package com.kaven.design.pattern.creational.abstractfactory;

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

Video类,一个产品等级结构(视频)。

package com.kaven.design.pattern.creational.abstractfactory;

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

Article类,一个产品等级结构(手记)。

package com.kaven.design.pattern.creational.abstractfactory;

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

JavaVideo类,Java课程这个产品族中的Java视频,继承对应的产品等级结构Video类。

package com.kaven.design.pattern.creational.abstractfactory;

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

PythonVideo类,Python课程这个产品族中的Python视频,继承对应的产品等级结构Video类。

package com.kaven.design.pattern.creational.abstractfactory;

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

JavaArticle类,Java课程这个产品族中的Java手记,继承对应的产品等级结构Article类。

package com.kaven.design.pattern.creational.abstractfactory;

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

PythonArticle类,Python课程这个产品族中的Python手记,继承对应的产品等级结构Article类。

package com.kaven.design.pattern.creational.abstractfactory;

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

JavaCourseFactory类,是一个具体的产品族工厂(Java课程),实现了产品族的抽象工厂CourseFactory接口。

package com.kaven.design.pattern.creational.abstractfactory;

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

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

PythonCourseFactory类,是一个具体的产品族工厂(Python课程),实现了产品族的抽象工厂CourseFactory接口。

package com.kaven.design.pattern.creational.abstractfactory;

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

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

应用层代码:

package com.kaven.design.pattern.creational.abstractfactory;

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课程手记!

上面的例子中,想要对产品族进行扩展是很麻烦,比如每门课程还需要增加代码 Code,我们不仅需要增加 Code抽象类、JavaCode类、PythonCode类,还需要修改CourseFactory接口、JavaCourseFactory类、PythonCourseFactory类的原有代码,不仅违背了开闭原则,当存在很多具体的产品族时,需要修改、测试的地方就会有很多,风险也随之增加。

适用场景

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

解决的问题
每个工厂只能创建一类产品,即工厂方法模式的弊端。

​​设计模式-工厂方法模式(Factory Method)​​

优点

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

缺点

  1. 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难。
  2. 增加了系统的抽象性和理解难度。

如果有说错的地方,请大家不吝赐教(记得留言哦~~~~)。