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

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

一、认识工厂模式


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


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


简单工厂模式:将被创建的对象称为"产品",把创建产品的对象称为"工厂",若是产品不多,可通过使用一个工厂类即可完成,若是出现新的产品,需要去修改原有的方法,这违法了开闭原则。由于在简单工厂中创建对象的方法是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种设计模式中)


好处:


相对于无工厂模式,我们不再通过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 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、工厂方法模式


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


优点:


用户只需要知道具体工厂的名称即可得到所需要的产品,无需知道产品创建的过程。

更具有灵活性,当新增产品时,我们只需要创建一个相对应的工厂类,满足开闭原则。

典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:


若是产品类过多,那么也就意味着创建对应数量的产品工厂,增加了复杂度。

增加了系统的抽象性和理解程度。

工厂方法模式实现:


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



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


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天前
|
设计模式 Java
【JAVA基础篇教学】第十四篇:Java中设计模式
【JAVA基础篇教学】第十四篇:Java中设计模式
|
2天前
|
设计模式 算法 Java
设计模式在Java开发中的应用
设计模式在Java开发中的应用
14 0
|
4天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
45 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
9天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
19 4
|
9天前
|
设计模式 存储 前端开发
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
24 4
|
Java 设计模式
亲身实践,JAVA最优良的Adapter模式--适配器模式
网上关于JAVA的适配器模式例子有很多,但真的有少实在不怎么样,看也不懂。自己总结了一个在性能和结构上都很容易理解的Adapter模式。 Adapter模式也叫适配器模式,是由GoF提出的23种设计模式的一种。
878 0
|
1天前
|
安全 Java
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解