syshlang设计模式之创建型的三种工厂模式(Factory Pattern) | 浪迹一生

所谓拥有,皆非束缚;所有过往,皆为序章。

0%

设计模式之创建型的三种工厂模式(Factory Pattern)

    工厂模式(Factory Pattern)主要是为创建对象提供了接口,实际开发中,我们可以通过指定的工厂来生产对象,在工厂中创建对象时,不会对客户端暴露创建逻辑,并且所有的对象都是通过一个共同的工厂(接口)创建出来的,如果创建对象的业务逻辑发生改变,我们只需改动“工厂”的逻辑,这在一定程度上降低了耦合度,达到了解耦的目的。

    工厂模式(Factory Pattern)可以细分为三类:简单工厂模式(Simple Factory)、 工厂方法模式(Factory Method)、 抽象工厂模式(Abstract Factory)。

简单工厂模式(Simple Factory)

简单工厂模式(Simple Factory)也叫静态工厂模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* @author sunys
*/
public class SimpleFactory {

public static void main(String[] args) {
Shape shape = ShapeSimpleFactory.getShapeByType("circle");
}

private interface Shape{
/**
* @return
*/
String getShapeType();
}
private static class Circle implements Shape {
public String getShapeType() {
return "circle";
}
}
private static class Rectangle implements Shape {
public String getShapeType() {
return "rectangle";
}
}


private static class ShapeSimpleFactory{

public static Shape getShapeByType(String type){
if ("circle".equals(type)){
return new Circle();
}else if ("rectangle".equals(type)){
return new Rectangle();
}else {
return null;
}
}
}
}

    在上面的例子中,提供了一个ShapeSimpleFactory类,用于封装实例化对象的行为,作为生产几何图形Shape类型对象的“工厂”,该类提供了一个公共的静态方法用于根据类型获取对应的几何图形实体。可以看到这种方式简单粗暴,使用了if…else来做业务逻辑的判断生产对象,试想,那么如果项目的规模变大,Shape的类型增多。。。

工厂方法模式(Factory Method)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* @author sunys
*/
public class FactoryMethod {

public static void main(String[] args) {
CircleFactory circleFactory = new CircleFactory();
Shape circle = circleFactory.createShape();
RectangleFactory rectangleFactory = new RectangleFactory();
Shape rectangle = rectangleFactory.createShape();
}
private interface Shape{}
private static class Circle implements Shape { }
private static class Rectangle implements Shape { }

private interface ShapeFactoryMethod{
/**
* 生产几何图型
* @return
*/
Shape createShape();
}
private static class CircleFactory implements ShapeFactoryMethod{
public Shape createShape() {
return new Circle();
}
}
private static class RectangleFactory implements ShapeFactoryMethod{
public Shape createShape() {
return new Rectangle();
}
}
}

    在工厂方法模式的例子中,定义了一个创建对象的父类接口ShapeFactoryMethod,并声明了生产几何图形的方法createShape,由子类工厂实现生产对象的逻辑。乍一看,工厂方法跟简单工厂似乎不一样,但实际上是“换汤不换药”,简单工厂是采用if…else,而工厂方法模式则是将对象的实例化推迟到子类实现。显然,项目的规模变大时,需要创建更多的工厂,该种方式也不适用。

    简单工厂模式可以看做是工厂方法模式的一种特例,两个归为一类,当项目需要生产的特定对象种类较少时,可以采用这种方式,简单实用。

抽象工厂模式(Abstract Factory)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @author sunys
*/
public class AbstractFactory {
public static void main(String[] args) {
ShapeAbstractFactory circlecombination = ShapeAbstractFactory.getFactory("circlecombination");
Shape shape = circlecombination.getShape();
}

private interface Shape{}
private static class Circle implements Shape { }
private static class Rectangle implements Shape { }

/**
* 圆组合
*/
private static class CircleCombination extends ShapeAbstractFactory {
@Override
Shape getShape() {
return new Circle();
}
}
/**
* 矩形组合
*/
private static class RectangleCombination extends ShapeAbstractFactory {
@Override
Shape getShape() {
return new Rectangle();
}
}


private static abstract class ShapeAbstractFactory{
private static final CircleCombination CIRCLECOMBINATION = new CircleCombination();
private static final RectangleCombination RECTANGLECOMBINATION = new RectangleCombination();
static ShapeAbstractFactory getFactory(String Combination){
if ("circlecombination".equals(Combination)){
return CIRCLECOMBINATION;
}
if ("rectanglecombination".equals(Combination)){
return RECTANGLECOMBINATION;
}
return null;
}
abstract Shape getShape();
}
}

    看上面的代码例子,可以看到简单工厂和工厂方法的影子,实际上抽象工厂模式可以看作是将简单工厂模式和工厂方法模式进行整合,或者是升级改进版。将工厂抽象成两层,AbstractFactory(抽象工厂)和具体实现的工厂子类,那么我们在创建对象时就可以根据对象的类型特点选择对应的工厂子类进行生产,这样一来,就相当将上面提到的简单工厂模式的单个的工厂类变成了工厂簇,这种方式不仅更利于代码的维护和扩展,而且适用于大规模项目中需要生产大量对象的情况。

------------- The End -------------
  • 本文作者: 浪迹一生
  • 本文链接: https://www.syshlang.com/659a32bd/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!