工厂模式:简化对象的创建过程

news2024/9/20 10:47:25

工厂模式:简化对象的创建过程

介绍

在软件开发中,对象的创建是一个常见的操作。通常情况下,我们可以直接使用 new 关键字来创建对象,但是在某些情况下,对象的创建过程可能会比较复杂,涉及到多个步骤或者依赖关系。这时候,使用工厂模式可以帮助我们简化对象的创建过程。

工厂模式是一种创建型设计模式,它提供了一种封装对象创建过程的方式,使得客户端代码不需要直接依赖具体的类来创建对象。通过使用工厂模式,我们可以将对象的创建逻辑抽象出来,使得客户端代码只需要与工厂接口进行交互,而不需要关心具体的对象创建细节。

优点

1. 封装对象创建过程

工厂模式将对象的创建过程封装在工厂类中,客户端代码只需要与工厂接口进行交互,而不需要关心具体的对象创建细节。这样可以降低客户端代码的复杂性,提高代码的可维护性和可读性。

2. 解耦客户端代码和具体类

使用工厂模式可以将客户端代码与具体的类解耦。客户端代码只需要依赖工厂接口,而不需要依赖具体的类。这样可以提高代码的灵活性,使得客户端代码可以在不修改代码的情况下切换不同的实现类。

3. 可扩展性

工厂模式可以很容易地扩展新的产品类。只需要创建一个新的具体工厂类,并实现工厂接口即可。这样可以在不修改现有代码的情况下引入新的产品类。

三种实现

  1. 简单工厂模式(Simple Factory Pattern):
    • 优点:
      • 实现了对象的创建和使用的分离,客户端只需要通过工厂类来创建对象,而不需要知道具体的创建细节。
      • 可以根据需要动态地创建不同类型的对象。
    • 缺点:
      • 工厂类集中了所有对象的创建逻辑,当需要添加新的产品时,需要修改工厂类的代码,违反了开闭原则。
      • 工厂类的职责过重,违反了单一职责原则。
  2. 工厂方法模式(Factory Method Pattern):
    • 优点:
      • 将对象的创建延迟到子类中,每个子类都可以根据需要创建自己的对象,符合开闭原则。
      • 客户端只需要关心所需产品的接口,而不需要关心具体的实现类。
    • 缺点:
      • 需要定义一个工厂接口和多个具体工厂类,增加了系统的复杂度。
      • 每个具体工厂类只能创建一种类型的对象,如果需要创建多种类型的对象,需要增加更多的具体工厂类。
  3. 抽象工厂模式(Abstract Factory Pattern):
    • 优点:
      • 提供了一个接口,用于创建相关或依赖对象的家族,可以创建多个不同类型的对象。
      • 客户端通过抽象接口使用具体工厂创建的对象,与具体工厂的实现解耦。
    • 缺点:
      • 增加新的产品族比较困难,需要修改抽象工厂的接口和所有具体工厂的实现类。

接下来我们以电子产品制造为例来解释简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂模式

在简单工厂模式中,我们有一个工厂类,根据客户端的请求创建不同类型的产品。在电子产品制造的例子中,我们有三种产品:手机、电视和电脑。工厂类根据客户端的请求创建对应的产品。
在这里插入图片描述

// 抽象产品:电子产品
interface ElectronicProduct {
    void produce();
}

// 具体产品:手机
class Phone implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing Phone");
    }
}

// 具体产品:电视
class TV implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing TV");
    }
}

// 具体产品:电脑
class Computer implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing Computer");
    }
}

// 简单工厂类
class ElectronicProductFactory {
    public static ElectronicProduct createProduct(String type) {
        if (type.equals("phone")) {
            return new Phone();
        } else if (type.equals("tv")) {
            return new TV();
        } else if (type.equals("computer")) {
            return new Computer();
        } else {
            throw new IllegalArgumentException("Invalid product type");
        }
    }
}

public class Client{
    public static void main(String[] args) {
        ElectronicProduct phone = ElectronicProductFactory.createProduct("phone");
        phone.produce(); // Output: Producing Phone

        ElectronicProduct tv = ElectronicProductFactory.createProduct("tv");
        tv.produce(); // Output: Producing TV

        ElectronicProduct computer = ElectronicProductFactory.createProduct("computer");
        computer.produce(); // Output: Producing Computer
    }
}

在这个例子中,我们使用了一个简单工厂类ElectronicProductFactory,根据客户端传入的产品类型来创建对应的产品对象。客户端只需要知道产品的类型,而不需要关心具体的创建过程。

工厂方法模式

在工厂方法模式中,我们将每种产品的创建过程交给具体的工厂类来实现。在电子产品制造的例子中,我们有三种产品:手机、电视和电脑。每种产品都有对应的工厂类来创建。
在这里插入图片描述

// 抽象产品:电子产品
interface ElectronicProduct {
    void produce();
}

// 具体产品:手机
class Phone implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing Phone");
    }
}

// 具体产品:电视
class TV implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing TV");
    }
}

// 具体产品:电脑
class Computer implements ElectronicProduct {
    public void produce() {
        System.out.println("Producing Computer");
    }
}

// 抽象工厂:电子产品工厂
interface ElectronicProductFactory {
    ElectronicProduct createProduct();
}

// 具体工厂:手机工厂
class PhoneFactory implements ElectronicProductFactory {
    public ElectronicProduct createProduct() {
        return new Phone();
    }
}

// 具体工厂:电视工厂
class TVFactory implements ElectronicProductFactory {
    public ElectronicProduct createProduct() {
        return new TV();
    }
}

// 具体工厂:电脑工厂
class ComputerFactory implements ElectronicProductFactory {
    public ElectronicProduct createProduct() {
        return new Computer();
    }
}

public class Client {
    public static void main(String[] args) {
        ElectronicProductFactory phoneFactory = new PhoneFactory();
        ElectronicProduct phone = phoneFactory.createProduct();
        phone.produce(); // Output: Producing Phone

        ElectronicProductFactory tvFactory = new TVFactory();
        ElectronicProduct tv = tvFactory.createProduct();
        tv.produce(); // Output: Producing TV

        ElectronicProductFactory computerFactory = new ComputerFactory();
        ElectronicProduct computer = computerFactory.createProduct();
        computer.produce(); // Output: Producing Computer
    }
}

在这个例子中,我们定义了一个抽象工厂接口ElectronicProductFactory,每个具体产品都有对应的工厂类来实现ElectronicProductFactory接口。客户端根据需要选择对应的工厂类来创建产品。

抽象工厂模式

在抽象工厂模式中,我们有多个抽象产品和多个抽象工厂,每个抽象工厂负责创建一组相关的产品。在电子产品制造的例子中,我们有两种产品:手机和电视,每种产品都有对应的工厂来创建。
在这里插入图片描述

// 抽象产品:手机
interface Phone {
    void produce();
}

// 具体产品:苹果手机
class ApplePhone implements Phone {
    public void produce() {
        System.out.println("Producing Apple Phone");
    }
}

// 具体产品:三星手机
class SamsungPhone implements Phone {
    public void produce() {
        System.out.println("Producing Samsung Phone");
    }
}

// 抽象产品:电视
interface TV {
    void produce();
}

// 具体产品:小米电视
class XiaomiTV implements TV {
    public void produce() {
        System.out.println("Producing Xiaomi TV");
    }
}

// 具体产品:索尼电视
class SonyTV implements TV {
    public void produce() {
        System.out.println("Producing Sony TV");
    }
}

// 抽象工厂:电子产品工厂
interface ElectronicProductFactory {
    Phone createPhone();
    TV createTV();
}

// 具体工厂:苹果工厂
class AppleFactory implements ElectronicProductFactory {
    public Phone createPhone() {
        return new ApplePhone();
    }

    public TV createTV() {
        return new XiaomiTV();
    }
}

// 具体工厂:三星工厂
class SamsungFactory implements ElectronicProductFactory {
    public Phone createPhone() {
        return new SamsungPhone();
    }

    public TV createTV() {
        return new SonyTV();
    }
}

public class Client {
    public static void main(String[] args) {
        ElectronicProductFactory appleFactory = new AppleFactory();
        Phone applePhone = appleFactory.createPhone();
        applePhone.produce(); // Output: Producing Apple Phone

        TV xiaomiTV = appleFactory.createTV();
        xiaomiTV.produce(); // Output: Producing Xiaomi TV

        ElectronicProductFactory samsungFactory = new SamsungFactory();
        Phone samsungPhone = samsungFactory.createPhone();
        samsungPhone.produce(); // Output: Producing Samsung Phone

        TV sonyTV = samsungFactory.createTV();
        sonyTV.produce(); // Output: Producing Sony TV
    }
}

在这个例子中,我们定义了两个抽象产品接口PhoneTV,每个具体产品都实现了对应的接口。我们还定义了一个抽象工厂接口ElectronicProductFactory,每个具体工厂类都实现了ElectronicProductFactory接口,并负责创建一组相关的产品。客户端可以选择对应的具体工厂来创建产品。

总结

  • 简单工厂模式适用于对象类型较少且不会频繁变化的情况,但不符合开闭原则和单一职责原则。
  • 工厂方法模式适用于对象类型较多且需要灵活扩展的情况,但需要定义多个工厂类。
  • 抽象工厂模式适用于创建多个相关对象的情况,但增加新的产品族比较困难。

工厂模式是一种简化对象创建过程的设计模式,它将对象的创建逻辑封装在工厂类中,使得客户端代码只需要与工厂接口进行交互,而不需要关心具体的对象创建细节。工厂模式具有封装对象创建过程、解耦客户端代码和具体类、可扩展性等优点。在实际的软件开发中,工厂模式被广泛应用于对象的创建和管理。


学习更多设计模式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为生成式AI提速,亚马逊云科技Amazon EC2 P5满足GPU需求

生成式AI(Generative AI)已经成为全球范围内的一个重要趋势,得到越来越多企业和研究机构的关注和应用。纽约时间7月26日,亚马逊云科技数据库、数据分析和机器学习全球副总裁Swami Sivasubramanian在亚马逊云科技举办的纽约峰会上更…

React Native获取手机屏幕宽高(Dimensions)

import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接: https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/

程序员自由创业周记#5:加一上线

程序员自由创业周记#5:加一上线 这是一位程序员进行独立开发创业的记录,将分享创业过程中的所思所想以及收支明细。 充实 如果说程序员独立创业的成功率只有5%,那如果家里有一位3岁多还没上幼儿园的小朋友要照顾,成功的概率至少还…

通俗易懂web3.0

目录 前言一、WEB1.0二、WEB2.0三、WEB3.0区别最后 前言 大家好,我是清风。互联网连接了人与人,在过去的30年中,互联网技术不断进化、演化,向纵深发展,政治、经济、社交、生活、工作已经几乎离不开互联网。我们经历了…

软件测试面试【富途面经分享】

目录 一面面经(1h) 二面面经 一面面经(1h) 一、对白盒黑盒灰盒测试的理解 答: 1、黑盒测试就当整个程序是个黑盒子,我们看不到它里面做了什么事情,只能通过输入输出看是否能得到我们所需的来…

使用HTTP隧道时如何应对目标网站的反爬虫监测?

在进行网络抓取时,我们常常会遇到目标网站对反爬虫的监测和封禁。为了规避这些风险,使用代理IP成为一种常见的方法。然而,如何应对目标网站的反爬虫监测,既能保证数据的稳定性,又能确保抓取过程的安全性呢?…

亚马逊关键词的作用有哪些?

亚马逊关键词在平台上扮演着重要的作用,涵盖了消费者、卖家和整个平台的多个方面: 1、消费者的作用: 帮助消费者快速找到所需商品:通过输入关键词,消费者可以迅速找到感兴趣的商品,节省时间和精力。 支持…

【Linux】运行程序前加上strace,可以追踪到函数库调用过程

rootubuntu:/home/peng/test# gcc 123.c -o run rootubuntu:/home/peng/test# strace ./run 如执行结果可知: 我们的程序虽然只有一个printf函数,但是在执行过程中,我们前后调用了execve、access、open、fstat、mmap、brk、write等系统调用。…

01_二值图、灰度图、彩色图

01_二值图、灰度图、彩色图 1. 二值图2. 灰度图3. 彩色图 1. 二值图 二值图像(黑白图像):每个像素点只有两种可能,0和1,0代表黑色,1代表白色。数据类型通常为1个二进制位。 得出来的图像 2. 灰度图 单…

ad+硬件每日学习十个知识点(22)23.8.2(LDO datasheet手册解读)

文章目录 1.LDO的概述、features2.LDO的绝对参数(功率升温和结温)3.LDO的引脚功能4.LDO的电气特性5.LDO的典型电路(电容不能真用1uF,虽然按比例取输出值,但是R2的取值要考虑释放电流)6.LDO的开关速度和线性…

PaperEdge 文档图像矫正

效果 地址: https://github.com/cvlab-stonybrook/PaperEdge

leaflet-uniapp 缩放地图的同时 显示当前缩放层级

记录实现过程: 需求为移动端用户在使用地图时,缩放地图的同时,可以获知地图此时缩放的级别。 效果图如下:此时缩放地图级别为13 map.on() 有对应的诸多行为 查看官网即可,这里根据需要为--zoomstart zoom zoomend 代…

Vector - CAPL - 诊断模块函数(连接管理)

CanTpCreateConnection - 创建TP连接 功能:使用给定的地址模式(add人Mode)创建新连接,可用于诊断数据的收发。 说明:无法更改已有连接的寻址模式;如果确实有需要,可以关闭当前连接后再创建一个…

首批获得金融级行业云平台认证,天翼云深耕行业云

云计算下半场看什么? 无疑是金融、政务、制造等传统政企用户的上云与用云。随着数字经济发展和产业数字化的提速,上云已是政企用户推动其数字化转型不断深入的重要抓手,成为不可阻挡的趋势。 与互联网用户相比,政企用户上云极为…

Qt5.13引入QtWebApp的模块后报错: error C2440: “reinterpret_cast”: 无法从“int”转换为“quintptr”

1、开发环境 Win10-64 qt5.13 msvc2015-64bit-release 2、报错 新建一个demo工程。 引入QtWebApp的httpserver、logging、templateengine三个模块后。 直接运行,,此时报错如下: E:\Qt5.13.1\install\5.13.1\msvc2015_64\include\QtCore…

在腾讯云服务器OpenCLoudOS系统中安装redis(有图详解)

创建安装目录: mkdir -p /app/soft/redis 2. 下载安装包 进入安装目录 cd /app/soft/redis/ 下载安装包 wget https://download.redis.io/releases/redis-7.0.1.tar.gz 解压: tar -zxvf redis-7.0.1.tar.gz 安装gcc yum install gcc-c 进入re…

JSON:让数据传输更优雅

在东南亚海滩的阳光下,时而有一些贝壳、手工艺品等迷人的商品吸引着你。然而,语言的障碍有时会成为购买商品的阻碍。不得不用手比划以及尝试各种办法来进行交流。幸运的是,人们找到原始沟通的技巧,让彼此都能接受的信息交流方式&a…

ES6 - 对象新增的一些常用方法

文章目录 1,Object.is()2,Object.asign()3,Object.getOwnPropertyDescriptors()4,Object.setPrototypeOf()和getPrototypeOf()5,Object.keys()、values() 和 entries()6,Object.fromEntries()7,…

高效构建 vivo 企业级网络流量分析系统

作者:vivo 互联网服务器团队- Ming Yujia 随着网络规模的快速发展,网络状况的良好与否已经直接关系到了企业的日常收益,故障中的每一秒都会导致大量的用户流失与经济亏损。因此,如何快速发现网络问题与定位异常流量已经成为大型企…