前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring5系列(二) | 工厂设计模式

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

作者头像
一缕82年的清风
修改2021-12-13 09:39:36
2140
修改2021-12-13 09:39:36
举报
文章被收录于专栏:lsqingfeng

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而言就是他负责了对象的创建过程,所以我们只需要关注对象的使用过程就可以了,这样也就大大地简化了我们的开发过程。同时降低了代码的重复和维护成本。因为有了工厂,我们就不需要书写对象的创建过程了。

一. 简单工厂模式

代码语言:javascript
复制
interface Mouse{
    void sayHi();
}
class DellMouse implements Mouse{
    public void sayHi(){
        System.out.println("hi,DellMouse")
    }    
}
class HpMouse implements Mouse{
    public void sayHi(){
        System.out.println("hi,HpMouse")
    }    
}

class MouseFacotry{
    public static Mouse createMouse(int i){
        switch(i){
            case 0:return new DellMouse();break;
            case 1:return new HpMouse();break;
            default:return null;
        }
    }
}
复制代码

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

二. 工厂方法模式

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

适用场景:

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

角色分配

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

代码示例

代码语言:javascript
复制
public interface MouseFactory{
    Mouse getMouse();
}
public class DellMouseFactory implements MouseFactory{
    public Mouse getMouse(){
        return new DellMouse();
    }
}
public class HpMouseFactory implements MouseFactory{
    public Mouse getMouse(){
        return new HpMouse();
    }
}

public interface Mouse{
    void sayHi();
}
public class DellMouse implements Mouse{
    public void sayHi(){
        System.out.println("hi,DellMouse")
    }    
}
public class HpMouse implements Mouse{
    public void sayHi(){
        System.out.println("hi,HpMouse")
    }    
}

public class Test{
    public static void main(String[] args){
        MouseFactory dellFac = new DellMouseFactory();
        Mouse dellMouse = dellFac.getMouse();
        dellMouse.sayHi();
        
    }
}
复制代码

三. 抽象工厂模式

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

适用场景

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

角色分配

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

实例

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

枪:

代码语言:javascript
复制
public interface Gun{
     public void shooting();
 }
复制代码

子弹:

代码语言:javascript
复制
public interface Bullet{
     public void load();
 }
复制代码

创建对应实现类 AK:

代码语言:javascript
复制
 public class AK implements Gun{
     public void shooting(){
         System.out.println("shooting with AK");
     }
 }

复制代码

M4A1:

代码语言:javascript
复制
public class M4A1 implements Gun{
     public void shooting(){
         System.out.println("shooting with M4A1");
     }
 }
复制代码

AK子弹:

代码语言:javascript
复制
 public class AK_Bullet implements Bullet {
     @Override
     public void load() {
         System.out.println("Load bullets with AK");
     }
 }
复制代码

M4A1子弹类

代码语言:javascript
复制
 public class M4A1_Bullet implements Bullet {
     @Override
     public void load() {
         System.out.println("Load bullets with M4A1");
     }
 }
复制代码

创建工厂

代码语言:javascript
复制
public interface Factory{
     public Gun produceGun();
     public Bullet produceBullet();
 }
 
 public class AKFac implements Factory{
     public Gun produceGun(){
         return new AK();
     }
     public Bullet produceBullet(){
         return new AK_Bullet();
     }
 }
 
 public class M4A1Fac implements Factory{
     public Gun produceGun(){
         return new M4A1();
     }
     public Bullet produceBullet(){
         return new M4A1_Bullet();
     }
 }
复制代码

测试

代码语言:javascript
复制
public class Test{
     public static void main(String[] args){
          Factory factory;
          Gun gun;
          Bullet bullet;
          factory =new AKFac();
          bullet=factory.produceBullet();
          bullet.load();
          gun=factory.produceGun();
          gun.shooting(); 
     }
 }
复制代码

四. 总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/03/30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 简单工厂模式
  • 二. 工厂方法模式
    • 适用场景:
      • 角色分配
        • 代码示例
        • 三. 抽象工厂模式
          • 适用场景
            • 角色分配
              • 实例
              • 四. 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档