设计模式之空对象模式

目录

1.简介

2.结构图

3.实例

4.优缺点


1.简介

        空对象模式也是我们平时编程用的比较多的一种行为型设计模式,它的宗旨在解决空对象引起的异常报错问题;在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。

        在空对象模式中,我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类,还创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方。

        在C/C++编程中,如果一个接口返回一个对象指针,如:

    class AbstractObject{
    public:
        int compareTo(int value){
            //...
            return 0;
        }
    }
    AbstractObject* getValue(int n);

在接口调用的时候,IMessageField*  p =  getValue(100); 一般都是去判断 p 是否 为null,如果不判断p, 直接调用IMessageField的成员函数compareTo,程序就崩溃了;利用空对象模式就解决了这个问题,从而避免不管怎么调用都不会导致程序崩溃的情况,下面我们就看看怎么解决这个问题的。

2.结构图

空对象模式的UML类图如下:

由上图可以看到,空对象模式主要包含3个角色。
1) 抽象对象(AbstractObject):定义所有子类公有的行为和属性,一般定义一个isNull接口是不必可少的。
2) 真实对象(CRealObject):继承AbstractObject类,并实现所有行为。
3) 空对象(CNullObject):继承AbstractObject类,对父类方法和属性不做实现和赋值。

3.实例

真实对象和空对象定义如下:

#include <iostream>
#include <map>
#include <memory>

// 抽象对象
class AbstractObject {
public:
	virtual void doSomething() = 0;
	virtual bool isNull() const = 0;
};

// 真实对象1
class CRealObject1 : public AbstractObject {
public:
	void doSomething() override {
		std::cout << "CRealObject1 is doing something." << std::endl;
	}
	bool isNull() const override { return false; }
};

// 真实对象2
class CRealObject2 : public AbstractObject {
public:
	void doSomething() override {
		std::cout << "CRealObject2 is doing something." << std::endl;
	}
	bool isNull() const override { return false; }
};

// 真实对象3
class CRealObject3 : public AbstractObject {
public:
	void doSomething() override {
		std::cout << "CRealObject3 is doing something." << std::endl;
	}
	bool isNull() const override { return false; }
};

// 空对象
class CNullObject : public AbstractObject {
public:
	void doSomething() override {
		// 空对象不进行任何操作
	}
	bool isNull() const override { return true; }
};

class CMessageEntity
{
public:
	void  add(int value, AbstractObject* pObject) {
		m_objects[value] = pObject;
	}
	void  remove(int value) {
		m_objects.erase(value);
	}

	AbstractObject* getObject(int value) {
		static CNullObject s_nullObject;
		if (m_objects.find(value) != m_objects.end()) {
			return m_objects[value];
		}
		return &s_nullObject;
	}
private:
	std::map<int, AbstractObject*> m_objects;
};

测试例程如下:

int main() {
	std::unique_ptr<AbstractObject> obj1(new CRealObject1());
	std::unique_ptr<AbstractObject> obj2(new CRealObject2());
	std::unique_ptr<AbstractObject> obj3(new CRealObject3());

	CMessageEntity entities;

	entities.add(10, obj1.get());
	entities.add(20, obj2.get());
	entities.add(234, obj3.get());

	entities.getObject(20)->doSomething();  // 输出: CRealObject2 is doing something.
	entities.getObject(234)->doSomething(); // 输出: CRealObject3 is doing something.
	entities.getObject(0)->doSomething();   // 输出: 
	entities.getObject(10)->doSomething();  // 输出: CRealObject1 is doing something.

	return 0;
}

上述示例中,定义了一个抽象对象类AbstractObject,真实对象类CRealObject1、CRealObject2、CRealObject3和空对象类CNullObject都继承自抽象对象类。在主函数中,创建了三个真实对象和一个空对象,并调用它们的doSomething()方法。真实对象会执行具体的操作,而空对象不进行任何操作。通过使用空对象,可以避免对空值的检查,使得代码更加简洁和健壮。

4.优缺点

优点:
1.避免NullPointerException:这是空对象模式最主要的好处。通过提供一个空对象实例,可以避免在调用方法时抛出NullPointerException
2.改善代码质量:通过明确地表示一个对象是空的,可以使代码更具可读性,也减少了因为错误地使用空引用而导致的运行的错误。
3.更好的扩展性:如果一个类经常需要一个空实例,那么在将来需要改变这个类的行为时,可以更容易地适应这些变化
缺点:
1增加类的数量:为了使用空对象模式,口能需要为每一个类都提供一个空对象实现,这会增加类的数量,也可能会增加代码的复杂性。
2.不易发现错误:有时候,开发者可能会错误地认为空对象实例表示正常的操作,这可能导致在运行时出现难以发现的错误。
3.违反开放封闭原则:开放封闭原则鼓励的是添加新的行为,而不是新的具体类。而空对象模式需要为每个类添加新的空实现类,这似乎与开放封闭原则相违背。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【一文详解】知识分享:(MySQL关系型数据库快速入门)

mysql基础 数据类型 整型 类型名称取值范围大小TINYINT-128〜1271个字节SMALLINT-32768〜327672个宇节MEDIUMINT-8388608〜83886073个字节INT (INTEGHR)-2147483648〜21474836474个字节BIGINT-9223372036854775808〜92233720368547758078个字节 注: 无符号在数据类型后加 un…

免费申请SSL证书

首先&#xff0c;让我们了解一下SSL证书的作用。SSL&#xff08;Secure Sockets Layer&#xff09;证书是一种数字证书&#xff0c;它可以加密网站与用户之间的通信数据&#xff0c;防止信息在传输过程中被窃取或篡改&#xff0c;同时也可以验证网站的真实身份&#xff0c;避免…

electron+vue编辑Office Word?

Electron 桌面应用是基于 Chromium 内核的&#xff0c;而谷歌Chrome取消了对PPAPI插件支持后&#xff0c;在线Office方案纷纷失效&#xff0c;只能更换国产浏览器在低版本浏览器苟延残喘&#xff0c;不能用于electronvue项目。 经过小编不断的寻找&#xff0c;终于找到一款至今…

对git中tag, branch的重新理解

1. 问题背景 项目中之前一个tag&#xff08;v1.0&#xff09;打错了&#xff0c;想删除它&#xff0c;但我们从此tag v1.0中迁出新建分支Branch_v1.0,在此分支下修复了bug&#xff0c;想重新打一个tag v1.0&#xff0c;原来的tag v1.0可以删除掉吗&#xff1f; 错误的理解&am…

Starrocks监控方案

下载安装包 Download | Prometheus Download Grafana | Grafana Labs 部署prometheus 配置文件 global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: StarRocks_Cluster metrics_path: /metrics static_configs: - targets: [192.168.110…

【BetterBench】2024年都有哪些数学建模竞赛和大数据竞赛?

2024年每个月有哪些竞赛&#xff1f; 2024年32个数学建模和数据挖掘竞赛重磅来袭&#xff01;&#xff01;&#xff01; 2024年数学建模和数学挖掘竞赛时间目录汇总 一月 &#xff08;1&#xff09;2024年第二届“华数杯”国际大学生数学建模竞赛 报名时间&#xff1a;即日起…

同城短视频矩阵怎么做?小魔推助力实体行业高效视频分发

在如今的互联网时代&#xff0c;各个行业的实体老板都在考虑转型的方向&#xff0c;希望能有更多的发展&#xff0c;特别是抖音短视频做作为日活8亿用户的超大平台&#xff0c;吸引了无数的实体老板入场做宣传&#xff0c;来做自己门店、品牌的曝光获客动作&#xff0c;但引流并…

C++力扣题目104--二叉树的最大深度

给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例&#xff1a; 给定二叉树 [3,9,20,null,null,15,7]&#xff0c; 返回它的最大深度 3 。 思路 看完本篇可以一起做了如下…

Apache Doris (六十三): Spark Doris Connector - (3)-配置型及列映射关系

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. Spark 操作Doris配置项

CentOS中静态HTTP服务的最佳实践和优化技巧

在CentOS中提供静态HTTP服务是常见的需求&#xff0c;尤其是在构建Web应用程序、托管网站或提供文件下载时。为了确保高效、安全且可靠的传输&#xff0c;这里提供了一些最佳实践和优化技巧。 1. 选择合适的HTTP服务器软件 Nginx: 轻量级、高效&#xff0c;支持HTTP/2&#x…

【安卓模拟器】雷电模拟器9 v9.0.64 绿色版(免安装版,一键绿化)

下载地址 极核GetShell 简介 雷电模拟器9是一款安卓模拟器&#xff0c;支持安卓9版本。安卓模拟器除了能够运行游戏娱乐&#xff0c;对于渗透测试&移动安全测试也有举足轻重的作用。 软件截图 绿化教程 视频教程 下载地址提供了视频绿化教程&#xff0c;有需要的可以…

工单系统:助力传统服务行业实现数字化转型的关键要素

数字化转型的浪潮冲击着传统服务业&#xff0c;对其造成了巨大的影响。其中&#xff0c;工单系统以其多样和强大的功能性&#xff0c;成为传统服务行业必备的数字工具。今天&#xff0c;小编就来大家来聊聊工单系统对传统服务行业有哪些影响&#xff1f;希望对于还未投入使用的…

视频壁纸制作Dynamic Wallpaper中文

Dynamic Wallpaper是一款专门为macOS用户设计的动态壁纸软件。它可以将视频、图片、音乐等多种元素融合在一起&#xff0c;为用户的桌面带来生动、个性化的视觉效果。Dynamic Wallpaper内置了大量动态壁纸&#xff0c;包括自然风景、城市风貌、抽象艺术等多种主题。用户可以根据…

【大数据OLAP引擎】StarRocks为什么快?

StarRocks的优势 StarRocks最初主要的优势是性能&#xff0c;当时在单表查询方面与性能标杆ClickHouse不相上下&#xff0c;而join优化特性使其在多表关联查询场景下的性能表现要远远优于ClickHouse&#xff0c;替换ClickHouse自然也就成了StarRocks的第一个目标。 而StarRoc…

2024年口碑好的外贸CRM软件推荐

外贸CRM软件是指专门为外贸行业设计开发的客户关系管理软件。它通过集成各种功能模块&#xff0c;帮助外贸企业管理客户信息、销售机会、订单跟踪、市场活动等重要业务流程。外贸CRM软件可以提高外贸企业的销售效率和客户满意度&#xff0c;帮助企业建立良好的客户关系&#xf…

(详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models

Haoran Wei1∗, Lingyu Kong2∗, Jinyue Chen2, Liang Zhao1, Zheng Ge1†, Jinrong Yang3, Jianjian Sun1, Chunrui Han1, Xiangyu Zhang1 1MEGVII Technology 2University of Chinese Academy of Sciences 3Huazhong University of Science and Technology arXiv 2023.12.11 …

卖家必看!跨境电商独立站选品思路——电商API接口采集更便捷高效的选品方式

要想打造一个成功的独立站&#xff0c;选品过程至关重要。只有先确定选品&#xff0c;才能完成后续的具体定价、库存备货、店铺风格、匹配支付和物流等等。那么&#xff0c;对于需要搭建独立站的卖家而言&#xff0c;该如何去进行选品&#xff0c;有哪些思路和方法呢&#xff1…

如何使用CentOS系统中的Apache服务器提供静态HTTP服务

在CentOS系统中&#xff0c;Apache服务器是一个常用的Web服务器软件&#xff0c;它可以高效地提供静态HTTP服务。以下是在CentOS中使用Apache提供静态HTTP服务的步骤&#xff1a; 1. 安装Apache服务器 首先&#xff0c;您需要确保已安装Apache服务器。可以使用以下命令安装Ap…

OpenHarmony南向之LCD显示屏

OpenHarmony南向之LCD显示屏 概述 LCD&#xff08;Liquid Crystal Display&#xff09;驱动&#xff0c;通过对显示器上下电、初始化显示器驱动IC&#xff08;Integrated Circuit&#xff09;内部寄存器等操作&#xff0c;使其可以正常工作。 HDF Display驱动模型 LCD器件驱…

QWebEngineView类中的load、seturl、setPage、setHtml和setContent方法的功能与用法对比

文章目录 📖 介绍 📖🏡 环境 🏡📒 对比 📒📝 load方法📝 setUrl方法📝 setPage方法📝 setHtml方法📝 setContent方法📖 介绍 📖 QWebEngineView 是 Qt 提供的一个用于呈现 Web 内容的类,基于 Google 的 Chromium 浏览器引擎。它提供了对现代 Web 标…