Zer0e's Blog

设计模式之工厂模式

字数统计: 958阅读时长: 3 min
2020/08/12 Share

前言

本文讲讲工厂模式。

正文

概念

工厂模式是Java中常用的一种设计模式,它属于创建型模式的一种,又称为工厂方法模式,这种模式提供了创建对象的一种方法,对客户端隐藏生成对象的逻辑,使用一个接口来指向新的对象。
常见的实例有:

  • 工厂提供多种产品,你可以直接购买,无需关心如何制作。
  • 日志管理,可以使用多种方式记录,并且可以记录到本地,远程等等。
  • 数据库访问,不知道系统最后使用哪种数据库时,封装可用的数据库。

当对象较为复杂时,使用工厂模式较为适合,如果对象十分简单,那直接使用new生成就可以了。

实现

下面我们用一个例子来实现工厂模式。
例如游戏公司要制作几个新的游戏。
我们将创建一个游戏Game接口,以及实现它的实体类,然后创建工厂去制作游戏。
我们先定义Game接口

1
2
3
public interface Game {
void test();
}

接着定义几个游戏A,B,C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class GameA implements Game{
@Override
public void test() {
System.out.println("this is Game A");
}
}
public class GameB implements Game{
@Override
public void test() {
System.out.println("this is Game B");
}
}
public class GameC implements Game{
@Override
public void test() {
System.out.println("this is Game C");
}
}

接着创建工厂,根据名称生成实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class GameFactory {
public Game getGame(String name){
if (name == null){
return null;
}

if (name.equalsIgnoreCase("GameA")){
return new GameA();
}else if (name.equalsIgnoreCase("GameB")){
return new GameB();
}else if (name.equalsIgnoreCase("GameC")){
return new GameC();
}
return null;
}
}

接着编写客户端进行调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Client {
public static void main(String[] args) {
GameFactory gameFactory = new GameFactory();

Game game1 = gameFactory.getGame("GameA");
game1.test();

Game game2 = gameFactory.getGame("GameB");
game2.test();

Game game3 = gameFactory.getGame("GameC");
game3.test();

}
}

/*
this is Game A
this is Game B
this is Game C
*/

后续思考

以上我们就实现了一个简单的工程模式示例,当然从上述工厂的代码来看,肯定是不够优雅的,毕竟我们需要写很多的if else,或者case语句。
那我自己想到的点是,通过一个枚举类或者常量,提供所有可以创建对象的关键字,然后通过关键字所对应的值,来进行反射创建操作。
例如创建一个GameType类

1
2
3
4
5
public class GameType {
static final String GameA = GameA.class.getName();
static final String GameB = GameB.class.getName();
static final String GameC = GameC.class.getName();
}

修改GameFactory

1
2
3
4
5
6
7
8
9
  
public Game getGame2(String type){
try {
return (Game) Class.forName(type).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return null;
}

对应client

1
2
3
  
Game game = gameFactory.getGame2(GameType.GameA);
game.test();

算是少些了一下冗余吧,当然也可以使用枚举类,这里就不再多写了。优化一下就少了许多if else。

优缺点

工厂模式的优点在于客户端只需知道名称就可以创建一个对象,并且拓展性较好,而且屏蔽了类的具体实现。
而缺点就是在增加一个产品之后,就需要添加具体类与修改工厂,增加系统的复杂性。

总结

本文总结了简单工厂模式,当然,从本文的例子看并不需要工厂模式去创建对象,但是当对象较为复杂时,例如对象依赖于其他对象,那在客户端中就没必要自己实现对象,而是交给工厂实现。而当客户端不知道需要创建对象的类时,也可以使用工厂模式来设计系统。
之后会讲讲工厂模式的进阶,抽象工厂模式,算是一个比较难的模式。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 后续思考
    4. 2.4. 优缺点
  3. 3. 总结