有始有终的编码原则

基本情况

在程序员的修炼之道之中,说到:

这个建议能简单地应用到大多数场合。简单说就是,分配资源的函
数或对象,对释放资源应负有责任。

这其实就是我们常说的谁分配的就谁负责释放,这也是内存释放的一个原则,这一个原则,可以推而广之,就是谁分配的资源,就谁分配释放;这真是非常常用的东西,比如数据库存连接的分配与释放。

我写一个简单的例子说明这种情况,这一个例子就是单纯为了实现价格读出后,然后价格更改,再写入:

void Market::readCustomer()
{
    fopen_s(&m_pf, "test.txt", "r+");

    if (m_pf != nullptr)
    {
        CUSTOMER p = {0};
        fscanf(m_pf, "%s %d", p.name, &p.price);
        printf("%s %d\n", p.name, p.price);
    }
}

void Market::writeCustomer()
{
    if (m_pf != nullptr)
    {
        CUSTOMER p = { "zhangsan", m_money };
        fprintf(m_pf, "%s %d\n", p.name, p.price);
        printf("%s %d\n", p.name, p.price);
        fclose(m_pf);
        m_pf = nullptr;
    }
}

void Market::updateCustomer(int money)
{

    this->readCustomer();
    m_money = money;
    this->writeCustomer();

}

为了清楚其见,写下头文件的部分代码:

typedef struct Customer
{
    char name[10];
    int price;

}CUSTOMER;

private:
     FILE* m_pf;
     int m_money;

上面代码updateCustomer,看着是没问题的,但发现其耦合了变量 m_pf,从函数角度来看,的确是耦合这一个变量,不是一个好事;

后来加了些需要,要求100元以上,才更改价格,程序员,可能更改成下面这个样子:

void Market::updateCustomer(int money)
{

    this->readCustomer();
    m_money = money;
    if(m_money > 100)
    {
    	this->writeCustomer();
    }

}

运行代码,不一会,就提示打开的文件过多,原来,那些小于100的客户,只打开了文件的链接,没有关闭文件链接,与是可能更改如下:

void Market::updateCustomer(int money)
{

   this->readCustomer();
   m_money = money;
   if(m_money > 100)
   {
   	this->writeCustomer();
   }
   else
   {
     fclose(m_pf);
   }

}

现在问题是解决了,但是出现一个变量的三处耦合,最严重的是文件的状态变得混乱。

程序员修炼这样描述这种问题:

这个问题已修复——如果不考虑新的平衡,文件现在的确关闭了。
但是,这个修复方案意味着,三个例程因为共享变量m_pf耦合
在了一起,而且对文件何时是打开状态、何时是关闭状态的跟踪开始变
得混乱。我们正掉入一个陷阱,如果继续走这条路,情况将开始迅速恶
化。这是不平衡的!

那么,如果用有始有终的原则,则更改如下:

void Market::readCustomer(FILE *pf)
{
    if (pf != nullptr)
    {
        CUSTOMER p = {0};
        fscanf(pf, "%s %d", p.name, &p.price);
        printf("%s %d\n", p.name, p.price);
    }
}

void Market::writeCustomer(FILE *pf)
{
    if (pf != nullptr)
    {
        CUSTOMER p = { "zhangsan", m_money };
        fprintf(pf, "%s %d\n", p.name, p.price);
        printf("%s %d\n", p.name, p.price);
    }
}

void Market::updateCustomer(int money)
{   
    FILE *pf;
    fopen_s(&pf, "test.txt", "r+");
    this->readCustomer(pf);
    m_money = money;
    this->writeCustomer(pf);
    fclose(pf);
    pf = nullptr;
}

这样代码就清晰了很多:

我们修改了代码,将文件引用通过参数传进去,而不是在内部持有
引用[5]。现在,关于该文件的所有职责都在 updateCustomer例程中。
它打开文件,再(有始有终地)在返回之前关闭它。例程保持了文件使
用的平衡:打开和关闭在同一个位置,而且非常明显的是,每次对文件
的打开操作都有一个对应的关闭操作。重构还删除了一个丑陋的共享变
量。

总结

代码中时时处处都在遵守这一原则,代码才能清晰,代码才能简单。
image.png

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

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

相关文章

CGI, FastCGI, WSGI, uWSGI, uwsgi一文搞懂

1. CGI # 1、通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。 # 2、CGI程序可以…

Hive ---- DDL(Data Definition Language)数据定义

Hive ---- DDL(Data Definition Language)数据定义 1. 数据库(database)1. 创建数据库2. 查询数据库3. 修改数据库4. 删除数据库5. 切换当前数据库 2. 表(table)1. 创建表2. 查看表3. 修改表4. 删除表5. 清…

TCP教程:详解TCP连接过程

目录标题 一 、简述二 、TCP建立连接协议(三次握手)2.1 概述及目的2.2 第一次握手:客户端发送SYN报文2.3 第二次握手:服务器回应SYN-ACK报文2.4 第三次握手:客户端回应ACK报文2.5 顾客预定座位场景2.6底层原理2.7 TCP …

Docker 网络

一、Docker 网络实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿…

科海思除COD树脂,大孔树脂,除COD专用树脂

一、产品介绍 Tulsimer A-722 MP具有控制孔径的大孔强碱性Ⅰ型阴离子交换树脂 Tulsimer A-722 MP 是一款具有便于颜色和有机物去除的控制孔径的,专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-722 MP(氯型)专门应用于去除COD…

day2 OSI七层体系结构

目录 网络体系结构的形成 协议与划分层次 OSI七层体系结构 网络体系结构的形成 两台计算机要互相传送文件需解决很多问题; (1) 必须有一条传送数据的通路。 (2) 发起方必须激活通路。 (3) 要告诉网络如何识别接收方。 (4) 发起方要清楚对方是否已开机&#…

[BJDCTF2020CTF]之Misc篇(NSSCTF)刷题记录③

NSSCTF-Misc篇刷题记录wp SUCTF-2019-MISC签到题2021-安徽省赛-misc签到RCTF-2019-Misc-draw2020-BJDCTF-Misc-藏藏藏2020-BJDCTF-Misc-签个到2020-BJDCTF-Misc-认真你就输了2020-BJDCTF-Misc-你猜我是个啥2020-BJDCTF-Misc-一叶障目2020-BJDCTF-Misc-鸡你太美2020-BJDCTF-Misc…

NLP原理和应用入门:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)

目录 一、梯度裁剪 1.1设定范围值裁剪 1. 全部参数裁剪(默认) 2. 部分参数裁剪 1.2 通过L2范数裁剪 1.3通过全局L2范数裁剪 二. 模型导出ONNX协议 三、动态图转静态图 3.1两种图定义 3.2 什么场景下需要动态图转静态图 3.3为什么动态图模式越来…

【NFS共享存储服务】

目录 一、NFS (Network File System)网络文件系统1.1、NFS工作原理1.2、举例1.2.1、共享文件总结 一、NFS (Network File System)网络文件系统 依赖于RPC (远端过程调用) 需安装nfs-utils、rpcbind软件包 系统服务: nfs、rpcbind 共享配置文件: /etc/ex…

Ajax和Json综合案例

1. 查询所有 创建brand.html,使用axios发送请求&#xff0c;其中查询一般采用get的请求方式 <script src"js/axios-0.18.0.js"></script><script>//1. 当页面加载完成后&#xff0c;发送ajax请求window.onload function () {//2. 发送ajax请求axi…

造型简约的机箱,安装简单兼容性好,安钛克P20C体验

我们准备组装一台新主机的时候&#xff0c;机箱确实很重要&#xff0c;它决定了主机的整体风格和兼容性。我比较喜欢用中塔机箱&#xff0c;像是上个月我新装的主机&#xff0c;用的就是安钛克P20C&#xff0c;这款机箱的设计很简约&#xff0c;而且还有多种版本可选&#xff0…

【剑指offer】学习计划day1

目录 一. 前言 二. 用两个栈实现队列 a.题目 b.题解分析 c.AC代码 二. 包含min函数的栈 a.题目 b.题解分析 c.AC代码 一. 前言 本系列是针对Leetcode中剑指offer学习计划的记录与思路讲解。详情查看以下链接&#xff1a; 剑指offer-学习计划https://leetcode.cn/study-pla…

jstat命令查看jvm内存情况及GC内存变化

命令格式 jstat [Options] pid [interval] [count] 参数说明&#xff1a; Options&#xff0c;选项&#xff0c;一般使用 -gc、-gccapacity查看gc情况 pid&#xff0c;VM的进程号&#xff0c;即当前运行的java进程号 interval&#xff0c;间隔时间(按该时间频率自动刷新当前内存…

Python整个颜色小网站,给刚刚失恋的他.........

一些过场剧情: 死党一直暗恋校花&#xff0c;但是校花对他印象也不差&#xff0c; 就是死党一直太怂了&#xff0c;不敢去找校花&#xff0c; 直到昨天看到校花登上了校董儿子的豪车&#xff0c; 死党终于彻底死心&#xff0c;大醉一场&#xff0c;作为他的兄弟&#xff0c…

系统集成项目管理工程师 笔记(第六章:项目整体管理)

文章目录 项目整体管理6个过程制定项目章程过程 6.3 制订项目管理计划 2476.4 指导与管理项目工作 2516.5 监控项目工作 255监控项目工作的输入监控项目工作的工具与技术监控项目工作的输出 6.6 实施整体变更控制6.7结束项目或阶段 6.1 项目整体管理概述 242 6.1.1 项目整体管理…

“探索C++非质变算法:如何更高效地处理数据“

&#x1f4d6;作者介绍&#xff1a;22级树莓人&#xff08;计算机专业&#xff09;&#xff0c;热爱编程&#xff1c;目前在c&#xff0b;&#xff0b;阶段>——目标Windows&#xff0c;MySQL&#xff0c;Qt&#xff0c;数据结构与算法&#xff0c;Linux&#xff0c;多线程&…

王道计组(23版)6_总线

总线概述 特点 分时&#xff1a;同一时刻只允许一个部件向总线发送信息 共享&#xff1a;总线上可以挂接多个部件&#xff0c;各个部件互相交换的信息都可以通过这组线路分时共享&#xff0c;多个部件可以同时从总线接收相同的信息 分类 片内总线&#xff1a;CPU芯片内部AL…

Linux下版本控制器(SVN) -命令行客户端

文章目录 进阶知识-Linux下版本控制器(SVN)5、命令行客户端5.1 创建两个工作区目录模拟两个开发人员5.2 检出5.3 添加5.4 提交5.5 查看服务器端文件内容5.6 更新操作5.7 冲突5.7.1 过时的文件5.7.2 冲突的产生5.7.3 冲突的表现5.7.4 冲突的手动解决5.7.5 冲突的半自动解决5.7.6…

openharmony内核中不一样的双向链表

不一样的双向链表 链表初识别遍历双向链表参考链接 链表初识别 最近看openharmony的内核源码时看到一个有意思的双向链表&#xff0c;结构如下 typedef struct LOS_DL_LIST{struct LOS_DL_LIST *pstPrev; //前驱节点struct LOS_DL_LIST *pstNext; //后继节点 }LOS_DL_LIST;不…

算法:在指定范围内生成随机不重复的位置

问题&#xff1a; 在游戏中&#xff0c;我们经常会遇到以下问题&#xff1a;在指定的范围内生成随机不重复的位置。 比如某次“神官赐福”活动中&#xff0c;需要在城门口生成n个不重复的宝箱。 针对这种问题&#xff0c;我们可以先将范围按照宝箱&#xff08;基本单元格&#…