推荐:Java设计模式汇总
抽象工厂模式
定义
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类。
现在看不明白没关系,坚持看到最后,并且把例子看懂,再来多体会几遍就能明白了。
类型
创建型。
产品族与产品等级结构
比如说正方形代表视频
,圆形代表手记
,椭圆形代表源代码
,则视频、手记、源代码都是一个产品等级结构,对应的视频、手记、源代码就组成了一个产品族,如果说视频、手记、源代码组成了课程,则课程就是产品族
,由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();
}
}
结果:
上面的例子中,想要对产品族进行扩展是很麻烦,比如每门课程还需要增加代码 Code,我们不仅需要增加 Code抽象类、JavaCode类、PythonCode类,还需要修改CourseFactory接口、JavaCourseFactory类、PythonCourseFactory类的原有代码,不仅违背了开闭原则,当存在很多具体的产品族时,需要修改、测试的地方就会有很多,风险也随之增加。
适用场景
- 应用层不依赖于产品类实例如何被创建、实现等细节。
- 强调一系列相关的产品对象(属于同一产品族)一起被创建。
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得应用层不依赖于具体的实现。
解决的问题
每个工厂只能创建一类产品,即工厂方法模式的弊端。
设计模式-工厂方法模式(Factory Method)
优点
- 具体产品在应用层中代码隔离,无需关心创建的细节。
- 将一个系列的产品统一到一起创建。
缺点
- 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难。
- 增加了系统的抽象性和理解难度。
如果有说错的地方,请大家不吝赐教(记得留言哦~~~~)。