工厂模式
Overview
工厂方法模式一种创建对象的模式,它被广泛应用在JDK中以及Spring和Struts框架中。
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
通过给工厂对象传递不同参数来实现获得不同的子类。
主要解决
主要解决接口选择的问题。
我们通过工厂来替我们选择,对于不知情的人,只要传入参数,工厂会自动为我们选择一个类。
何时使用
我们明确地计划不同条件下创建不同实例时。
应用实例
- 购买汽车,直接去工厂提货,而不需要知道汽车是怎么制造的
- Hibernate 换数据库只需换方言和驱动就可以
优点
- 一个调用者想创建一个对象,只要知道其名称就可以了
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以
- 屏蔽产品的具体实现,调用者只关心产品的接口
实现
Shape and Subclass
Shape interface
1
2
3
4
5
6
| public interface Shape {
/**
* draw a geometry
*/
void draw();
}
|
Circle
1
2
3
4
5
6
| public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle.draw");
}
}
|
Rectangle
1
2
3
4
5
6
| public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle.draw");
}
}
|
Square
1
2
3
4
5
6
| public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square.draw");
}
}
|
Factory
Solution 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("circle")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("rectangle")) {
return new Rectangle();
} else if (shapeType.equalsIgnoreCase("square")) {
return new Square();
}
return null;
}
}
|
Solution 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| public enum ShapeCreator {
/**
* create Circle, Rectangle, Square
*/
CIRCLE(Circle::new), RECTANGLE(Rectangle::new), SQUARE(Square::new);
private final Supplier<Shape> shapeSupplier;
ShapeCreator(Supplier<Shape> shapeSupplier) {
this.shapeSupplier = shapeSupplier;
}
public Shape getInstance() {
return shapeSupplier.get();
}
public static Shape getShape(ShapeCreator creator) {
return creator.getInstance();
}
}
|
Solution 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| public enum ShapeCreator2 {
/**
* create Circle, Rectangle, Square
*/
CIRCLE(new Circle()), RECTANGLE(new Rectangle()), SQUARE(new Square());
private final Shape shape;
ShapeCreator2(Shape shape) {
this.shape = shape;
}
public Shape getShape() {
return shape;
}
}
|
Tester
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
| package individual.cy.learn.pattern.creational.factory;
/**
* @author mystic
*/
public class FactoryPatternTester {
public static void main(String[] args) {
ShapeFactory factory = new ShapeFactory();
// Acquire Circle
Shape circle = factory.getShape("circle");
circle.draw();
// Acquire Rectangle
Shape rectangle = factory.getShape("rectangle");
rectangle.draw();
// Acquire Square
Shape square = factory.getShape("square");
square.draw();
System.out.println();
ShapeCreator.CIRCLE.getInstance().draw();
ShapeCreator.RECTANGLE.getInstance().draw();
ShapeCreator.SQUARE.getInstance().draw();
System.out.println();
System.out.println(ShapeCreator.CIRCLE.getInstance());
System.out.println(ShapeCreator.CIRCLE.getInstance());
System.out.println(ShapeCreator.CIRCLE.getInstance());
// Or this usage
System.out.println(ShapeCreator.getShape(ShapeCreator.CIRCLE));
System.out.println(ShapeCreator.getShape(ShapeCreator.CIRCLE));
System.out.println(ShapeCreator.getShape(ShapeCreator.CIRCLE));
System.out.println();
System.out.println(ShapeCreator2.CIRCLE.getShape());
System.out.println(ShapeCreator2.CIRCLE.getShape());
System.out.println(ShapeCreator2.CIRCLE.getShape());
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| Circle.draw
Rectangle.draw
Square.draw
Circle.draw
Rectangle.draw
Square.draw
individual.cy.learn.pattern.creational.factory.Circle@12f40c25
individual.cy.learn.pattern.creational.factory.Circle@3ada9e37
individual.cy.learn.pattern.creational.factory.Circle@5cbc508c
individual.cy.learn.pattern.creational.factory.Circle@3419866c
individual.cy.learn.pattern.creational.factory.Circle@63e31ee
individual.cy.learn.pattern.creational.factory.Circle@68fb2c38
individual.cy.learn.pattern.creational.factory.Circle@2eafffde
individual.cy.learn.pattern.creational.factory.Circle@2eafffde
individual.cy.learn.pattern.creational.factory.Circle@2eafffde
|
ShapeCreator创建子对象,都是不同的
ShapeCreator2子对象都是同一个