设计模式之工厂模式

工厂模式是Java中最常用的设计模式,包括简单工厂模式、工厂方法模式和抽象工厂模式。它提供了创建对象的最佳方式,避免暴露创建逻辑并解耦调用者。文章详细介绍了三种工厂模式的区别和应用场景,并讨论了在Spring开发中如何运用工厂模式实现IoC容器创建Bean。
摘要由CSDN通过智能技术生成

系列文章目录


前言

  工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离,工厂模式分为简单工厂模式工厂方法模式抽象工厂模式


工厂模式的核心

  • 将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。
  • 获取实例对象不用new,而是用工厂类创建对象

学习工厂模式的疑问

我们带着几个问题看工厂模式:

  • 三个工厂模式之间有什么区别?
  • 为什么要用工厂模式?或者工厂模式有什么好处?

工厂模式的三种模式:

简单工厂模式

  简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护

手机接口:

public interface Phone {
    void call();
}

两个实现类:

public class IPhone implements Phone {

    @Override
    public void call() {
        System.out.println("用苹果手机打电话");
    }
}
public class MPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用小米手机打电话");
    }
}

手机的工厂类:

public class PhoneFactory {
    public Phone createShape(String shapeType){
        if(shapeType == null){
            return null;
        }
        if(shapeType.equalsIgnoreCase("MPhone")){
            return new MPhone();
        } else if(shapeType.equalsIgnoreCase("IPhone")){
            return new IPhone();
        }
        return null;
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        PhoneFactory factory = new PhoneFactory();
        Phone MPhone = factory.createShape("MPhone");
        MPhone.call();
        Phone IPhone = factory.createShape("IPhone");
        IPhone.call();
    }
}

单工厂的优点/缺点

  • 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
  • 缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则

工厂方法模式

  工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节
在这里插入图片描述

手机工厂接口:

public interface PhoneFactory {
    Phone createPhone();
}

两个子工厂:

public class MPhoneFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new MPhone();
    }
}

public class IPhoneFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        Phone MPhone = new MPhoneFactory().createPhone();
        Phone IPhone = new IPhoneFactory().createPhone();
        MPhone.call();
        IPhone.call();
    }
}

抽象工厂模式

  上边的工厂方法模式是一种极端情况的抽象工厂模式(即只生产一种产品的抽象工厂模式),而抽象工厂模式可以看成是工厂方法模式的一种推广。
先理解产品族和产品等级

  • 产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。一个品牌下面的所有产品;例如康师傅下面的绿茶,冰红茶,方便面 称为康师傅的产品族;小米下面的手机,ipad 称为小米的产品族;
  • 产品等级:产品等级结构即产品的继承结构,如一个抽象类是绿茶,其子类有统一绿茶、康师傅绿茶,则抽象绿茶与具体品牌的绿茶之间构成了一个产品等级结构,抽象绿茶是父类,而具体品牌的绿茶是其子类。

在这里插入图片描述
实现抽象工厂模式

在这里插入图片描述

两个产品接口:

public interface Phone {
    void call();
}

public interface IPad {
    void play();

}

一个工厂接口:

public interface Factory {
    Phone createPhone();

    IPad createIPad();
}

四个产品实现类:

public class IPhone implements Phone {

    @Override
    public void call() {
        System.out.println("用苹果手机打电话");
    }
}

public class MPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用小米手机打电话");
    }
}
public class IIPad implements IPad {
    @Override
    public void play() {
        System.out.println("打开苹果ipad");
    }
}
public class MIPad implements IPad {
    @Override
    public void play() {
        System.out.println("打开小米ipad");
    }
}

两个工厂实现类:

public class IFactory implements Factory{
    @Override
    public Phone createPhone() {
        return new IPhone();
    }

    @Override
    public IPad createIPad() {
        return new IIPad();
    }
}

public class MFactory implements Factory{
    @Override
    public Phone createPhone() {
        return new MPhone();
    }

    @Override
    public IPad createIPad() {
        return new MIPad();
    }
}

如果增加产品族或产品等级会怎么样?

增加产品等级

在这里插入图片描述

增加产品族

在这里插入图片描述
可见扩展产品族,只需要增加新的实现类即可,不需要修改原来的代码,符合设计模式中的OCP原则(开闭原则),也就是对扩展开放,对修改关闭

工厂模式区别

  • 简单工厂 :用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
  • 工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
  • 抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)

为什么要用工厂模式,而不是直接new?

  首先是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。
  其次工厂模式可以降低代码重复。如果创建对象B的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。我们可以这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的创建过程的修改维护。

工厂模式适用的一些场景

  1. 对象的创建过程/实例化准备工作很复杂,需要初始化很多参数、查询数据库等。
  2. .类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。

Spring开发中的工厂设计模式

1.Spring IOC

  • 看过Spring源码就知道,在Spring IOC容器创建bean的过程是使用了工厂设计模式
  • Spring中无论是通过xml配置还是通过配置类还是注解进行创建bean,大部分都是通过简单工厂来进行创建的。
  • 当容器拿到了beanName和class类型后,动态的通过反射创建具体的某个对象,最后将创建的对象放到Map中。

2.为什么Spring IOC要使用工厂设计模式创建Bean呢

  • 在实际开发中,如果我们A对象调用B,B调用C,C调用D的话我们程序的耦合性就会变高。(耦合大致分为类与类之间的依赖,方法与方法之间的依赖。)
  • 在很久以前的三层架构编程时,都是控制层调用业务层,业务层调用数据访问层时,都是是直接new对象,耦合性大大提升,代码重复量很高,对象满天飞
  • 为了避免这种情况,Spring使用工厂模式编程,写一个工厂,由工厂创建Bean,以后我们如果要对象就直接管工厂要就可以,剩下的事情不归我们管了。Spring IOC容器的工厂中有个静态的Map集合,是为了让工厂符合单例设计模式,即每个对象只生产一次,生产出对象后就存入到Map集合中,保证了实例不会重复影响程序效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值