长大后想做什么?做回小孩!

0%

工厂模式

工厂模式属于创建型模式,它提供了一种更加优雅的创建对象的方式,也是最常见的设计模式之一!

用户需要到 ”交通工具生产车间“ 去获取一种交通工具,用户可能要 “汽车“ 或 ”自行车“ 甚至是 “飞机”等。。。作为生产车间,只需要告诉用户一个获取其想要的交通工具的方法即可,至于交通工具是如何生产出来,用户并不需要去关心。

正文

简单工厂模式(静态工厂方法模式)

用户可以使用工厂类提供的 get 静态方法并传入的不同参数,从而获取不同的实例,这些被创建的实例通常都具有共同的父类:

dzEFA0.png

实现起来也很比较容易,共同父类:

1
2
3
public abstract class Transportation {
public abstract void identity();
}

汽车、自行车、飞机等等实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Car extends Transportation {
@Override
public void identity() {
System.out.println("i'm car!");
}
}
public class Bicycle extends Transportation {
@Override
public void identity() {
System.out.println("i'm Bicycle!");
}
}
public class Plane extends Transportation {
@Override
public void identity() {
System.out.println("i'm Plane!");
}
}

工厂类:

1
2
3
4
5
6
7
8
9
10
11
12
public class TransportationFactory {
public static Transportation getTransprotation(String type) {
if ("car".equalsIgnoreCase(type)) {
return new Car();
} else if ("bicycle".equalsIgnoreCase(type)) {
return new Bicycle();
} else if ("plane".equalsIgnoreCase(type)) {
return new Plane();
}
return null;
}
}

测试:

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
Transportation car = TransportationFactory.getTransprotation("car");
if (car != null) {
car.identity();//i'm car!
}
Transportation plane = TransportationFactory.getTransprotation("plane");
if (plane != null) {
plane.identity();//i'm Plane!
}
}

这种方式简单方便,JDK 中也有很多应用,例如:DateFormat 提供了 get(LocaleProviderAdapter adapter, int timeStyle, int dateStyle, Locale loc) 去根据参数去创建不同的实例。。

但是这种方式有一个致命的缺点就是不够灵活!每新增一种交通工具,都需要修改工厂类的方法,这就违背了程序设计中的开闭原则

工厂模式

可以看作是一种简单工厂模式的再抽象,在简单工厂模式中每个交通工具都有一个共同父类,但是都通过一个统一的大工厂去创建;

而工厂模式中,在之前简单工厂模式的基础上,工厂类本身也需要分成不同的子工厂类,每种子工厂类去创建其具体的交通工具,且都共同继承自的同一个大工厂父类:

dzAx1g.png

按照惯例,找一个 JDK 中的例子:Collection 接口看作是一个工厂抽象类,其中有抽象方法 iterator() 用于创建迭代器,很多类都实现了这个接口,例如 ArrayList 实现了接口作为子工厂,会 new 一个 Itr 类对象,这个 Itr 类作为具体的”产品”也同样有一个迭代器父类 Iterator;除此之外 LinkedList 也可以 new 一个具体产品 ListItr 类对象,这个类的父类也同样是 Iterator。等等。。。

dzkgJS.png

概括来说,就是定义一个用于创建对象的接口,让其子类决定实例化哪个类。工厂模式优点是将一个类的实例化延迟到其子类。

将简单工厂的例子改造为工厂模式后,类图:

dzkyIf.png

抽象工厂模式

抽象工厂模式可以看作是工厂模式的又一次扩展,直接看将工厂模式改造成抽象工厂模式后的类图:

dzkRzQ.png

在之前的工厂模式,一个工厂父类(或工厂接口)的所有子工厂都是生产同一大类的子类,那么我们只要给这个工厂父类(或接口)增加可以生产其大类抽象方法,并让其所有的子工厂都各自实现这个抽象方法,就可以做到让一个工厂大类可以生产多个不同大类的产品。(可能比较拗口,多想几遍,很好理解):

dzAMY8.png

虽然进一步扩展了工厂模式,但是每次增加新的产品大类的时候,都要给工厂父类(或接口)增加新抽象方法,并让所有的子工厂都去各自实现,就又像文章开头提到的简单工厂模式一样:违反了程序设计中的开闭原则

设计模式,只是前辈们在生产实践中,不断摸索总结出的一系列的指导思想,我们重要的是吸收这种优秀、简练的思想,在实际生产中灵活选择、灵活编码!


菜鸟本菜,不吝赐教,感激不尽!

更多题解源码和学习笔记:githubCSDNM1ng