设计模式——工厂模式

定义:

​ 工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。

本章代码:小麻雀icknn/设计模式练习 - Gitee.com

工厂模式分三类

  1. 简单工厂模式(Simple Factory)
  2. 工厂方法模式(Factory Method)
  3. 抽象工厂模式(Abstract Factory)

在《设计模式》一书中工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。简单工厂模式(Simple Factory)

简单工厂

简单工厂,工厂模式定义:提供创建对象的接口。简单工厂模式(Simple Factory Pattern)属于类的创建型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂中的角色

1.Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

2.IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

3.Product:具体产品类,是简单工厂模式的创建目标。

简单理解:一个工厂(Factory工厂类),有一系列产品(IProduct抽象产品类),该系列产品都有哪种型号(Product具体产品类)

举例:

Factory:工厂类

java 复制代码
package com.study.main;

public class ToolFactory {
    public ToolInterface getTool(String name){
        if(name.equals("Tongs")){
           return new Tongs(name);
        }
        if(name.equals("Hammer")){
            return new Hammer(name);
        }
        return null;
    }
}

IProduct:抽象产品类

java 复制代码
package com.study.main;

public interface ToolInterface {
    public String name ();
    public void methods();
}

Product:具体产品类

java 复制代码
package com.study.main;

public class Hammer implements ToolInterface{
    public String name;

    public Hammer(String name) {
        this.name = name;
    }

    @Override
    public String name() {

        return this.name;
    }

    @Override
    public void methods() {
        System.out.println(this.name);
    }
}

public class Tongs implements ToolInterface{
    public String name;
    public Tongs(String name) {
        this.name = name;
    }
    @Override
    public String name() {

        return this.name;
    }

    @Override
    public void methods() {
        System.out.println(this.name);
    }
}

调用:

java 复制代码
package com.study.main;

public class FactoryMain {
    public static void main(String[] args) {
        ToolFactory toolFactory = new ToolFactory();
        ToolInterface tongs = toolFactory.getTool("Hammer");
        tongs.methods();
    }
}

优点:

  1. 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
  2. 客户端无需知道所创建具体产品的类名,只需知道参数即可。
  3. 也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。

缺点:

  1. 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
  2. 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度。
  3. 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
  4. 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。

违反了开闭原则,所以不常用

工厂方法模式

工厂方法模式属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义在于定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,仅负责声明具体工厂子类必须实现的接口。这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式的主要角色

  • Abstract Factory 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  • Concrete Factory 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • Product 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
  • Concrete Product 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

UML图

举例

抽象工厂 接口

java 复制代码
package com.study.main.FactoryMethod;

public interface Factory {
    void method();
}

抽象产品 接口

java 复制代码
package com.study.main.FactoryMethod;

public interface Tool {
    String name();
}

具体工厂1

java 复制代码
package com.study.main.FactoryMethod;

public class TongsFactory implements Factory{

    @Override
    public void method() {
        String tongs = new Tongs("Tongs").name();
        System.out.println(tongs);
    }
}

具体工厂 2

java 复制代码
package com.study.main.FactoryMethod;

public class HammerFactory implements Factory{
    @Override
    public void method() {
        String hammer = new Hammer("Hammer").name();
        System.out.println(hammer);
    }
}

具体产品1

java 复制代码
package com.study.main.FactoryMethod;

public class Tongs implements Tool{
    String name;

    public Tongs(String name) {
        this.name = name;
    }

    @Override
    public String name() {
        return this.name;
    }
}

具体产品2

java 复制代码
package com.study.main.FactoryMethod;

public class Hammer implements Tool{
    String name;

    public Hammer(String name) {
        this.name = name;
    }

    @Override
    public String name() {
        return this.name;
    }
}

调用

java 复制代码
package com.study.main.FactoryMethod;

import com.study.main.ToolFactory;

public class FactoryMethodMain {
    public static void main(String[] args) {
        new HammerFactory().method();
        new TongsFactory().method();
    }
}

优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:

  • 类的个数容易过多,增加复杂度。
  • 增加了系统的抽象性和理解难度。
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

抽象工厂

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

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式的主要角色

  • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
  • 抽象工厂:提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  • 具体工厂:主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。

UML图

例子:

抽象接口

java 复制代码
package com.study.main.AbstractFactory;

public interface AbstractFactory {
    Pencil createPencil();
    Eraser createEraser();
}
package com.study.main.AbstractFactory;

public interface Eraser {
    void erase();
}
package com.study.main.AbstractFactory;

public interface Pencil {
    void draw();
}

抽象类

java 复制代码
package com.study.main.AbstractFactory;

public class ChenGuangEraser implements Eraser{
    @Override
    public void erase() {
        System.out.println("----------ChenGuang Erase---------------");
    }
}

package com.study.main.AbstractFactory;

public class ChenguangFactory implements AbstractFactory{
    @Override
    public Pencil createPencil() {
        return new ChenGuangPencil();
    }

    @Override
    public Eraser createEraser() {
        return new ChenGuangEraser();
    }
}

package com.study.main.AbstractFactory;

public class ChenGuangPencil implements Pencil{
    @Override
    public void draw() {
        System.out.println("----------ChenGuang Draw---------------");
    }
}

package com.study.main.AbstractFactory;

public class TrueColorEraser implements Eraser{
    @Override
    public void erase() {
        System.out.println("----------TrueColor Erase---------------");
    }
}
package com.study.main.AbstractFactory;

public class TrueColorFactory implements AbstractFactory{

    @Override
    public Pencil createPencil() {
        return new TrueColorPencil();
    }

    @Override
    public Eraser createEraser() {
        return new TrueColorEraser();
    }
}

package com.study.main.AbstractFactory;

public class TrueColorPencil implements Pencil{
    @Override
    public void draw() {
        System.out.println("----------TrueColor Draw---------------");
    }
}

优点:

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

缺点:

  • 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
  • 模式的结构与实现
  • 抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。

Spring中的应用:

相关推荐
守护者1709 分钟前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云11 分钟前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络13 分钟前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。19 分钟前
Docker学习
java·开发语言·学习
如若12320 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
西猫雷婶1 小时前
python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶
开发语言·python·opencv
kiiila1 小时前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾1 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala