栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式之工厂方法模式(Java实现)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式之工厂方法模式(Java实现)

文章目录
  • 前言
  • 一、认识工厂模式
  • 二、引出工厂模式
  • 三、工厂模式实现
    • 3.1、简单工厂模式
    • 3.2、工厂方法模式
  • 总结
  • 参考资料

前言

本篇博客是关于工厂方法模式的实现,若文章中出现相关问题,请指出!

对应代码地址:Gitee(demo-exer/ java-Lear23designpatterns)、Github(java-demo/ java-Lear23designpatterns)

所有博客文件目录索引:博客目录索引(持续更新)


一、认识工厂模式

工厂模式定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂中,实现了创建者与调用者的分离!

工厂模式分类:简单工厂模式、工厂方法模式、抽象工厂模式。

  • 简单工厂模式:将被创建的对象称为"产品",把创建产品的对象称为"工厂",若是产品不多,可通过使用一个工厂类即可完成,若是出现新的产品,需要去修改原有的方法,这违法了开闭原则。由于在简单工厂中创建对象的方法是static,所以又被称为静态工厂模式。该模式并不算在GoF23种设计模式之中。
    • 应用场景:Spring中的BeanFactory。
  • 工厂方法模式:解决了简单工厂模式违反开闭原则,在工厂方法模式中每一个产品都对应着一个工厂类,满足了开闭原则,就是需要付出更多的代价,若是产品特别多那么整体代码量会巨大。
    • 应用场景:Spring与Mybatis的结合(FactoryBean接口)。
  • 抽象工厂模式:围绕一个超级工厂来创建其他工厂,该超级工厂又称为其他工厂的工厂。


二、引出工厂模式

我们通常去创建一个对象的实例需要通过自己去手动new来创建实例,这种方式又称为无工厂模式,对于一些较复杂且需要多项配置时就比较头疼了,需要一个个填入到构造器中,造成不必要的麻烦!

下面代码就通过手动new的方式来获取实例:

interface Car {
    void name();
}

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

//保时捷
class Porsche implements Car{
    @Override
    public void name() {
        System.out.println("保时捷");
    }
}

//消费者
public class Customer {

    public static void main(String[] args) {
        //通过手动new的方式来获取产品实例
        Car bmw = new BMW();
        Car porsche = new Porsche();
        bmw.name();
        porsche.name();
    }
}

在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替!



三、工厂模式实现 3.1、简单工厂模式

简单工厂模式:由于工厂的方法是static所以也叫做静态工厂模式。简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。(但该模式并不在GoF23种设计模式中)

好处:

  1. 相对于无工厂模式,我们不再通过new来获取自己想要创建的实例,而是通过一个工厂类方法,只需要传入指定的参数就能够获取到我们想要的对象实例。
  2. 使用工厂方法时无需只要知道执行的类名,只需要知道能够创建实例的参数即可。

缺点:

  1. 一旦新增产品,我们就需要回到原有的工厂类创建实例方法中进行修改,否则无法扩展其他产品,这违反开闭原则(扩展功能,不要修改原来的方法)。
  2. 简单工厂模式工厂类单一,负责所有产品的创建,职责过重一旦出现异常整个系统都会受到影响,若是产品量过多,工厂类创建实例方法会非常臃肿。违法了单一职责原则。

应用场景:

  • 对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

简单工厂模式实现:

interface Car {
    void name();
}

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

//保时捷
class Porsche implements Car{
    @Override
    public void name() {
        System.out.println("保时捷");
    }
}

public class CarFactory {
    
    //传入指定名称来获取具体产品实例
    public static Car getCar(String name){
        if("宝马".equals(name)){
            return new BMW();
        }else if("保时捷".equals(name)){
            return new Porsche();
        }
        return null;
    }
}


public class Main {
    public static void main(String[] args){
        //通过工厂类来创建指定产品实例
        Car bmw = CarFactory.getCar("宝马");
        Car porsche = CarFactory.getCar("保时捷");
        bmw.name();
        porsche.name();
    }
}
  • 添加了一个汽车工厂类CarFactory,其中添加一个创建产品方法getCar()根据传入参数来创建实例。
  • 其中工厂创建方法通过if..else来判断创建也可以使用switch.case.进行创建。

说明:在简单工厂模式中,若是增加了其他产品则需要回到原来的方法中进行修改操作,这就违背了开闭原则,之后通过工厂方法模式则能够遵守该规则。不过有一说一,对于这种简单工厂模式在实际应用中会大量使用。



3.2、工厂方法模式

工厂方法模式:是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则,但是需要付出一定代价(对于产品很多并且零件很多情况下,造成创建工厂类过多情况)。

优点:

  1. 用户只需要知道具体工厂的名称即可得到所需要的产品,无需知道产品创建的过程。
  2. 更具有灵活性,当新增产品时,我们只需要创建一个相对应的工厂类,满足开闭原则。
  3. 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:

  1. 若是产品类过多,那么也就意味着创建对应数量的产品工厂,增加了复杂度。
  2. 增加了系统的抽象性和理解程度。

工厂方法模式实现:

在工厂方法模式中,我们添加一个工厂接口,一个产品对应一个工厂类,该工厂类实现该接口,顾客则通过指定产品的工厂类方法来获取产品实例,可见下图:

通过使用一个接口来规范工厂的获取实例方法:

interface Car {
    void name();
}

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

//保时捷
class Porsche implements Car{
    @Override
    public void name() {
        System.out.println("保时捷");
    }
}

//新增一个工厂接口
interface Factory{
    Car getCar();
}

public class BMWFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new BMW();
    }
}

public class PorscheFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Porsche();
    }
}


public class Main {
    public static void main(String[] args){
        //通过对应产品的工厂类来获取实例
        Car bmw = new BMWFactory().getCar();
        Car porsche = new PorscheFactory().getCar();
        bmw.name();
        porsche.name();
    }
}

看一下多个接口及类的UML图:

我们能够看到结构变得更加清晰了,想要哪个汽车类型即可从对应类型的工厂中拿到,但是随着产品的增多,工厂类也会增多,增加了复杂度。



总结

简单工厂模式(静态工厂模式):其并不属于GoF23种设计模式的范畴中,并在某种程度上并不符合设计原则,但实际使用最多。

工厂方法模式:符合开闭原则,当添加新的产品时不需要更改原有的方法代码,直接通过增加新的工厂类实现扩展。

这两种模式都是针对于某个产品!



参考资料

[1]. C语言中文网—简单工厂模式


我是长路,感谢你的耐心阅读。如有问题请指出,我会积极采纳!
欢迎关注我的公众号【长路Java】,分享Java学习文章及相关资料
Q群:851968786 我们可以一起探讨学习
注明:转载可,需要附带上文章链接

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854447.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号