Java工厂模式的深入了解

 更新时间:2022年01月05日 16:53:17   作者:空山新雨后~  
这篇文章主要为大家介绍了Java工厂模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

一、简单工厂模式

何为简单工厂模式?

首先先通过一个案例来理解

我有一个需求,要买车,买车有不同的型号,那么我们常见的做法就是我买车点有什么车我就买什么车,实例如下

定义一个车接口

 
public interface Car {
    void name();
}

定义一个实现类,例如宝马

public class Baoma implements Car {
 
    @Override
    public void name() {
        System.out.println("宝马");
    }
}

测试

public class Test {
    public static void main(String[] args) {
        
        Car car3 = new Baoma();
        car3.name();

 结果:宝马

很显然这并不符合我们工厂设计模式的思想,我们不应该让用户去new一个车出来,现实生活中也不可能自己去new一个车然后自己买,对不对,因此我们要设计一个简单的工厂来满足我们的需求,

简单工厂类

public class CarFactory {
    public static Car getCar(String car) {
        if(car.equals("宝马")) {
            return new Baoma();
        }else if(car.equals("奥迪")) {
            return new AoDI();
        }
        return null;
    }
}

测试

 Car car = CarFactory.getCar("宝马");
        car.name();
 
        Car car1 = CarFactory.getCar("奥迪");
        car1.name();

结果:宝马 奥迪

那么此时我们用户就不需要去关心我们的车是怎么来的,车该怎么造出来,造出来是什么车,我用户只管从工厂中去拿出我们需要的车即可,如果没有,再从工厂中去添加

         

该图是对简单工厂模式的一个辅助理解。     

总结一下,简单工厂模式: 用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)                  

二、工厂方法模式

那么在简单工厂类大家应该发现了一个问题,如果我们需要添加一辆新车,就需要进入工厂修改工厂的代码,如果我们修改了我们的代码,那么久违反了我们设计模式的开闭原则,不好,那么我们就来到了我们的工厂方法模式。

何为工厂方法模式,示例如下:

其中车类和车接口不变,我们改变一下车工厂

我们定义一个车接口,方法返回一辆车

public interface CarFactory {
    Car getCar();
}

那么我们可以想就是给每个车都配一个车工厂,那么添加的时候,只需要在新添加一个车工厂,去实现这个车工厂接口即可

奥迪工厂

public class AoDIFactory implements CarFactory{
 
    @Override
    public Car getCar() {
        return new AoDI();
    }
}

宝马工厂我就不演示了。

测试

        Car baoma = new BaoMaFactory().getCar();
        Car Aodi = new AoDIFactory().getCar();
 
        baoma.name();
        Aodi.name();

 

那么此时如果我们要添加新车,我们只需要去添加他的车以及他的工厂即可,用户则只需要去找对应的工厂

 

总结一下,

工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)

三、抽象工厂模式

前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。

同种类称为同等级,也就是说:工厂方法模式中只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。

这里需要先了解一个定义:

产品族:将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族

如图所示

3.1、抽象工厂模式的定义

是一种为访问类提供一个创建一组相关或相互依赖对象接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

使用抽象工厂模式一般要满足以下条件

可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组
抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。

当然使用抽象工厂模式也是有缺点的:        

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。

3.2、  抽象工厂模式的结构

1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。

2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。

3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。

4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

3.3抽象工厂模式代码示例

首先我们去定义抽象产品

比如

 * @Description 车接口
 */
public interface Car {
    void startCar();
    void stopCar();
    void washCar();
}
 * @Description 车载音响类
 */
public interface CarAudio {
    void startCarAudio();
    void stopCarAudio();
}

提供具体的产品

 * @Description 奥迪车
 */
public class AodiCar implements Car {
    @Override
    public void startCar() {
        System.out.println("启动奥迪车");
    }
 
    @Override
    public void stopCar() {
        System.out.println("关闭奥迪车");
    }
 
    @Override
    public void washCar() {
        System.out.println("洗奥迪车");
    }
}
 * @Description 奥迪车载音响
 */
public class AodiCarAudio implements CarAudio{
 
    @Override
    public void startCarAudio() {
        System.out.println("开启奥迪车载音响");
    }
 
    @Override
    public void stopCarAudio() {
        System.out.println("关闭奥迪车载音响");
    }
}
 * @Description 宝马车
 */
public class BaomaCar implements Car{
    @Override
    public void startCar() {
        System.out.println("开启宝马");
    }
 
    @Override
    public void stopCar() {
        System.out.println("停下宝马");
    }
 
    @Override
    public void washCar() {
        System.out.println("洗宝马");
    }
}
 * @Description 宝马车载音响
 */
public class BaomaCarAudio implements CarAudio{
    @Override
    public void startCarAudio() {
        System.out.println("打开宝马车载音响");
    }
 
    @Override
    public void stopCarAudio() {
        System.out.println("关闭宝马车载音响");
    }
}

提供抽象的工厂

 * @Description 产品工厂接口
 */
public interface ProductFactory {
    Car ProductCar();
    CarAudio ProductCarAudio();
}

提供具体的工厂

 * @Description 宝马工厂
 */
public class BaomaFactory implements ProductFactory{
 
    @Override
    public Car ProductCar() {
        return new BaomaCar();
    }
 
    @Override
    public CarAudio ProductCarAudio() {
        return new BaomaCarAudio();
    }
}
 * @Description aodi工厂
 */
public class AodiFactory implements ProductFactory{
    @Override
    public Car ProductCar() {
        return new AodiCar();
    }
 
    @Override
    public CarAudio ProductCarAudio() {
        return new AodiCarAudio();
    }
}

客户测试类

 * @Description 消费者类
 */
public class Customer {
    public static void main(String[] args) {
        System.out.println("--------奥迪系列---------");
        //获得奥迪工厂
        AodiFactory aodiFactory = new AodiFactory();
        Car car = aodiFactory.ProductCar();
        CarAudio carAudio = aodiFactory.ProductCarAudio();
        car.startCar();
        car.stopCar();
        carAudio.startCarAudio();
 
 
        System.out.println("--------宝马系列---------");
 
        BaomaFactory baomaFactory = new BaomaFactory();
        Car carBaoma = baomaFactory.ProductCar();
        CarAudio carAudioBaoma = baomaFactory.ProductCarAudio();
        carBaoma.stopCar();
        carBaoma.washCar();
        carAudioBaoma.startCarAudio();
 
    }
}

输出结果

        --------奥迪系列---------
启动奥迪车
关闭奥迪车
开启奥迪车载音响
--------宝马系列---------
停下宝马
洗宝马
打开宝马车载音响

idea中类图关系

如果我们要新增产品,需在总工厂去添加方法,而且其他的类也会修改,印证了我们之前写到的缺点,

总结一下:

抽象工厂模式就是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂

四、小结

工厂模式的核心本质

实例化对象不使用new,用工厂方法代替

将选择实现类,创建对象时统一管理和控制,从而将调用者跟我们的实现类解耦

简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)

工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)

抽象工厂模式:围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • java控制台输出图书馆管理系统

    java控制台输出图书馆管理系统

    这篇文章主要为大家详细介绍了java控制台输出图书馆管理系统,只用java代码不用数据库和GUI等,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 详解java==运算符和equals()方法的区别

    详解java==运算符和equals()方法的区别

    这篇文章主要介绍了java==运算符和equals()方法的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Java SpringBoot 使用拦截器作为权限控制的实现方法

    Java SpringBoot 使用拦截器作为权限控制的实现方法

    这篇文章主要介绍了Java SpringBoot 使用拦截器作为权限控制的实现,文中通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • IDEA插件推荐之Maven-Helper的教程图解

    IDEA插件推荐之Maven-Helper的教程图解

    这篇文章主要介绍了IDEA插件推荐之Maven-Helper的相关知识,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考
    2020-07-07
  • Java如何找出数组中重复的数字

    Java如何找出数组中重复的数字

    这篇文章主要为大家详细介绍了Java如何找出数组中重复的数字,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • springboot中一些比较常用的注解总结

    springboot中一些比较常用的注解总结

    今天给大家带来的是关于Java的相关知识,文章围绕着springboot中一些比较常用的注解展开,文中有非常详细的总结,需要的朋友可以参考下
    2021-06-06
  • SpringBoot中MyBatis-Flex的集成和使用实现

    SpringBoot中MyBatis-Flex的集成和使用实现

    MyBatis-Flex是一个基于MyBatis的数据访问框架,MyBatis-Flex能够极大地提高我们的开发效率和开发体验,本文主要介绍了SpringBoot中MyBatis-Flex的集成和使用实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 快速搭建一个SpringBoot项目(纯小白搭建教程)

    快速搭建一个SpringBoot项目(纯小白搭建教程)

    本文主要介绍了快速搭建一个SpringBoot项目,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • java 实现随机数组输出及求和实例详解

    java 实现随机数组输出及求和实例详解

    这篇文章主要介绍了java 实现随机数组输出及求和实例详解的相关资料,需要的朋友可以参考下
    2016-11-11
  • sms4j 2.0 全新来袭功能的调整及maven变化详解

    sms4j 2.0 全新来袭功能的调整及maven变化详解

    这篇文章主要介绍了sms4j 2.0 全新来袭功能的调整及maven变化详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论