工厂模式的定义
“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”(在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。)
- 简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory Method Pattern)。
- 工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式;
- 抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或Toolkit)模式。
定工厂方法(Factory Method)模式
定义
工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
特征:
- 工厂(Factory)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product)角色 :简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- 具体产品(Concrete Product)角色:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。定义工厂接口
代码实现
创建一个可以绘制不同形状的绘图工具,可以绘制圆形,正方形,三角形,每个图形都会有一个draw()方法用于绘图.
(1)创建Shape接口
1 | public interface Shape { |
(2)创建实现该接口的具体图形类
圆形1
2
3
4
5
6
7
8
9public class Circle implements Shape {
public Circle() {
System.out.println("Circle");
}
@Override
public void draw() {
System.out.println("Draw Circle");
}
}
长方形1
2
3
4
5
6
7
8
9public class Rectangle implements Shape {
public Rectangle() {
System.out.println("Rectangle");
}
@Override
public void draw() {
System.out.println("Draw Rectangle");
}
}
正方形1
2
3
4
5
6
7
8
9
10public class Square implements Shape {
public Square() {
System.out.println("Square");
}
@Override
public void draw() {
System.out.println("Draw Square");
}
}
(3)创建工厂类:
1 | public class ShapeFactory { |
(4)测试方法:
1 | public class Test { |
输出结果:
Circle
Draw Circle
Rectangle
Draw Rectangle
Square
Draw Square
工厂方法模式使用问题
优点:
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
抽象工厂(Abstract Factory)模式
定义
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
特征:
- 抽象工厂(AbstractFactory)角色 :是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
- 具体工厂类(ConreteFactory)角色 :这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。
- 抽象产品(Abstract Product)角色 :工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
- 具体产品(Concrete Product)角色 :抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。在抽象工厂中创建的产品属于同一产品族,这不同于工厂模式中的工厂只创建单一产品,我后面也会详解介绍到。
代码实现
步骤 1:为形状创建一个接口。
Shape.java1
2
3public interface Shape {
void draw();
}
步骤 2:创建实现接口的实体类。
Rectangle.java1
2
3
4
5
6
7public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java1
2
3
4
5
6
7public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java1
2
3
4
5
6
7public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
步骤 3:为颜色创建一个接口。
Color.java1
2
3public interface Color {
void fill();
}
步骤4:创建实现接口的实体类。
Red.java1
2
3
4
5
6
7public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
Green.java1
2
3
4
5
6
7public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
Blue.java1
2
3
4
5
6
7public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
步骤 5:为 Color 和 Shape 对象创建抽象类来获取工厂。
AbstractFactory.java1
2
3
4public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
步骤 6:创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。
ShapeFactory.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class ShapeFactory extends AbstractFactory {
@Override
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;
}
@Override
public Color getColor(String color) {
return null;
}
}
ColorFactory.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
步骤 7:创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。
1 | FactoryProducer.java |
步骤 8:使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
1 | AbstractFactoryPatternDemo.java |
步骤 9:执行程序,输出结果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.
抽象工厂模式使用问题
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
工厂方法模式与抽象工厂模式比较
- 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性。
- 抽象工厂模式则可以提供多个产品对象,而不是单一的产品对象。
抽象工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法中的工厂是生产单一产品的工厂。
Android中工厂方法、抽象工厂
Android中的ThreadFactory就是使用了工厂方法模式来生成线程的,线程就是ThreadFactory的产品。
感谢
郭霖的专栏 CSDN: https://blog.csdn.net/guolin_blog/article/category/1381137
segmentfault:
工厂模式
深入理解工厂模式
百度百科:
工厂方法模式
抽象工厂模式
菜鸟教程:抽象工厂模式