设计模式-工厂方法

news2024/11/15 21:25:01

工厂方法是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。

问题

假设你开设了一个汽车工厂。创业初期工厂只能生产宝马这一款车,因此大部分代码都位于名为宝马的类中。

工厂效益非常好,为了获得更多利润,你决定扩大生产,引入一款名为奥迪的车。

可是代码问题改如何处理呢?目前,大部分代码斗鱼宝马类相关。在程序中添加奥迪类需要修改全部代码。更糟糕的是,如果你以后需要在程序中支持另外一种车型,很可能需要再次对这些代码进行大幅修改。

解决方案

工厂方法模式建议使用特殊的工厂方法代替对于对象构造函数的直接调用(即使用new运算符)。不用担心,对象仍将通过new运算符创建,只是该运算符改在工厂方法中调用罢了。工厂方法返回的对象通常被称作“产品”。

假设生产汽车只有创建汽车和销售汽车两种功能。
在这里插入图片描述

这种更改可能毫无意义:我们只是改变了程序中调用构造函数的位置而已。但是,现在你可以在子类中重写工厂方法,从而改变其创建产品的类型。

这里的工厂方法是create()方法。

注意,仅当这些产品具有共同的基类或者接口时子类才能返回不同类型的产品,同时基类中的工厂方法还应将其返回类型声明为这一共有接口。
在这里插入图片描述
举例来说,宝马BMW奥迪Audi类都必须实现汽车Car接口,该接口声明了一个名为行驶run的方法。每个类都将以不同的方式实现该方法:宝马以后轮驱动的驱动形式行驶,奥迪以四轮驱动的形式驱动行驶。宝马部门BMWDepartment类的工厂方法返回宝马对象,奥迪部门AudiDepartment类则返回奥迪对象。

只要产品类实现共同的接口,你就可以将其对象传递给客户代码,而无需提供额外数据。

调用工厂方法的代码(通常被称为客户端代码)无需了解不同子类返回实际对象之间的差别。客户端将所有产品视为抽象汽车Car。客户端知道所有汽车对象都提供行驶run方法,但是并不关心其具体实现方式。

结构

在这里插入图片描述

  1. 产品(Product)将会对接口进行声明。对于所有由创建者及其子类构建的对象,这些接口都是通用的。

  2. 具体产品(Concrete Products)是产品接口的不同实现。

  3. 创建者(Creator)类声明返回产品对象的工厂方法。该方法的返回对象类型必须与产品接口相匹配。

    你可以将工厂方法声明为抽象方法,强制要求每个子类以不同方式实现该方法。或者,你也可以在基础工厂方法中返回默认产品类型。

    注意,尽管它的名字是创建者,但它最主要的职责并不是创建产品。一般来说,创建者类包含一些与产品相关的核心业务逻辑。工厂方法将这些逻辑处理从具体产品类中分离出来。打个比方,大型软件开发公司拥有程序员培训部门。但是,这些公司的主要工作还是编写代码,而非生产程序员。

  4. 具体创建者(Concrete Creators) 将会重写基础工厂方法,使其返回不同类型的产品。

    注意,并不一定每次调用工厂方法都会创建新的实例。工厂方法也可以返回缓存、对象池或其他来源的已有对象。

代码

在这里插入图片描述

interface Car {
    void run();
}

class BMW implements Car {

    @Override
    public void run() {
        System.out.println("后轮驱动行驶!");
    }
}

class Audi implements Car {

    @Override
    public void run() {
        System.out.println("四轮驱动行驶!");
    }
}

class CarDepartment {
    public Car create() {
        return null;
    }

    public void sell() {
        Car car = create();
        // 试驾汽车
        System.out.println("试驾汽车:");
        car.run();
        // ……其他操作……
    }
}

class BMWDepartment extends CarDepartment {
    public Car create() {
        return new BMW();
    }
}

class AudiDepartment extends CarDepartment {
    public Car create() {
        return new Audi();
    }
}

public class FactoryMethod {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String carType = scanner.nextLine();
        CarDepartment carFactory = null;
        if ("BMW".equals(carType)) {
            carFactory  = new BMWDepartment();
        } else if ("Audi".equals(carType)) {
            carFactory = new AudiDepartment();
        } else {
            throw new RuntimeException("错误!未知的车型。");
        }
        carFactory.sell();
    }
}

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

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

相关文章

Spring Cloud学习(七)【Docker 容器】

文章目录 初识 DockerDocker 介绍Docker与虚拟机Docker架构安装 Docker Docker 基本操作镜像相关命令容器相关命令数据卷 Dockerfile 自定义镜像镜像结构Dockerfile DockerComposeDockerCompose介绍安装DockerCompose Docker镜像仓库常见镜像仓库服务私有镜像仓库 初识 Docker …

CSS花边001:无衬线字体和有衬线字体

网站中我们看到过很多字体,样子各有千秋。通常针对结构,区分为有衬字体(serif) 和无衬字体(sans-serif)。今天我们聊一下这个话题。 什么是有衬字体,什么是无衬字体? 衬线字体&…

【c++随笔12】继承

【c随笔12】继承 一、继承1、继承的概念2、3种继承方式3、父类和子类对象赋值转换4、继承中的作用域——隐藏5、继承与友元6、继承与静态成员 二、继承和子类默认成员函数1、子类构造函数 二、子类拷贝构造函数3、子类的赋值重载4、子类析构函数 三、单继承、多继承、菱形继承1…

[ASP]数据库编辑与管理V1.0

本地测试:需要运行 ASP专业调试工具(自己搜索下载) 默认登陆口令:admin 修改口令:打开index.asp找到第3行把admin"admin"改成其他,如admin"abc123" 程序功能齐全,代码精简…

CLIP:用文本作为监督信号训练可迁移的视觉模型

Radford A, Kim J W, Hallacy C, et al. Learning transferable visual models from natural language supervision[C]//International conference on machine learning. PMLR, 2021: 8748-8763. CLIP 是 OpenAI 在 2021 年初的工作,文章发表在 ICML-2021&#xff0…

并发安全问题之--事物失效问题

并发安全问题之–事物失效问题 事物失效常见的6种原因: 1、事物方法非public修饰 2、非事物方法调用事物方法 3、事物方法抛出的异常被捕获了 4、事物方法抛出的异常类型不对 5、事物传播行为不对(事物发生嵌套时有事物传播) 6、事物锁属类没…

IP多播需要使用两种协议(IGMP和多播路由选择协议)

目录 IGMP 多播路由选择协议 组播协议包括组成员管理协议和组播路由协议: 组成员管理协议用于管理组播组成员的加入和离开(IGMP) 组播路由协议负责在路由器之间交互信息来建立组播树(多播路由选择协议) IGMP 图中标有 IP 地址的四台主机都参加了一个多播组,其…

逻辑回归-癌症病预测与不均衡样本评估

1.注册相关库(在命令行输入) pip install scikit-learn pip install pandas pip install numpy 2.导入相关库 import pandas as pd import numpy as np from sklearn.metrics import classification_report from sklearn.model_selection import train_test_split…

初始MySQL(三)(合计函数,分组函数,字符串相关函数,数字相关函数,时间日期函数,加密函数,流程控制函数)

目录 合计/统计函数 count 返回行的总数 sum 合计函数 - avg group by 字符串相关函数 数学相关函数 时间日期相关函数 加密函数 流程控制函数 合计/统计函数 count 返回行的总数 Select count(*) | count (列名) from tablename [WHERE where_definition] #演…

国际阿里云:Windows实例中数据恢复教程!!!

在处理磁盘相关问题时,您可能会碰到操作系统中数据盘分区丢失的情况。本文介绍了Windows系统下常见的数据盘分区丢失的问题以及对应的处理方法,同时提供了使用云盘的常见误区以及最佳实践,避免可能的数据丢失风险。 前提条件 已注册阿里云账…

C/C++满足条件的数累加 2021年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C满足条件的数累加 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C满足条件的数累加 2021年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 现有n个整数,将其中个位数…

2022年03月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下面有关random的常用方法,描述错误的是? A: random.random()生成一个[0.0,1.0)之间的随机小数 B: random.randint(a,b)生成一个[a,b]之间的随机整数 C: random.choice(seq)从序列中…

RT-DTER 引入用于低分辨率图像和小物体的新 CNN 模块 SPD-Conv

论文地址:https://arxiv.org/pdf/2208.03641v1.pdf 代码地址:https://github.com/labsaint/spd-conv 卷积神经网络(CNN)在图像分类、目标检测等计算机视觉任务中取得了巨大的成功。然而,在图像分辨率较低或对象较小的更困难的任务中,它们的性能会迅速下降。 这源于现有CNN…

Anolis 8.6 安装 Drawio

Anolis 8.6 安装 Drawio 22.1.0 一.RPM版(不建议)二.WAR 包部署 一.RPM版(不建议) Draw RPM 包下载链接 RPM 包直接基于Linux图形化能力部署,服务器类型的Linux系统启动RPM包安装的Draw可能比较复杂 系统版本 ## 1.…

Leetcode刷题详解—— 有效的数独

1. 题目链接:36. 有效的数独 2. 题目描述: 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的…

Spark Job优化

1 Map端优化 1.1 Map端聚合 map-side预聚合,就是在每个节点本地对相同的key进行一次聚合操作,类似于MapReduce中的本地combiner。map-side预聚合之后,每个节点本地就只会有一条相同的key,因为多条相同的key都被聚合起来了。其他节…

Day28力扣打卡

打卡记录 给小朋友们分糖果 II(容斥原理) 链接 大佬的题解 def c2(n: int) -> int:return n * (n - 1) // 2 if n > 1 else 0class Solution:def distributeCandies(self, n: int, limit: int) -> int:return c2(n 2) - 3 * c2(n - limit …

Codeforces Round 788 (Div. 2) E. Hemose on the Tree(树上构造)

题目 t(t<5e4)组样例&#xff0c;每次给定一个数p&#xff0c; 表示一棵节点数为的树&#xff0c; 以下n-1条边&#xff0c;读入树边 对于n个点和n-1条边&#xff0c;每个点需要赋权&#xff0c;每条边需要赋权&#xff0c; 权值需要恰好构成[1,2n-1]的排列 并且当你赋…

基于springboot实现沁园健身房预约管理系统【项目源码】计算机毕业设计

基于springboot实现沁园健身房预约管理系统演示 B/S架构 B/S结构是目前使用最多的结构模式&#xff0c;它可以使得系统的开发更加的简单&#xff0c;好操作&#xff0c;而且还可以对其进行维护。使用该结构时只需要在计算机中安装数据库&#xff0c;和一些很常用的浏览器就可以…

Jenkins简介及Docker Compose部署

Jenkins是一个开源的自动化服务器&#xff0c;用于自动化构建、测试和部署软件项目。它提供了丰富的插件生态系统&#xff0c;支持各种编程语言和工具&#xff0c;使得软件开发流程更加高效和可靠。在本文中&#xff0c;我们将介绍Jenkins的基本概念&#xff0c;并展示如何使用…