工厂模式一般指的是简单工厂模式、工厂方法模式、抽象工厂模式,这是三种工厂模式的最后一篇,其他两种的文章链接如下:
设计模式之简单工厂模式-CSDN博客
设计模式之工厂方法模式-CSDN博客
建议三种模式放在一起对比学习,更能领会其中的奥秘。看懂UML类图,更是奥秘中的奥秘哦,在UML类图中不同的箭头和线条,代表的意义是不同的,发现有很多人都画错了,这里简单的梳理了一下,如果需要可以移步这里:设计模式之基础:UML类图怎么看?_uml图怎么看-CSDN博客
抽象工厂模式是一种创建型的工厂模式,它提供了一个接口,使客户端可以在不指定具体产品的情况下创建多个产品组中的产品对象。当存在多个抽象角色时,抽象工厂模式可以用来创建一个工厂,该工厂能够根据需要生成相应类型的产品。这种模式将产品的生成和使用解耦,使得客户端无需了解具体产品的实现细节。
抽象工厂模式的核心思想是将工厂封装成了一个抽象接口,通过这个接口来创建产品。它允许客户端通过调用抽象工厂的接口来生成多个产品族中的产品对象,而无需知道每个产品族的实现细节。抽象工厂模式适用于存在多个产品族的情况,这些产品族具有不同的实现,但是客户端需要使用多个产品族中的产品。通过使用抽象工厂模式,客户端可以灵活地使用不同的产品族,而无需对代码进行大量修改。
抽象工厂模式和工厂方法模式都是设计模式中的对象创建型模式,主要用于封装对象的创建过程,以减少代码耦合。两种模式之间存在以下区别:
总之,抽象工厂模式相对于工厂方法模式,更适用于创建一系列相关或相互依赖的对象,以及对产品进行分类和组织的情况。
在抽象工厂模式中,存在四种角色:
还以女娲造人的传说举一个例子:刚开始造人,女娲觉得还挺有意思的,造的时间长了,都是黄皮肤的中国人,显得很单调,没啥意思了,于是拓展了一下业务,开始造黑色皮肤的非洲人了,用抽象工厂模式来演示这个过程会是什么样呢?
UML类图如下:
伪代码示例如下:
public interface Human {
/**
* 人类会吃东西
*/
void eat();
/**
* 人类会喝东西
*/
void drink();
}
public class YellowMan implements Human {
@Override
public void eat() {
System.out.println("黄色皮肤的中国男人在吃东西");
}
@Override
public void drink() {
System.out.println("黄色皮肤的中国男人在喝水");
}
}
public class YelloWoman implements Human {
@Override
public void eat() {
System.out.println("黄色皮肤的中国女人在吃东西");
}
@Override
public void drink() {
System.out.println("黄色皮肤的中国女人在喝水");
}
}
public interface HumanFactory {
Human createMan();
Human createWoman();
}
public class YelloHumanFactory implements HumanFactory{
@Override
public Human createMan() {
return new YellowMan();
}
@Override
public Human createWoman() {
return new YelloWoman();
}
}
public class BlackHumanFactory implements HumanFactory{
@Override
public Human createMan() {
return new BlackMan();
}
@Override
public Human createWoman() {
return new BlackWoman();
}
}
public class Test {
public static void main(String[] args) {
HumanFactory yellowHumanFactory=new YelloHumanFactory();
Human man = yellowHumanFactory.createMan();
Human woman = yellowHumanFactory.createWoman();
man.eat();
man.drink();
woman.eat();
woman.drink();
HumanFactory blackHumanFactory=new BlackHumanFactory();
Human man1 = blackHumanFactory.createMan();
Human woman1 = blackHumanFactory.createWoman();
man1.eat();
man1.drink();
woman1.eat();
woman1.drink();
}
}
女娲这都造人业务都拓展到海外了,光能造黄种人、黑种人怎么行,还想造白种人怎么办呢?很简单:
1、实现Human接口,再实现一个白种男人、一个白种女人的类;
2、实现HumanFactory接口,再实现一个白种人的制造工厂;
public class WhiteMan implements Human {
@Override
public void eat() {
System.out.println("白种欧洲男人吃东西");
}
@Override
public void drink() {
System.out.println("白种欧洲男人在喝水");
}
}
public class WhiteWoman implements Human {
@Override
public void eat() {
System.out.println("白种欧洲女人在吃东西");
}
@Override
public void drink() {
System.out.println("白种欧洲女人在喝水");
}
}
public class WhiteHumanFactory implements HumanFactory{
@Override
public Human createMan() {
return new WhiteMan();
}
@Override
public Human createWoman() {
return new WhiteWoman();
}
}
public class Test {
public static void main(String[] args) {
HumanFactory whiteHumanFactory=new WhiteHumanFactory();
Human man2 = whiteHumanFactory.createMan();
Human woman2 = whiteHumanFactory.createWoman();
man2.eat();
man2.drink();
woman2.eat();
woman2.drink();
}
}
有一天女娲觉得光造些男人、女人太单调了,男人、女人之间老是干架,怎么调合一下呢?那就造一些可爱小朋友吧。这时就会发现,如果还使用抽象工厂模式,就会很尴尬:HumanFactory接口里只有造男人、造女人的抽象方法,如果再加一个造小朋友的接口,就要对HuanFactory接口及其实现类具体工厂修改,这就破坏了开闭原则。如果除了造黑人、白人、黄人外,还想造点绿巨人,其实倒还好,和增加造白人的逻辑一样。这就是在决定是否使用抽象工厂模式的秘密所在,如果要扩展的是一个产品族,比较简单且适用,如果想丰富某一产品族的某个产品系列,就比较麻烦了;
有没有发现这种方式非常好?完全符合开闭原则,无须对原有系统进行修改;下面就总结一下抽象工厂模式的实际应用场景有哪些?
抽象工厂模式是一种设计程序时的工程方法,前面也说过,方法是为了解决问题的,不是灵丹妙药,用上了就一定很好,是绝不能生搬硬套的,重在理解和灵活运用。
对于抽象工厂模式有以下优点:
抽象工厂模式也有一些缺点:
因此,在使用抽象工厂模式时,需要根据具体的情况来考虑其优缺点,并决定是否使用该模式。