Head First Design Patterns -工厂模式

news2024/9/25 1:19:20

什么是工厂模式

工厂方法模式定义了一个创建对象的接口,但由子类来决定要实例化那个类。工厂方法让类把实例化推迟到了子类。

为什么要有工厂模式

书中以pizza店制作pizza为例子,假设不用工厂模式,在制作pizza阶段我们需要这样去实例化类:

Pizza orderPizza(String type) {
	Pizza pizza;
	
	// 基于pizza的类型,实例化具体的类,这里的每个pizza都需要实现Pizza接口
	if (type.equals("cheess")) {
		pizza = new CheesePizza();
	} else if (type.equals("greek")) {
		pizza = new GreekPizza();
	}

	// pizza的前期准备
	pizza.prepare();
	pizza.bake();
	return pizza;
}

上述代码不符合开闭原则,一旦pizza店改变pizza的供应,则需要修改上述代码

简单工厂模式

简单工厂模式并不是一种设计模式,而是一种编程习惯,定义一个工厂类,这个类封装所有披萨的对象创建,pizza店客户端中不会进行实例化

代码如下:

// 简单工厂代码
public Pizza SimplePizzaFactory {
	public Pizza createPizza(String type) {
		Pizza pizza = null;
		if (type.equals("cheess")) {
			pizza = new CheesePizza();
		} else if (type.equals("greek")) {
			pizza = new GreekPizza();
		}
	}
}

// pizza店客户端代码
public class PizzaStore {
	SimplePizzaFactory factory;
	
	public PizzaStore(SimplePizzaFactory factory) {
		this.factory = factory;
	}

	public Pizza orderPizza(String type) {
		Pizza pizza;
		pizza = factory.createPizza(type);
		// pizza的前期准备
		pizza.prepare();
		pizza.bake();
		return pizza;
	}
}

简单工厂模式的类图:
在这里插入图片描述

简单工厂模式的优点:

  • 将变化的部分抽离出来独立形成工厂,避免在客户端直接创建

简单工厂模式的缺点:

  • 简单工厂只是提供了封装对象创建的一种方式,但没有提供工厂方法的弹性,因为它没有办法改变正在创建的产品。

工厂模式

如果pizza店引入了加盟商,加盟商对于pizza需要有一些自己的定制化需求,而上面的简单工厂模式,则不符合这种需求,需要引入工厂模式。

具体代码:

1、定义pizza店接口

public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = createPizza(type);

        pizza.prepare();

        pizza.bake();

        pizza.cut();

        pizza.box();

        return pizza;
    }

    protected abstract Pizza createPizza(String type); // 交给子类进行实例化
}

2、 抽象pizza的制作流程

public abstract class Pizza {
    String name;
    String dough;

    void prepare() {
        System.out.println("prepare finish");
    };
    void bake() {
        System.out.println("bake finish");
    };

    void cut() {
        System.out.println("cut finish");
    };

    void box() {
        System.out.println("box finish");
    };

    public String getName() {return name;};
}

3、定义加盟商的定制化需求

public class NYPizzaStore extends PizzaStore{

    @Override
    public Pizza createPizza(String item) {
        if (item.equals("cheese")) {
            return new NYStyleCheesePizza();
        }else return null;
    }
}

4、定义加盟商所使用的pizza材料

public class NYStyleCheesePizza extends Pizza{
    public NYStyleCheesePizza() {
        String name = "NY Style pizza";
        String dough = "thin crust dough";
        String sauce = "Marinara Sauce";
    }
}

5、main函数执行

public class Main {
    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaStore();

        Pizza pizza = nyStore.orderPizza("cheese");

    }

}

执行结果:

prepare finish
bake finish
cut finish
box finish

工厂模式的类图:
在这里插入图片描述

工厂模式中引入的设计原则:

  • 依赖倒置原则:依赖抽象,而不应该依赖具体类

遵循依赖倒置设计原则的指南:

  • 变量不应该持有到具体类的引用
  • 类不应该派生自具体类
  • 方法不应该覆盖任何基类的已实现方法
    (以上指南并不是铁律,要看具体的场景来遵守)

抽象工厂模式

抽象工厂模式提供一个接口来创建相关或依赖对象的家族,而并不需要指定具体的类

比较工厂方法与抽象工厂方法:
工厂方法:
在这里插入图片描述
抽象工厂方法:
在这里插入图片描述

区别:

  • 工厂方法中只会提供一个抽象接口,接口的实现交给各个工厂去做,抽象类只会知道是制作一个pizza。
  • 抽象工厂是把工厂方法中的接口给拆开了,提供抽象接口的组合。会感知到制作pizza的抽象信息。
  • 抽象方法中对于每一个抽象接口的实现,利用了工厂方法的思路。

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

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

相关文章

Python--装饰器

在 Python 中,装饰器是一种特殊类型的函数,它们用于修改或增强其他函数或方法的行为。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。使用装饰器可以在不修改原函数代码的前提下,给函数添加新的…

visio实现背景透明图片的最简单方法

visio实现背景透明图片的最简单方法 导出中选择PNG格式 保存之后会弹出如下的对话框: 主要的修改包括三处:1.数据格式-逐行扫描 2.背景色(与你的visio中使用的颜色不重合的颜色)3.选中透明度颜色 透明度颜色选择与背景色相同的颜…

C#MQTT编程01--MQTT介绍

1、前言 近年来物联网的发展如火如荼已经渗透到我们生活的方方面面。从智能家居到工业自动化从智慧城市到智慧农业物联网,正在以前所未有的速度改变着我们的生活。 大家现在可能已经习惯了通过手机控制家里的灯光、空调和电视,这就是物联网在智能家居领域…

C#编程-了解进程的通信

了解进程的通信 逻辑上一个应用程序内的所有线程都包含在进程内。这是应用程序运行的操作系统单元。进程是程序的一个运行实例。运行时在同一计算机内或通过网络的进程间通信被称为进程内通信。要允许进程间通信,需要使用特殊的技术和机制。 考虑一个您打文档的场景。您使用…

由于找不到vcomp140.dll无法继续执行代码如何修复-亲测有效

本文将详细介绍vcomp140.dll的定义、作用以及丢失的原因和解决方法。 一、vcomp140.dll是什么? vcomp140.dll是Visual C 2015 Redistributable Package的一部分,它是运行某些基于C的应用程序所必需的动态链接库文件。它包含了许多用于支持C编程语言的函…

Next.js 集成 Auth0 登入和自定义登入页面

Next.js 集成 Auth0 和自定义登入页面 注册账号和基本配置进入 auth0 官网注册账号并登入进入控制台后访问 Applications/Applications进入程序配置页面添加配置 在 Next.js 使用在项目中集成 通过 Auth0Lock 配置方式自定义登入页面效果展示实现过程 注册账号和基本配置 进入…

[C#]利用paddleocr进行表格识别

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR.git 【算法介绍】 PaddleOCR表格识别是PaddlePaddle开源项目中的一个强大功能,它利用深度学习技术实现了对各类表格的高精度识别。PaddleOCR表格识别能够处理各种复杂的表格,包括但不限于…

CSS 下载进度条

<template><view class=btn>下载中</view></template><script></script><style>/* 设置整个页面的样式 */body {width: 100vw; /* 页面宽度为视口宽度 */background: #000000; /* 背景颜色为白色 */display: flex; /* 使用 flex…

通过 CMake 制作库文件 静态库 和 动态库

hehedalinux:~/Linux/loveDBTeacher-v2$ tree . ├── CMakeLists.txt ├── include │ └── head.h ├── main.c └── src├── add.c├── div.c├── mult.c└── sub.c CMake Calc 项目 在这里有add.c,div.c,mult.c,sub.c,main.c,head.h 二、生成静态库 …

Linux学习记录——사십이 高级IO(3)--- Poll型服务器

文章目录 1、认识poll接口2、实现3、特点 1、认识poll接口 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);// pollfd结构 struct pollfd {int fd; /* file descriptor */short events; /* requested events */short revents; /* returned…

三、电脑软件路径移动方式

一、电脑文件移动 当我们想整理硬盘或者移动软件时&#xff0c;常常会遇到多种多样的问题&#xff0c;下面就来说明一下我遇到的问题 1.桌面 解释&#xff1a;移动路径会导致桌面快捷方式失效&#xff0c;下面以图片解答如何恢复 原理&#xff1a;桌面快捷方式保存在C:\Users…

在Linux中创建文件的多种方法

目录 前言1 使用重定向符号 ">"2 使用文本编辑器 vi/vim3 使用 nano4 使用 echo5 使用 touch6 使用 printf7 使用 head8 使用 cat9 使用 tail10 使用 truncate结语 前言 在Linux系统中&#xff0c;文件的创建是日常操作中不可避免的一部分。无论是创建空文件、编…

AI手写数字识别(一)

使用Visual Studio Tools for AI加速桌面智能应用开发 主要知识点 典型的AI应用的代码结构和功能&#xff0c;如处理输入;使用Visual Studio Tools for AI进行TensorFlow模型到.Net Framework应用环境的快速集成。 简介 本文将介绍一例"手写数字识别应用"的开发过…

线性代数——行列式相关性质

目录 一、行列式与它的转置列行列式相等 二、对换行列式的两行&#xff08;列&#xff09;&#xff0c;行列式变号 三、行列式某行&#xff08;列&#xff09;有公因子k&#xff0c;则k可以提到行列式外 四、行列式中若两行成比例&#xff0c;则行列式为0 五、行列式的某一行…

使用FreeBASIC设计8051单片机汇编编译器

在STC论坛上看到有人用C语言实现8051汇编编译器&#xff08;源码&#xff09;&#xff0c;好奇下&#xff0c;试着用FB写了一下。 基本原理就是通过分析汇编文件然后转换为机器码。以下是51汇编与机器码对应的表格&#xff08;数据来自网络&#xff0c;如果发现有误请联系QQ149…

腾讯云添加SSL证书

一、进入腾讯云SSL证书&#xff1a; ssl证书控制台地址 选择“我的证书”&#xff0c;点击"申请免费证书" 2、填写域名和邮箱&#xff0c;点击“提交申请” 在此页面中会出现主机记录和记录值。 2、进入云解析 DNS&#xff1a;云解析DNS地址 进入我的解析-记录…

C#,入门教程(17)——条件语句(if-else)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(16)——可变数据类型&#xff08;var&#xff09;的基础知识与使用禁忌https://blog.csdn.net/beijinghorn/article/details/124032216 程序的核心是逻辑。 逻辑的核心是布尔条件表达式。 逻辑的主要体现形式之一是 if-else 语句…

【文末送书】语义解析:连接自然语言与机器智能的桥梁

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

R语言【paleobioDB】——pbdb_collections():通过参数选择,返回多个采集号的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_collections (...) Arguments 参数【...…

2024趋势:ERP中数据分析的五大要点

2024 年&#xff0c;数据分析不仅仅是 ERP 实施中的一个额外功能;这就像第一步&#xff0c;将最终确定整个 ERP 实施项目的成功之路。忘记笨重的电子表格和无休止的报告——准备好驾驭这五种新兴趋势的浪潮&#xff1a; 一、人工智能和机器学习 (ML) 的兴起 人工智能驱动的数据…