# 《Java极简设计模式》第03章:工厂方法模式(FactoryMethod)
沉淀,成长,突破,帮助他人,成就自我。
- 本章难度:★★☆☆☆
- 本章重点:用最简短的篇幅介绍工厂方法模式最核心的知识,理解工厂方法模式的设计精髓,并能够灵活运用到实际项目中,编写可维护的代码。
# 一、概述
⼯⼚模式也称简单⼯⼚模式,是创建型设计模式的⼀种,这种设计模式提供了按需创建对象的最佳⽅式。同时,这种创建⽅式不会对外暴露创建细节,并且会通过⼀个统⼀的接⼝创建所需对象。
⼯⼚模式属于创建型模式的⼀种,其⽬的就是隐藏创建类的细节与过程
定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
# 二、适用性
1.当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
# 三、参与者
- Product(抽象产品):定义工厂方法所创建的对象的接口。
- ConcreteProduct(具体产品):实现Product接口的具体类。
- Creator(抽象工厂):声明返回Product类型的工厂方法。这个方法应该返回一个Product类型的实例。可以是具体的也可以是抽象的类或接口。
- ConcreteCreator(具体工厂):重写Creator中的工厂方法以返回ConcreteProduct类型的实例。
# 四、类图
# 五、示例一
Product
package io.binghe.design.factotymethod;
/**
* 定义一个接口Work
* @author binghe
*/
public interface Work {
/**
* 定义方法
*/
void doWork();
}
2
3
4
5
6
7
8
9
10
11
ConcreteProduct
package io.binghe.design.factotymethod;
/**
* Work接口的具体实现类
* @author binghe
*/
public class TeacherWork implements Work {
public void doWork() {
System.out.println("老师审批作业!");
}
}
2
3
4
5
6
7
8
9
10
package io.binghe.design.factotymethod;
/**
* Work接口的具体实现类
* @author binghe
*/
public class StudentWork implements Work {
@Override
public void doWork() {
System.out.println("学生做作业!");
}
}
2
3
4
5
6
7
8
9
10
11
Creator
package io.binghe.design.factotymethod;
/**
* 抽象工厂接口
* @author binghe
*/
public interface IWorkFactory {
/**
* 定义获取Work实例对象的方法
* @return
*/
Work getWork();
}
2
3
4
5
6
7
8
9
10
11
12
ConcreteCreator
package io.binghe.design.factotymethod;
/**
* IWorkFactory工厂的实现类
* @author binghe
*/
public class StudentWorkFactory implements IWorkFactory {
@Override
public Work getWork() {
return new StudentWork();
}
}
2
3
4
5
6
7
8
9
10
11
package io.binghe.design.factotymethod;
/**
* IWorkFactory工厂的实现类
* @author binghe
*/
public class TeacherWorkFactory implements IWorkFactory {
@Override
public Work getWork() {
return new TeacherWork();
}
}
2
3
4
5
6
7
8
9
10
11
Test
package io.binghe.design.factotymethod;
/**
* 测试类
* @author binghe
*/
public class Test {
public static void main(String[] args) {
IWorkFactory studentWorkFactory = new StudentWorkFactory();
studentWorkFactory.getWork().doWork();
IWorkFactory teacherWorkFactory = new TeacherWorkFactory();
teacherWorkFactory.getWork().doWork();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Result
学生做作业!
老师审批作业!
2
# 六、示例二
下⾯我⽤可以利⽤
以电脑店为例,我是⼀个纯⼩⽩,⾯对琳琅满⽬的各种电脑⼀脸懵X,根本⽆从下⼿~
电脑接⼝
public interface Computer {
public String describe();
}
2
3
外星⼈游戏笔记本
public class Alienware implements Computer{
@Override
public String describe() {
return "外星⼈ALIENWARE m15 R7 15.6英⼨⾼端游戏本 12代i7 32G RTX3060 QH
D 240Hz ⾼刷屏 轻薄笔记本电脑2765QB";
}
}
2
3
4
5
6
7
⾼性能独显PC主机
public class Desktop implements Computer{
@Override
public String describe() {
return "外星⼈ALIENWARE R13 ⽔冷电竞游戏⾼端台式机 第12代i7 32G 512GB+2
T RTX3070 办公台式机 9776W";
}
}
2
3
4
5
6
7
Macbook办公轻薄本
public class Macbook implements Computer{
@Override
public String describe() {
return "Apple MacBook Pro 13.3 ⼋核M1芯⽚ 8G 256G SSD 深空灰 笔记本电
脑 轻薄本 MYD82CH/A";
}
}
2
3
4
5
6
7
2U戴尔服务器
public class Server implements Computer{
@Override
public String describe() {
return "戴尔(DELL) R740⼁R750⼁2U机架式服务器主机双路GPU深度学习 R740〖1
*银牌4210R 10核20线程〗 8G内存⼁1TB SATA硬盘 ⼁H350戴尔(DELL);
}
}
2
3
4
5
6
7
此时顾客将⾯对⼏⼗种不同性能,不同规格不同种类的电脑,难道顾客必须了解所有细节才能决定使⽤哪⼀个吗?
这⾥就破坏了“迪⽶特法则(知道的越少越好)”,⼤多数客户并不需要了解每⼀台细节,我们要把选择权交还给电脑店这⼀⽅。
控制权在顾客⽅是不对的

我们需要⼀个⼯⼚类,帮助顾客进⾏决策,这样控制权掌握

正确的做法
增加⼀个售货员帮助⽤户实现决策,根据客户的不同要求提供对应的产品。这个售货员就是充当了“⼯⼚"的⻆⾊。⼯⼚模式的特点:提供⽅法,返回接⼝
public class ShopAssistant {
public Computer suggest(String purpose){
Computer computer = null;
if(purpose.equals("⽹站建设")){
return new Server();
}else if(purpose.equals("电竞⽐赛")){
return new Desktop();
}else if(purpose.equals("⽇常办公")){
return new Macbook();
}else if(purpose.equals("3A游戏")){
return new Alienware();
}
return computer;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
站在顾客这⼀⽅,获取对象的过程变得⾮常简单,通过售货员这个⼯⼚帮助我们获取需要的对象,同时不再关注对象创建的过程与细节
public class Customer {
public static void main(String[] args) {
ShopAssistant shopAssistant = new ShopAssistant();
Computer c = shopAssistant.suggest("3A游戏");
System.out.println(c.describe());
}
}
2
3
4
5
6
7
项⽬中的作⽤
难道让⽤户⾃⼰选择使⽤那个语⾔吗?
在界⾯上提供个下拉选择框,让⽤户⾃⼰选择语⾔?

