博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂模式(Factory)
阅读量:6887 次
发布时间:2019-06-27

本文共 4971 字,大约阅读时间需要 16 分钟。

一、工厂模式介绍:

工厂模式实现了创建者和调用者的分离

工厂模式分类:

1.简单工厂模式

2.工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类

​3.抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

面向对象设计的基本原则:

OCP(开闭原则,Open-Closed Principle):

        一个软件的实体应当对扩展开放,对修改关闭。也就是说如果你要对一个已存在的系统做扩展的时候尽量要新增加类,而不是在原有的基础上修改。

DIP(依赖倒转原则,Dependence Inversion Principle)

       针对接口编程,不要针对实现编程。

LoD(迪米特法则,Law Of Demeter)

       只与你直接的朋友通信,而避免和陌生人通信。一个类尽量少的依赖其他类

 

二、工厂模式代码实现

未使用工厂模式的情况

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
//汽车接口
public 
interface 
Car {
    
void 
run();
}
//奥迪
public 
class 
Audi 
implements 
Car { 
    
@Override
    
public 
void 
run() {
        
System.out.println(
"奥迪在跑"
);
    
}
}
//比亚迪
public 
class 
Byd 
implements 
Car {
    
@Override
    
public 
void 
run() {
        
System.out.println(
"比亚迪在跑。"
);
    
}
}
//汽车测试类
public 
class 
TestCar {
//调用者
    
public 
static 
void 
main(String[] args) {
        
Car c1 = 
new 
Byd();
        
Car c2 = 
new 
Audi();    
        
c1.run();
        
c2.run();
        
//未使用工厂模式的时候,调用者会依赖很多类。违反了开闭原则
    
}
}

1、简单工厂模式:虽然能通过工厂来创建对象,但是违反了开闭原则。一旦增加功能需要在原有基础上修改代码。

使用了简单工厂模式后:可以创建一个工厂类,该类中提供一个创建汽车的工厂(方法)

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
//汽车工厂
public 
class 
CarFactory {
    
/**
     
* 创建汽车
     
* @param type
     
* @return
     
*/
    
public 
static 
Car createCar(String type){
        
//该方法还会有问题,假如以后有很多汽车都需要工厂来创建。则又得修改源代码,违反了OCP开闭原则
        
if 
(
"audi"
.equals(type)) {
            
return 
new 
Audi();
        
}
else 
if 
(
"byd"
.equals(type)) {
            
return 
new 
Byd();
        
}
else
{
            
return 
null
;
        
}
    
}
}
//测试简单工厂方法
public 
class 
TestSimpleFactoryCar {
//调用者
    
public 
static 
void 
main(String[] args) {
        
//创建汽车
        
Car audi = CarFactory.createCar(
"audi"
);
//创建者
        
Car byd = CarFactory.createCar(
"byd"
);
        
audi.run();
        
byd.run();
    
}
}

2、工厂方法模式:将工厂类调整为工厂接口,需要什么类型的工厂就使用该类实现该工厂,创建相应的产品。

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
//工厂接口
public 
interface 
CarFactory {
    
//创建汽车方法
    
Car createCar();
}
//创建比亚迪汽车的工厂
public 
class 
BydFactory 
implements 
CarFactory{
    
@Override
    
public 
Car createCar() {
        
return 
new 
Byd();
    
}
}
//创建奥迪的工厂
public 
class 
AudiFactory 
implements 
CarFactory {
    
@Override
    
public 
Car createCar() {
        
return 
new 
Audi();
    
}
}
 
//测试工厂方法
public 
class 
TestFactoryMethod {
    
public 
static 
void 
main(String[] args) {
        
/**
         
* 工厂方法模式好处在于,以后如果再增加一辆车。只需再实现CarFactory接口即可。避免了OCP开闭原则
         
* 不用在原来的代码上修改,只需新增类即可。
         
* 例如:增加一辆奔驰,增加一个奔驰工厂BenzFactory即可。更好扩展
         
*/
        
Car audi = 
new 
AudiFactory().createCar();
        
Car byd = 
new 
BydFactory().createCar();
        
audi.run();
        
byd.run();
    
}
}

3、抽象工厂模式:抽象工厂模式用来生产不同产品族的全部产品,对于只增加产品某一部分则不适用。抽象工厂模式是工厂模式的一种升级版本。

在有多个业务品种,业务分类时,抽象工厂能产品不同类别的一个全部产品。例如:生产汽车,抽象工厂模式可以生产高端汽车全部配件来组成一个高端汽车,

低端汽车全部配件来组成要给低端的汽车,但是不能产生一个高端的发动机和一个低端的座椅来组成一个中等的汽车。这样会混乱。

代码实现:

首先使用一个接口来定义一个发动机,使用具体的类来定义发动机的好坏(具体实现)

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
/**
 
* 发动机接口
 
*/
public 
interface 
Engine {
    
void 
run();
    
void 
start();
}
//好的发动机
class 
LuxuryEngine 
implements 
Engine{
    
@Override
    
public 
void 
run() {
        
System.out.println(
"好发动机转的快"
);
    
}
    
@Override
    
public 
void 
start() {
        
System.out.println(
"启动快,自动启停"
);
    
}
}
//差的发动机
class 
LowEngine 
implements 
Engine{
    
@Override
    
public 
void 
run() {
        
System.out.println(
"转的慢"
);
    
}
    
@Override
    
public 
void 
start() {
        
System.out.println(
"启动慢"
);
    
}
}

定义一个汽车总工厂,用来生产各种类型的汽车。所有的汽车都需要依赖此工厂来生产汽车。

1
2
3
4
5
6
7
8
/**
 
*  汽车总工厂,可以创建轮胎,座椅,发动机
 
*/
public 
interface 
CarFactory {
    
Engine createEngine();
//创建发动机
    
Seat createSeat();
//创建座椅
    
Tyre createTyre();
//创建轮胎
}

然后根据生产的不同产品,类创建具体的实现来生产汽车。例如:专门生产高端的汽车,专门生产低端的汽车。都可以用针对CarFactory具体的实现来创建。

高端汽车制造工厂,所有汽车的生产必须依赖汽车总工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 
*  高端汽车制造工厂
 
*/
public 
class 
LuxuryCarFactory 
implements 
CarFactory{
    
@Override
    
public 
Engine createEngine() {
        
return 
new 
LuxuryEngine();
    
}
    
@Override
    
public 
Seat createSeat() {
        
return 
new 
LuxurySeat();
    
}
    
@Override
    
public 
Tyre createTyre() {
        
return 
new 
LuxuryTyre();
    
}
}

低端汽车制造工厂,所有汽车的生产必须依赖汽车总工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 
*  低端汽车制造工厂
 
*/
public 
class 
LowCarFactory 
implements 
CarFactory{
    
@Override
    
public 
Engine createEngine() {
        
return 
new 
LowEngine();
    
}
    
@Override
    
public 
Seat createSeat() {
        
return 
new 
LowSeat();
    
}
    
@Override
    
public 
Tyre createTyre() {
        
return 
new 
LowTyre();
    
}
}

具体生产汽车的时候就可以根据需要来创建具体的汽车了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public 
static 
void 
main(String[] args) {
    
//想要好车
    
CarFactory factory = 
new 
LuxuryCarFactory();
    
Engine engine = factory.createEngine();
//创建高端发动机
    
engine.run();
    
engine.start();
     
    
//想要差一点的车
    
CarFactory factory2 = 
new 
LowCarFactory();
    
Engine e2= factory2.createEngine();
    
Seat s2 = factory2.createSeat();
    
Tyre t2 = factory2.createTyre();
    
e2.run();
    
e2.start();
    
//以后想要中等车的话可以增加相应中等配件的接口
}

以上就是一个针对产品族的工厂,用来生产一个产品,而不是一个配件。假如以后想生产一个中端汽车产品。就可以增加相应的类,实现汽车总工厂CarFactory

来生产。

 

三、工厂模式要点

简单工厂模式(静态工厂模式)

   虽然某种程度不符合面向对象规则(不符合开闭原则,每次新增内容都需要在原有代码上修改),但是实际使用最多。

工厂方法模式

   不修改已有类的前提下,通过增加新类来实现扩展。

抽象工厂模式

    不可以增加产品中某一个配件,可以增加一个具体的产品族。

 

四、应用场景

JDK中的Calendar的getInstance方法

JDBC中Connection对象的获取getConnection

Hibernate中SessionFactory创建Session

spring中的IOC容器创建管理bean对象的时候也是工厂模式

XML解析时的DocumentBuilderFactory创建解析器对象

反射中Class对象的newInstance方法。

 

 

 

参考资料:

  大话设计模式(带目录完整版).pdf

  HEAD_FIRST设计模式(中文版).pdf

  尚学堂_高淇_java300集最全视频教程_【GOF23设计模式】

转载地址:http://mwxbl.baihongyu.com/

你可能感兴趣的文章
WinForm多线程编程
查看>>
Hyperledger Fabric 客户端开发五
查看>>
spring的参数校验
查看>>
Nginx的URL Rewrite基本指令
查看>>
Properties属性文件操作工具类PropsUtil
查看>>
计算机系统要素 C4
查看>>
Mysql存储引擎
查看>>
每看一次自己写的代码都有一种重写的冲动
查看>>
androidManifest.xml问题
查看>>
升级ubuntu后nginx无法启动
查看>>
inux多线程顺序控制的示例
查看>>
SQLServer 2016安装时的错误:Polybase要求安装Oracle JRE 7更新51或更高版本
查看>>
wkhtmtopdf--高分辨率转HTML成PDF(二)
查看>>
如何优雅的编写Dockerfile
查看>>
调试时显示数据防止乱码
查看>>
logback 日志输出级别设置
查看>>
直接插入法
查看>>
用户管理 新老用户的管理
查看>>
linux时间同步命令
查看>>
书法家程序员往往是公司最不受欢迎的程序员
查看>>