Abstract Factory Pattern in Design Pattern

抽象工厂模式

Overview

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。

每个生成的工厂都能按照工厂模式提供对象。

主要解决

主要解决接口选择的问题。

何时使用

系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

应用实例

  • QQ 换皮肤,一整套一起换

优点

  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

实现

Abstract Factory Pattern

Shape and Subclass

Shape interface

1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public interface GeometricShape {
/**
* draw a geometric shape
*/
void draw();
}

ShapeType2D

1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public enum ShapeType2D {
/**
* 2d geometric shape
*/
LINE, CIRCLE, SQUARE
}

ShapeType3D

1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public enum ShapeType3D {
/**
* 3d geometric shape
*/
SPHERE, CUBE, CYLINDER
}

2D Shape

Line
1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Line implements GeometricShape {
@Override
public void draw() {
System.out.println("Line.draw");
}
}
Circle
1
2
3
4
5
6
7
8
9
10
11
12
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Circle implements GeometricShape {
@Override
public void draw() {
System.out.println("Circle.draw");
}
}

Square
1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Square implements GeometricShape {
@Override
public void draw() {
System.out.println("Square.draw");
}
}

3D Shape

Cude
1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Cube implements GeometricShape {
@Override
public void draw() {
System.out.println("Cube.draw");
}
}
Sphere
1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Sphere implements GeometricShape {
@Override
public void draw() {
System.out.println("Sphere.draw");
}
}
Cylinder
1
2
3
4
5
6
7
8
9
10
11
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class Cylinder implements GeometricShape {
@Override
public void draw() {
System.out.println("Cylinder.draw");
}
}

Factory

Abstract Factory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public abstract class AbstractFactory {
/**
* To get a 2d geometric shape
*
* @param type shape name
* @return Geometric Shape
*/
public abstract GeometricShape getGeometricShape2D(ShapeType2D type);

/**
* To get a 3d geometric shape
*
* @param type shape name
* @return Geometric Shape
*/
public abstract GeometricShape getGeometricShape3D(ShapeType3D type);
}

Two Dimension Shape 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
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class TwoDimensionShapeFactory extends AbstractFactory {
@Override
public GeometricShape getGeometricShape2D(ShapeType2D type) {
switch (type) {
case LINE:
return new Line();
case CIRCLE:
return new Circle();
case SQUARE:
return new Square();
default:
return null;
}
}

@Override
public GeometricShape getGeometricShape3D(ShapeType3D type) {
return null;
}
}

Three Dimension Shape 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
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class ThreeDimensionShapeFactory extends AbstractFactory {

@Override
public GeometricShape getGeometricShape2D(ShapeType2D type) {
return null;
}

@Override
public GeometricShape getGeometricShape3D(ShapeType3D type) {
switch (type) {
case SPHERE:
return new Sphere();
case CUBE:
return new Cube();
case CYLINDER:
return new Cylinder();
default:
return null;
}
}
}

Factory Creator

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
package individual.cy.learn.pattern.creational.abstractfactory;

import java.util.function.Supplier;

/**
* @author mystic
*/
public enum FactoryCreator {
/**
* create 2D, 3D geometric shape
*/
TWO_D_SHAPE_FACTORY(TwoDimensionShapeFactory::new), THREE_D_SHAPE_FACTORY(ThreeDimensionShapeFactory::new);

private final Supplier<AbstractFactory> factorySupplier;

FactoryCreator(Supplier<AbstractFactory> factorySupplier) {
this.factorySupplier = factorySupplier;
}

public AbstractFactory getInstance() {
return factorySupplier.get();
}

public static AbstractFactory getFactory(FactoryCreator creator) {
return creator.getInstance();
}
}

Tester

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package individual.cy.learn.pattern.creational.abstractfactory;

/**
* @author mystic
*/
public class AbstractFactoryPatternTester {
public static void main(String[] args) {
// draw 2d shape
FactoryCreator.TWO_D_SHAPE_FACTORY
.getInstance()
.getGeometricShape2D(ShapeType2D.LINE)
.draw();

// draw 3d shape
FactoryCreator.THREE_D_SHAPE_FACTORY
.getInstance()
.getGeometricShape3D(ShapeType3D.CYLINDER)
.draw();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
13:18:52: Executing task 'AbstractFactoryPatternTester.main()'...

Configuration on demand is an incubating feature.
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes

> Task :AbstractFactoryPatternTester.main()
Line.draw
Cylinder.draw

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
13:18:54: Task execution finished 'AbstractFactoryPatternTester.main()'.