Spring5系列(二) | 工厂设计模式

简介: Spring5系列(二) | 工厂设计模式

spring中大量使用的工厂设计模式,所以我们这个章节先简单的了解下工厂设计模式的内容。

工厂设计模式属于创建型模式中的一种。在GOF中的定义:

“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),工厂方法模式(factory method)和抽象工厂(abstract factory)模式。

为什么要使用工厂模式:

工厂模式的主要好处就是解耦合,这个词好像比较耳熟吧,我们在spring概述的章节中就提高了spring的主要功效也是解耦合,简直不谋而合。同时工厂模式的主要作用是对象的创建和使用过程分开。而对于spring而言就是他负责了对象的创建过程,所以我们只需要关注对象的使用过程就可以了,这样也就大大地简化了我们的开发过程。同时降低了代码的重复和维护成本。因为有了工厂,我们就不需要书写对象的创建过程了。

一. 简单工厂模式

interfaceMouse{
voidsayHi();
}
classDellMouseimplementsMouse{
publicvoidsayHi(){
System.out.println("hi,DellMouse")
    }    
}
classHpMouseimplementsMouse{
publicvoidsayHi(){
System.out.println("hi,HpMouse")
    }    
}
classMouseFacotry{
publicstaticMousecreateMouse(inti){
switch(i){
case0:returnnewDellMouse();break;
case1:returnnewHpMouse();break;
default:returnnull;
        }
    }
}
复制代码

简单工厂在实际应用中相对于其他工厂模式用的相对少,并且它违背了我们在概述中说的开放-封闭原则。因为每次你要添加一个功能,都需要在switch-case或者 if-else中去修改代码,添加分支条件 使用场景: 需要创建的对象较少,客户端不关心对象的创建过程 角色:工厂角色, 抽象产品角色(Mouse) ,具体产品角色(DellMouse, HpMouse)

二. 工厂方法模式

工厂方法模式应该是工厂模式家族中使用最多的模式,一般项目中存在最多的就是这个模式。 工厂方法模式是简单工厂模式的进一步深化,在工厂方法模式中,我们不在提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。

适用场景:

  • 一个类不知道它所需要的对象的类: 在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道它所对应的工厂即可,具体的产品对象由具体工厂类创建。客户端需要知道创建具体产品的工厂类
  • 一个类通过其子类来指定创建哪个对象: 在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中

角色分配

  • 抽象工厂(Abstract factory): 是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口
  • 具体工厂(Concrete factory): 这是实现抽象工厂接口的具体工厂类,包含于应用长须密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象
  • 抽象产品(Abstract product) : 工厂方法模式所创建的对象的超类型,也就是产品对象的公共父类或共同接口
  • 具体产品(Concrete product): 这个角色实现了抽象产品角色所定义的接口。某具体产品的由专门的具体工厂创建,他们之间往往一一对应。

代码示例

publicinterfaceMouseFactory{
MousegetMouse();
}
publicclassDellMouseFactoryimplementsMouseFactory{
publicMousegetMouse(){
returnnewDellMouse();
    }
}
publicclassHpMouseFactoryimplementsMouseFactory{
publicMousegetMouse(){
returnnewHpMouse();
    }
}
publicinterfaceMouse{
voidsayHi();
}
publicclassDellMouseimplementsMouse{
publicvoidsayHi(){
System.out.println("hi,DellMouse")
    }    
}
publicclassHpMouseimplementsMouse{
publicvoidsayHi(){
System.out.println("hi,HpMouse")
    }    
}
publicclassTest{
publicstaticvoidmain(String[] args){
MouseFactorydellFac=newDellMouseFactory();
MousedellMouse=dellFac.getMouse();
dellMouse.sayHi();
    }
}
复制代码

三. 抽象工厂模式

在工厂方法模式中,其实我们有一个潜在的意识。那就是我们生产的都是同一类产品。抽象工厂模式是工厂方法的进一步深化,在这个模式中工厂类不单单可以创建一种产品,而是可以创建一组产品。抽象工厂应该是比较难理解的一个工厂模式了

适用场景

和工厂方法一样客户端不需要知道它所创建的对象类 需要一组对象共同完成某种功能,并且可能存在多组对象完成不同功能的情况(同属同一个产品族的产品) 系统结构稳定,不会频繁增加对象(因为一增加就需要修改原有代码,不符合开闭原则)

角色分配

  • 抽象工厂: 是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  • 具体工厂: 是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。
  • 抽象产品:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
  • 具体产品:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。在抽象工厂中创建的产品属于同一产品族,这不同于工厂模式中的工厂只创建单一产品,我后面也会详解介绍到。
  • 抽象工厂和工厂方法中的工厂区别: 抽象工厂是生产一整套产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的,而工厂方法的工厂是生产单一的产品的工厂。

实例

我们以吃鸡游戏举例。游戏中有各种枪。假设现在存在AK,M4A1两类枪,每一种枪对应一种子弹。我们现在这样考虑生产AK的工厂可以顺带生产AK子弹,生产M4A1的工厂可以生产其锁对象的子弹。 创建相关接口:

枪:

publicinterfaceGun{
publicvoidshooting();
 }

子弹:

publicinterfaceBullet{
publicvoidload();
 }

创建对应实现类 AK:

publicclassAKimplementsGun{
publicvoidshooting(){
System.out.println("shooting with AK");
     }
 }

M4A1:

public class M4A1 implements Gun{
     public void shooting(){
         System.out.println("shooting with M4A1");
     }
 }

AK子弹:

publicclassAK_BulletimplementsBullet {
@Overridepublicvoidload() {
System.out.println("Load bullets with AK");
     }
 }

M4A1子弹类

publicclassM4A1_BulletimplementsBullet {
@Overridepublicvoidload() {
System.out.println("Load bullets with M4A1");
     }
 }

创建工厂

publicinterfaceFactory{
publicGunproduceGun();
publicBulletproduceBullet();
 }
publicclassAKFacimplementsFactory{
publicGunproduceGun(){
returnnewAK();
     }
publicBulletproduceBullet(){
returnnewAK_Bullet();
     }
 }
publicclassM4A1FacimplementsFactory{
publicGunproduceGun(){
returnnewM4A1();
     }
publicBulletproduceBullet(){
returnnewM4A1_Bullet();
     }
 }

测试

publicclassTest{
publicstaticvoidmain(String[] args){
Factoryfactory;
Gungun;
Bulletbullet;
factory=newAKFac();
bullet=factory.produceBullet();
bullet.load();
gun=factory.produceGun();
gun.shooting(); 
     }
 }

四. 总结

好了,关于工厂设计模式,我们就暂时写这么多,这里边有很多内容都是直接从我的笔记上摘抄的,而笔记中的内容也多半是多年前在知乎上摘录,但是没有记录原文作者和链接,在此表达鸣谢,如有侵权,请联系删除。



目录
相关文章
|
5月前
|
设计模式 SQL Java
Spring中的设计模式
Spring中的设计模式
|
16天前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
2月前
|
设计模式 SQL Java
一探到底!Spring团队使用的那些设计模式,快来看看你用过哪几个
该文章主要介绍了Spring框架中使用的设计模式,并列举了一些常见的设计模式及其在Spring框架中的应用。
一探到底!Spring团队使用的那些设计模式,快来看看你用过哪几个
|
2月前
|
设计模式 XML 数据格式
python之工厂设计模式
python之工厂设计模式
python之工厂设计模式
|
2月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
26 0
|
2月前
|
设计模式 测试技术
依赖注入与工厂设计模式的区别
【8月更文挑战第22天】
35 0
|
2月前
|
设计模式 缓存 Java
深入Spring Boot启动过程:揭秘设计模式与代码优化秘籍
深入Spring Boot启动过程:揭秘设计模式与代码优化秘籍
|
4月前
|
设计模式 Java 编译器
设计模式——创建型模式(工厂,简单工厂,单例,建造者,原型)
设计模式——创建型模式(工厂,简单工厂,单例,建造者,原型)
|
3月前
|
设计模式 Java 开发者
工厂设计模式的实现与应用场景分析
工厂设计模式的实现与应用场景分析