03-JAVA设计模式-工厂模式详解

工厂模式

工厂设计模式是一种创建型设计模式,它提供了一种封装对象创建过程的机制,将对象的创建与使用分离。
这种设计模式允许我们在不修改客户端代码的情况下引入新的对象类型。
在Java中,工厂设计模式主要有三种形式:简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂模式

用来生成同一等级结构中的任意产品。

注:对增加新的产品需要修改已有的代码,这违背了面向对象设计原则中的开闭原则(对扩展开放,对修改关闭)

UML

在这里插入图片描述

实现代码

Animal.java

// 定义一个动物的接口
public interface Animal {// 接口中定义一个抽象的方法:叫声void makeSound();
}

Cat.java

// 定义一个实现类实现Animal接口
public class Cat implements Animal{// 猫属于动物:实现发出叫声的接口@Overridepublic void makeSound() {System.out.println("喵喵喵");}
}

Dog.java

// 定义一个实现类实现Animal接口
public class Dog implements Animal{// 狗属于动物:实现发出叫声的接口@Overridepublic void makeSound() {System.out.println("汪汪汪");}
}

SimpleAnimalFactory.java

// 定义一个简单工厂类用于创建动物
public class SimpleAnimalFactory {// 定义一个创建动物的方法用于生产不同的动物的静态方法public static Animal createAnimal(String type) {if ("Cat".equalsIgnoreCase(type)) {return new Cat();}else if ("Dog".equalsIgnoreCase(type)) {return new Dog();}else  {return null;}}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 根据简单工厂创建不同的动物,执行动作// 生产一个CatAnimal cat = SimpleAnimalFactory.createAnimal("cat");cat.makeSound();// 生产一个DogAnimal dog = SimpleAnimalFactory.createAnimal("Dog");dog.makeSound();}
}

执行结果:

在这里插入图片描述

结论:

简单工厂好处在于,对于客户端调用时,我们不需要关心具体实现,只需要调用工厂方法,传入参数获取我们需要返回的结果即可。

但是对于同一个产品(动物),如果我们进行新增(猪),则必须要修改Factory中createAnimal(String type)方法。因此违背了开闭原则

工厂方法模式

用来生产同一等级结构中的固定产品。

支持增加任意产品,满足开闭原则,但设计相对于简单工厂复杂一些

UML

在这里插入图片描述

实现代码

Product.java

// 定义一个产品接口
public interface Product {//定义一个抽象的使用的方法void use();
}

ProductA.java

// ProductA实现Product接口
public class ProductA implements Product{@Overridepublic void use() {System.out.println("ProductA 使用了");}
}

ProductB.java

// ProductB实现Product接口
public class ProductB implements Product{@Overridepublic void use() {System.out.println("ProductB 使用了");}
}

ProductFactory.java

// 定义一个ProductFactory工厂接口
public interface ProductFactory {// 接口中定义一个创建Product的方法Product createProduct();
}

ProductAFactory.java

// 创建一个ProductA的工厂,实现ProductFactory接口,用于生产ProductA
public class ProductAFactory implements ProductFactory{@Overridepublic Product createProduct() {return new ProductA();}
}

ProductBFactory.java

// 创建一个ProductB的工厂,实现ProductFactory接口,用于生产ProductB
public class ProductBFactory implements ProductFactory{@Overridepublic Product createProduct() {return new ProductB();}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 创建ProductAProduct product1 = new ProductAFactory().createProduct();product1.use();// 创建ProductBProduct product2 = new ProductBFactory().createProduct();product2.use();}
}

执行结果:

在这里插入图片描述

从工厂方式模式,我们可以看出,我们可以任意增加同一产品,而不会影响到原来已有产品
(创建一个产品C继承Product接口,创建一个产品C的Factory类生产C,使用是通过相应Factory调用生产C即可)。
如果产品中新增一个方法,则所有实现了Product接口的方法都必须修改相应方法。

抽象工厂模式

用来生产不同产品族的全部产品。

对增加新的产品无能为力,支持增加产品族

UML

在这里插入图片描述

实现代码

Engine.java

// 定义发动机接口
public interface Engine {// 定义发动机 发动方法void run();// 定义发动机 停止方法void stop();
}

HighEndEngine.java

// 创建一个高端发动机实现发动机
public class HighEndEngine implements Engine{@Overridepublic void run() {System.out.println("高端发动机-跑的快");}@Overridepublic void stop() {System.out.println("高端发动机-刹车性能强");}
}

LowEndEngine.java

// 创建一个低端发动机实现发动机
public class LowEndEngine implements Engine{@Overridepublic void run() {System.out.println("低端发动机-跑的慢");}@Overridepublic void stop() {System.out.println("低端发动机-刹车性能弱");}
}

CarBody.java

// 定义一个车身接口
public interface CarBody {// 定义一个乘坐的方法void ride();
}

HighEndCarBody.java

// 创建一个高端车身实现车身
public class HighEndCarBody implements CarBody{@Overridepublic void ride() {System.out.println("高端车身-奢华-安全");}
}

LowEndCarBody.java

// 创建一个低端车身实现车身
public class LowEndCarBody implements CarBody{@Overridepublic void ride() {System.out.println("低端车身-朴素-看起来安全");}
}

Tyre.java

// 定义一个轮胎接口
public interface Tyre {// 定义轮胎转动的方法void run();
}

HighEndTyre.java

// 创建一个高端轮胎实现轮胎
public class HighEndTyre implements Tyre{@Overridepublic void run() {System.out.println("高端轮胎-太空材料-安全-耐磨");}
}

LowEndTyre.java

// 创建一个低端轮胎实现轮胎
public class LowEndTyre implements Tyre{@Overridepublic void run() {System.out.println("低端轮胎-普通材料-易磨损");}
}

CarFactory.java

// 定义Car的接口
public interface CarFactory {// 创建发动机Engine engine();// 创建车身CarBody carBody();// 创建轮胎Tyre tyre();
}

HighEndCarBody.java

// 高端汽车工厂实现汽车工厂
public class HighEndCarFactory implements CarFactory{@Overridepublic Engine engine() {return new HighEndEngine();}@Overridepublic CarBody carBody() {return new HighEndCarBody();}@Overridepublic Tyre tyre() {return new HighEndTyre();}
}

LowEndCarFactory.java

// 低端汽车工厂实现汽车工厂
public class LowEndCarFactory implements CarFactory{@Overridepublic Engine engine() {return new LowEndEngine();}@Overridepublic CarBody carBody() {return new LowEndCarBody();}@Overridepublic Tyre tyre() {return new LowEndTyre();}
}

TestClient.java

public class TestClient {public static void main(String[] args) {// 使用高端汽车工厂类 创建高端汽车HighEndCarFactory highEndCar = new HighEndCarFactory();highEndCar.engine().stop();highEndCar.carBody().ride();highEndCar.tyre().run();System.out.println("==========================");// 使用低端汽车工厂类 创建低端汽车LowEndCarFactory lowEndCar = new LowEndCarFactory();lowEndCar.engine().stop();lowEndCar.carBody().ride();lowEndCar.tyre().run();}
}

执行结果:

在这里插入图片描述

抽象工厂,不可以增加产品(比如:CarFactory一旦定下了,如果我们要新增新的部件则所有实现CarFactory的类都需实现该方法)。
但是抽象工厂,可以根据已有的接口,创建更多的产品族(比如:定义一个中端汽车工厂,调用高端发动机,低端轮胎,低端车身,等任意组合成新的Factory)

对比及应用场景

简单工厂模式

  • 优点:
    • 实现了对象的创建和使用的责任分割,客户端只需要传入正确的参数,就可以获取需要的对象,无需知道创建细节。
    • 工厂类中有必要的判断逻辑,可以决定根据当前的参数创建对应的产品实例,客户端可以免除直接创建产品对象的责任。
  • 缺点:
    • 工厂类职责过重,如果产品种类增加,工厂类的代码会变得庞大且复杂,不利于维护。
    • 简单工厂模式违背了开放封闭原则,因为每次增加新产品时,都需要修改工厂类的代码。
  • 适用场景:
    • 创建对象较少,且对象的创建逻辑不复杂时。
    • 客户端不关心对象的创建过程,只关心使用对象时。

工厂方法模式

  • 优点:
    • 将对象的创建推迟到子类中进行,使得类的实例化更加灵活和可扩展。
    • 降低了客户端与具体产品类之间的耦合度,客户端只需要知道对应的工厂,无需知道具体的产品类。
  • 缺点:
    • 增加了系统的抽象性和理解难度,需要引入额外的工厂接口和工厂类。
    • 如果产品类较少,使用工厂方法模式可能会增加不必要的复杂性。
  • 适用场景:
    • 需要创建大量相似对象时,可以使用工厂方法模式来简化对象的创建过程。
    • 当一个类需要由其子类来指定创建哪个对象时,可以使用工厂方法模式。
    • 但实际开发中,简单工厂比工厂方法使用的更多

抽象工厂模式

  • 优点:
    • 提供了创建一系列相关或相互依赖对象的接口,无需指定它们具体的类。
    • 增加了系统的灵活性和可扩展性,可以通过更换不同的工厂来实现不同的产品族。
  • 缺点:
    • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难。
    • 如果产品族中的产品较少,使用抽象工厂模式可能会导致代码冗余和复杂性增加。
  • 适用场景:
    • 当需要创建一组相互关联或相互依赖的对象时,可以使用抽象工厂模式。
    • 当一个系统需要独立地变化其创建的对象时,抽象工厂模式是一个很好的选择。

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/596447.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实时渲染 -- 材质(Materials)

一、自然界中的材质 首先了解下自然界中的材质 如上这幅图,不同的物体、场景、组合,会让我们看到不同的效果。 我们通常认为物体由其表面定义,表面是物体和其他物体或周围介质之间的边界面。但是物体内部的材质也会影响光照效果。我们目前只…

golang设计模式图解——命令模式

设计模式 GoF提出的设计模式有23个,包括: (1)创建型(Creational)模式:如何创建对象; (2)结构型(Structural )模式:如何实现类或对象的组合; (3&a…

【C++初阶】String在OJ中的使用(一):仅仅反转字母、字符串中的第一个唯一字母、字符串最后一个单词的长度、验证回文串、字符串相加

前言: 🎯个人博客:Dream_Chaser 🎈博客专栏:C 📚本篇内容:仅仅反转字母、字符串中的第一个唯一字母、字符串最后一个单词的长度、验证回文串、字符串相加 目录 917.仅仅反转字母 题目描述&am…

Flutter 解决NestedScrollView与TabBar双列表滚动位置同步问题

文章目录 前言一、需要实现的效果如下二、flutter实现代码如下:总结 前言 最近写flutter项目,遇到NestedScrollView与TabBar双列表滚动位置同步问题,下面是解决方案,希望帮助到大家。 一、需要实现的效果如下 1、UI图&#xff1…

数据结构之堆底层实现的循序渐进

题外话 把没写的都补回来! 正题 堆 概念 堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储, 大根堆:指根结点比左右孩子都大的堆 小根堆:指根结点比左右孩子都小的堆 性质 1.堆中某个节点的值总是不大于或不小于其父节点的值 2…

上位机图像处理和嵌入式模块部署(qmacvisual实时视频)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们测试和练习的时候,大部分情况下都是利用图像进行测试的,但是实际情况下,或者准确一点说,工…

如何在 Ubuntu 上安装和配置 Tomcat 服务器?

简介:最近有粉丝朋友在问如何在 Ubuntu 上安装和配置 Tomcat 服务器?今天特地写这篇文章进行解答,希望能够帮助到大家。 文章目录 Ubuntu上安装和配置Tomcat的详细步骤Tomcat在Linux环境下的安装与配置一、下载并上传Tomcat压缩包二、启动To…

第1个Django应用及Django的请求处理

Python学习之路系列文章目录 python面向对象之警察与匪徒火拼场景模拟python面向对像之第二次笔记Django环境搭建及测试第1个Django应用及Django的请求处理 第1个Django应用及Django的请求处理 Python学习之路系列文章目录一、PyCharm创建django项目二、创建app什么是app怎么创…

设计模式之建造者模式:灵活可扩展的对象创建过程

目录 一、什么是建造者模式 二、建造者模式的应用场景 三、建造者模式的优缺点 3.1. 优点 3.2. 缺点 四、建造者模式示例 4.1. 问题描述 4.2. 问题分析 4.3. 代码实现 五、建造者模式的另一种实现方式 六、总结 一、什么是建造者模式 建造者模式(Builder…

016——DHT11驱动开发(基于I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 电路描述 1.3 通信协议 二、 驱动程序 三、 应用程序 四、 上机实验 一、 模块介绍 1.1 简介 DHT11 是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器,会测量空气中湿度,再根据测量结果决定是否继续加…

Vue-Router入门

现在的前后端分离项目,后端只管数据传递,视图跳转的活交由前端来干了,vue-router就是专门来干这个活的,它可以让页面跳转到指定组件 组件是可复用的 Vue 实例, 把一些公共的模块抽取出来,然后写成单独的的工具组件或者…

基于沙漏 Tokenizer 的高效三维人体姿态估计框架HoT

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读:基于沙漏 Tokenizer 的高效三维人体姿态估计框架HoT1、研究背景2、提出方法3、模块详细3.1、什么是HoT3.2、HoT 框架3.3、Token 剪…