编程不是功能实现了就可以了

简介:        最近在项目中发现一个事件,功能很简单,也达到了预期的功能效果,但是编程不仅仅是功能实现了就可以了,更应该是如何完美的实现功能。

       最近在项目中发现一个事件,功能很简单,也达到了预期的功能效果,但是编程不仅仅是功能实现了就可以了,更应该是如何完美的实现功能。下面我将这个事件的代码贴出来,进行一下分析。代码不是很长,总共才19行,该事件是确定按钮对象上面的一个事件定义。每点击一次确定就会触发一次该事件。

1   string    ls_error,ls_zyhm
2   sql_lis = create Transaction
3   uo_support.set_trans_object(sql_lis)
4   IF NOT uo_support.dbconnect(2) THEN  return false
5   ls_zyhm = string(istr_jsxx.jsbr.zyh)
6   gf_begin_transaction(sql_lis)
7   update lis_requisition_info set cypb = 8 where inpatient_id=:ls_zyhm and patient_type=1 using sql_lis;
8   if sql_lis.sqlcode = 0 then
9       gf_commit_transaction(sql_lis)
10     if isvalid(sql_lis) then destroy(sql_lis)
11  else
12     ls_error = "更新:lis_requisition_info表失败!!~r~n"+sql_lis.sqlerrtext
13     gf_rollback_transaction(sql_lis)
14     if isvalid(sql_lis) then destroy(sql_lis)
15      gf_write_log(ls_error)
16      is_errtext = is_errtext + ls_error
17      return false
18   end if
19   return true


问题一:sql_lis的作用域与创建

       很多人第一眼看到该代码可能觉得sql_lis没定义,首先该代码实现了预期的功能,并且能够运行,说明sql_lis定义了,大家普遍觉得sql_lis没定义是有原因的,因为sql_lis的创建与销毁完全是按照局部变量来实现的,所以大家一眼就觉得sql_lis是局部变量,但是在该项目中sql_lis是被定义成了全局变量。

       何为全局变量?我一直持有一个观念,就是全局变量在系统开始之初就被赋值,系统的运行过程中不能再对全局变量进行重新赋值。这个是有原因的,全局变量使用起来非常的灵活,全局变量是供各个模块共同使用的变量,如果每个模块都随意按照自己的需要对全局变量进行重新赋值,会对使用该全局变量的模块造成很严重的影响。


问题二:uo_support对象的事务属性赋值

       如果不熟悉系统框架,可能看不出这个问题,事件第三行对uo_support对象的事务属性进行了赋值,在此sql_lis作为一个引用参数被传入到uo_support对象中,当后面uo_support调用dbconnect方法时,sql_lis就连上了数据库。当然,uo_support对象的事务属性也变成了sql_lis,紧接着后面又把sql_lis给销毁了,后面无论是修改密码还是退出登录对数据库的操作都使用了sql_lis,造成事务对象不可用,当然了即便不销毁,uo_support里面的操作使用sql_lis也是错误的(表跟数据库不匹配)。


问题三:sql_lis断开连接

       sql_lis对象销毁之前,没有将数据库连接断开,本身该事件就是点击确定按钮的时候调用的,操作非常频繁,数据库连接不断开,势必会造成数据库会话的不断上升,直到系统退出数据库才会释放该进程占用的所有会话。也许有人会反驳了,如果数据库会话不断上升的话,数据库连接应该会被占满才对啊。大家都知道pb开发出来的系统是单线程运行的,重复相同的操作,很大可能会造成sql_lis使用了相同的内存块,在这种情况下,数据库端是不会重复开辟会话而是直接使用了上次没有释放的会话。我特意进行了测试,调用完该事件之后,点击另一个按钮故意创建一个对象不释放内存,这样再次回过头来调用上面事件的时候,由于新创建的sql_lis被分配到了新的内存块,造成数据库端重新建立了一个新的连接,造成数据库端session的上升。


问题四:sql_lis连接到底应该放在什么地方

       在这个事件中,sql_lis的连接放在了事件当中,但是该事件是频繁被调用的,这样的后果就是sql_lis不断的被创建,不断的连接数据库,不断的销毁sql_lis.大家都知道tcp建立连接是三次握手,断开连接是四次握手。也就是说在不断的操作过程中,注意我们的系统是成百上千的客户端在同时使用的,并不是单机系统。tcp的建立连接与断开连接是非常占用网络带宽的。生产环境中,数据库的配置是不会变的,也就是说数据库一旦建立连接,在网络没有断开的情况下是一直可以使用的,完全没必要在局部操作中去建立数据库连接。这也是为什么基本所有系统都是刚开始启动时连接上数据库,后面系统的运行过程中一直使用的原因。当然了有的系统在使用的过程中也会判断一下连接是不是由于断网等原因造成不可再用,在这样的情况下,是可以重新进行数据库连接的。


问题五:数据库连接失败的时候直接返回

       第四行代码可以看到,sql_lis连接失败的时候直接返回了false,此时虽然sql_lis连接数据库失败,但是sql_lis对象本身已经创建了,也已经分配内存了,返回之前需要先销毁sql_lis对象。也许有人会说了,代码都执行完了,sql_lis对象不是会自动销毁吗?前提是sql_lis在此处是全局变量,事件结束了,sql_lis的生命周期并没有结束,作为全局变量,他是不会自动销毁的。当sql_lis网络断掉后,其他数据块网络如果正常,频繁的调用该事件,就会不停的创建sql_lis,而且创建完了又不销毁,这样的话,很快内存就会泄露干净了。


       短短的19行代码,暴露出了五个非常严重的问题,编程不是儿戏,实现功能是前提,如何更好的实现是重点。当客户不停抱怨的时候,当程序bug给客户带来利益损失的时候,我们是否能够静下心来自我反思一下。任务重,时间紧不是借口,产品的健壮与否关系到公司乃至所有同事的利益。日常的工作中,养成良好的编程习惯,为产品的健壮做出程序员该做的贡献吧。

目录
相关文章
|
2月前
|
存储 设计模式 Java
为什么我们在程序开发设计中要基于接口而非实现编程?
为什么我们在程序开发设计中要基于接口而非实现编程?
69 1
|
7月前
|
Java 数据库连接 数据库
用户注册功能实现及代码优化案例
用户注册功能实现及代码优化案例
155 0
|
4月前
|
C# 开发者 设计模式
WPF开发者必读:命令模式应用秘籍,轻松简化UI与业务逻辑交互,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,命令模式是简化UI与业务逻辑交互的关键技术,通过将请求封装为对象,实现UI操作与业务逻辑分离,便于代码维护与扩展。本文介绍命令模式的概念及实现方法,包括使用`ICommand`接口、`RelayCommand`类及自定义命令等方式,并提供示例代码展示如何在项目中应用命令模式。
59 0
|
7月前
|
设计模式 算法 程序员
代码之禅:从功能实现到艺术境界
【2月更文挑战第19天】 在编程世界里,每一行代码不仅仅是冷冰冰的字符组合,它们背后承载着程序员的智慧和创造力。本文将深入探讨如何将日常的编程工作提升至一种艺术境界,让代码不仅实现功能需求,还能反映出编写者的哲学思考和技术审美。我们将通过一系列实践策略和思维模式,探索如何编织出既高效又优雅的代码,使之成为技术与艺术完美结合的产物。
|
7月前
|
设计模式
二十三种设计模式全面解析-桥接模式的高级应用:构建灵活的跨平台UI框架
二十三种设计模式全面解析-桥接模式的高级应用:构建灵活的跨平台UI框架
167 0
|
前端开发
前端代码简洁之路,后台系统之详情页设计
前端业务开发中,为了脱离舒适区,也为了解放重复功能开发的劳动力,会将一些功能进行改造,本期改造千篇一律的详情页。
4014 26
前端代码简洁之路,后台系统之详情页设计
|
存储 JavaScript API
移动端单模块功能实现思路及重要方法总结
移动端单模块功能实现思路及重要方法总结
移动端单模块功能实现思路及重要方法总结
|
分布式计算 搜索推荐 BI
报表统计_执行框架_框架编写 | 学习笔记
快速学习报表统计_执行框架_框架编写
|
开发框架 小程序 IDE
mPaaS 小程序架构解析 | 实操演示小程序如何实现多端开发
mPaaS 小程序开发框架已全面开放,免费接入,欢迎体验。
3313 0
mPaaS 小程序架构解析 | 实操演示小程序如何实现多端开发
|
SQL 缓存 监控
2.NetDh框架之简单高效的日志操作类(附源码和示例代码)
前言 NetDh框架适用于C/S、B/S的服务端框架,可用于项目开发和学习。目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型、多库实例,简单强大; 此部分具体说明可参考博客: https://www.cnblogs.com/michaeldonghan/p/9317078.html 2.提供简单高效的日志操作类使用,支持日志写入Db和txt、支持任何数据库类型写入(包括传统sql数据库和nosql数据库等)、支持同步写入日志和后台独立线程异步处理日志队列; 此部分具体说明可参考博客: 本文以下章节内容。
1339 0