目录
  1. 1. 工厂模式
    1. 1.1. 定义
      1. 1.1.1. 工厂方法定义
      2. 1.1.2. 抽象工厂定义
    2. 1.2. 工厂模式种类
    3. 1.3. 工厂模式实现
    4. 1.4. 代码实现
      1. 1.4.1. 产品准备
      2. 1.4.2. 简单工厂
      3. 1.4.3. 工厂方法
      4. 1.4.4. 多工厂方法
      5. 1.4.5. 单例工厂
      6. 1.4.6. 抽象工厂
      7. 1.4.7. 各个工厂的场景实现
    5. 1.5. 应用场景
      1. 1.5.1. 工厂方法模式
      2. 1.5.2. 抽象工厂模式
    6. 1.6. 工厂模式优缺点
      1. 1.6.1. 工厂方法模式优缺点
        1. 1.6.1.1. 优点
      2. 1.6.2. 抽象工厂模式优缺点
        1. 1.6.2.1. 优点
        2. 1.6.2.2. 缺点
工厂模式

工厂模式

定义

工厂方法定义

Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

抽象工厂定义

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

工厂模式种类

  1. 简单工厂(静态工厂)
  2. 工厂方法
  3. 多工厂方法
  4. 单例工厂
  5. 抽象工厂
    工厂模式主要分为工厂方法模式和抽象工厂模式。其他的模式是工厂方法的延伸。

工厂模式的多个种类可以看作是一个升级路线: 简单工厂–>工厂方法–>多工厂方法–>抽象方法
简单方法是工厂类没有抽象工厂。不能进行扩展,并且创建方法是静态方法。
工厂方法是简单工厂的升级版,增加了抽象工厂类,创建方法也是成员方法。工厂方法只能生产一类的产品。
多工厂方法是工厂方法的升级版,多工厂方法能够生产多个种类的产品,但是每个种类的产品都需要创建一个匹配的工厂。
抽象工厂则是工厂方法的升级版,抽象工厂能将多个种类的产品放在一个工厂中生产。

工厂模式实现

现在我们需要创建尼安德特人,直立人和智人三个人种。
按照工厂模式,我们需要抽象人,具体人种,抽象工厂,具体工厂四个类。
使用简单工厂,不需要抽象工厂,直接通过具体工厂的静态方法生产出对应人种。
使用工厂方法,通过实现抽象工厂,为每个人种创建对应的工厂,每个工厂创建一个种类。
使用抽象方法,通过实现抽象工厂,为多个具有相同特征的人种建立一个工厂,创建一条生产线,直接生产出需要的人种族。

代码实现

产品准备

  1. 抽象出人出来
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 这是所有人种的能力
*/
public interface Human {
/* 人能说 */
public void talk();

/* 人能使用工具 */
public void useTools();

/* 人能双脚走路 */
public void walkOnTwoFeet();
}
  1. 尼安德特人类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 尼安德特人,从12万年前开始生活在欧洲,亚洲西部以及非洲北部,在2.4万年前消失了,有学者认为他们是被智人(现代人)灭绝的
*/
public class HomoNeanderthalensis implements Human{
@Override
public void talk() {
System.out.println("尼安德特人能说话");
}

@Override
public void useTools() {
System.out.println("尼安德特人能使用工具");
}

@Override
public void walkOnTwoFeet() {
System.out.println("尼安德特人能用两只脚走路");
}
}
  1. 直立人
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 直立人,生活在距今180万-300万年的非洲、欧洲、和亚洲的人种
*/
public class HomoErectus implements Human{
@Override
public void talk() {
System.out.println("直立人能说话");
}

@Override
public void useTools() {
System.out.println("直立人能使用工具");
}

@Override
public void walkOnTwoFeet() {
System.out.println("直立人能用两只脚走路");
}
}
  1. 智人
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 智人,现代人种的祖先,距今25万-4万年前。与尼安德特人,直立人同属于人属的人种
*/
public class HomoSapiens implements Human{
@Override
public void talk() {
System.out.println("智人能说话");
}

@Override
public void useTools() {
System.out.println("智人能使用工具");
}

@Override
public void walkOnTwoFeet() {
System.out.println("智人能用两只脚走路");
}
}

简单工厂

  1. 创建一个简单工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 简单工厂模式
* 前面已经有了三个人种类
* 这里有一个工厂,用来创建人种。现在我们需要获取我们需要的人种对象,直接通过工厂来进行创建
* 这个工厂使用反射来创建对象实例
*
* 工厂方法与简单工厂之间区别就是,简单工厂没有父类,不能进行扩展。并且创建方法是静态方法,简化了类的创建过程
*/
public class SimpleFactory {
public static <T extends Human> T createHuman(Class<T> c) {
Human human = null ;
try {
human = (Human)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("人种生成错误");
}
return (T) human ;
}
}

工厂方法

  1. 创建一个抽象工厂
1
2
3
4
5
6
/**
* 创建一个抽象工厂
*/
public abstract class AbstractHumanFactory {
public abstract <T extends Human> T createHuman(Class<T> c);
}
  1. 创建一个具体工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 工厂方法模式
*/
public class MethodFactory extends AbstractHumanFactory{
@Override
public <T extends Human> T createHuman(Class<T> c) {
Human human = null ;
try {
human = (Human) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("人种生成错误");
}
return (T) human ;
}
}

多工厂方法

  1. 创建一个抽象工厂
1
2
3
public abstract class AbstractHumanFactory1 {
public abstract Human createHuman();
}
  1. 为各个人种(产品)创建各自的工厂
    直立人
1
2
3
4
5
6
public class HomoErectusFactory extends AbstractHumanFactory1 {
@Override
public Human createHuman() {
return new HomoErectus();
}
}

尼安德特人

1
2
3
4
5
6
public class HomoNeanderthalensisFactory extends AbstractHumanFactory1 {
@Override
public Human createHuman() {
return new HomoNeanderthalensis();
}
}

智人

1
2
3
4
5
6
public class HomoSapiensFactory extends AbstractHumanFactory1 {
@Override
public Human createHuman() {
return new HomoSapiens();
}
}

单例工厂

  1. 创建人
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class SingleTonHuman implements Human {
private SingleTonHuman(){

}

@Override
public void talk() {
System.out.println("人能说话");
}

@Override
public void useTools() {
System.out.println("人能使用工具");
}

@Override
public void walkOnTwoFeet() {
System.out.println("人能用两只脚走路");
}
}
  1. 创建单例工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SingleTonHumanFactory {
private static SingleTonHuman singleTonHuman ;
static {
try {
Class c = Class.forName(SingleTonHuman.class.getName());
Constructor constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
singleTonHuman = (SingleTonHuman)constructor.newInstance();
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}

public SingleTonHuman getInstance(){
return singleTonHuman ;
}
}

抽象工厂

  1. 创建一个抽象工厂,其中定义了一个产品族(生产线)
1
2
3
4
5
public interface AbstractFactory {
public HomoSapiens createHomoSapiens();
public HomoErectus createHomoErectus();
public HomoNeanderthalensis createHomoNeanderthalensis();
}
  1. 创建一个产品线工厂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class HumanFactory implements AbstractFactory {
@Override
public HomoSapiens createHomoSapiens() {
return new HomoSapiens();
}

@Override
public HomoErectus createHomoErectus() {
return new HomoErectus();
}

@Override
public HomoNeanderthalensis createHomoNeanderthalensis() {
return new HomoNeanderthalensis();
}
}

各个工厂的场景实现

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
public class App
{
/**
* 简单工厂
*/
/*public static void main( String[] args )
{
Human human = SimpleFactory.createHuman(HomoErectus.class);
human.talk();
human.useTools();
}*/

/**
* 工厂方法
* 一个工厂生产一个产品
*/
/*public static void main(String[] args) {
MethodFactory factory = new MethodFactory();
HomoSapiens human = factory.createHuman(HomoSapiens.class);
human.talk();
human.useTools();
human.walkOnTwoFeet();
}*/

/**
* 多工厂
* 工厂方法的延伸,多个工厂生产多个产品
* @param args
*/
/*public static void main(String[] args) {
Human homoErectus = new HomoErectusFactory().createHuman();
homoErectus.useTools();
homoErectus.talk();
homoErectus.walkOnTwoFeet();

Human homoSapiens = new HomoSapiensFactory().createHuman();
homoSapiens.useTools();
homoSapiens.talk();
homoSapiens.walkOnTwoFeet();

Human homoNeanderthalensis = new HomoNeanderthalensisFactory().createHuman();
homoNeanderthalensis.useTools();
homoNeanderthalensis.talk();
homoNeanderthalensis.walkOnTwoFeet();
}*/

/**
* 单例工厂
* @param args
*/
/*public static void main(String[] args) {
SingleTonHumanFactory factory = new SingleTonHumanFactory();
SingleTonHuman instance = factory.getInstance();
instance.useTools();
instance.talk();
instance.walkOnTwoFeet();
}*/

/**
* 抽象工厂
* 一个共产能生产多个产品
* @param args
*/
public static void main(String[] args) {
/* 建设人类生产线 */
HumanFactory humanFactory = new HumanFactory();

/**
* 抽象工厂只需要一个工厂就能生产出需要的所有人种,而工厂方法如果想要生产人种,需要为每个人种创建一个工厂来进行生产
* 抽象工厂将需要的产品创建方法抽象出来,之后只需要创建一个实体工厂就能创建需要的产品族
*/
/* 创建一个人种 */
HomoErectus homoErectus = humanFactory.createHomoErectus();
homoErectus.useTools();
homoErectus.talk();
homoErectus.walkOnTwoFeet();

HomoNeanderthalensis homoNeanderthalensis = humanFactory.createHomoNeanderthalensis();
homoNeanderthalensis.useTools();
homoNeanderthalensis.talk();
homoNeanderthalensis.walkOnTwoFeet();

HomoSapiens homoSapiens = humanFactory.createHomoSapiens();
homoSapiens.useTools();
homoSapiens.talk();
homoSapiens.walkOnTwoFeet();

}
}

应用场景

工厂方法模式

  1. 工厂方法模式可以作为new一个对象的替代品。
  2. 工厂方法可以用在需要灵活的、可扩展框架的地方。
  3. 工厂方法也可以用在异构项目中。
  4. 可以用在驱动开发的框架下。

抽象工厂模式

  1. 对一个对象族都有相同的约束。

工厂模式优缺点

工厂方法模式优缺点

优点
  1. 良好的封装性,代码结构清晰。
  2. 工厂方法模式的扩展性很好。
  3. 可以屏蔽产品类,我们只需要让工厂帮我们生产产品就行了。
  4. 工厂方法是典型的解耦。

抽象工厂模式优缺点

优点
  1. 封装性,我们只需要关心接口就行了,不关心产品是怎样创建的,工厂帮我们创建。
  2. 产品族内的约束为非公开约束,我们不需要知道知道这个约束,我们只需要得到产品就可以了。
缺点
  1. 抽象工厂可以生产一个产品族,但是产品族的扩展很困难。
文章作者: rack-leen
文章链接: http://yoursite.com/2020/01/04/Java/Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 rack-leen's blog
打赏
  • 微信
  • 支付宝

评论