一个程序员怎么能做出这样的事情?

红薯
 红薯
发布于 2011年08月05日
收藏 9

本文是从 Why On Earth Would A Developer Do This? 这篇文章翻译而来。


我正好看到了下面的一段代码:

        public void Execute()

        {

            ArrayList empIds = PayrollDatabase.GetAllEmployeeIds();

            foreach (int empId in empIds)

            {

                Employee employee = PayrollDatabase.GetEmployee(empId);

                if (employee.IsPayDate(payDate))

                {

                    DateTime startDate = employee.GetPayPeriodStartDate(payDate);

                    Paycheck pc = new Paycheck(startDate, payDate);

                    paychecks[empId] = pc;

                    employee.Payday(pc);

                }

            }

        }

这段代码有点老,是用.NET 2.0之前版本写的。可是,并不是里面ArrayList的用法让我苦恼。首先他从数据库里取出所有员工的Id。然后他遍历这个Id集合,从数据库这取出每个员工的信息。每当我看到这样的代码,我都想踹写这个程序的人一脚。

如果你还不明白这样的写法有什么问题,请这样想想:你第一次把select语句发送给数据库查询员工Id,查询出5条员工记录。然后你需要向数据库 请求另外5条查询语句,分别查出这几个员工的信息。这还好,6次查询并不是一个多大的事情,不是吗?可是你为什么不能把所有需要的数据一次性的全部查询出 来呢(这样只有一次开销大的查询)!想象一下,如果你要计算的是100个员工的工资呢,而不是5个?如果是1000个员工的呢?

让我不可理解的是,这样的代码天天都会产生。难道这些人真的不在乎、或真的不知道这样的代码有多糟吗?如果他们真的不知道,那真是很悲哀。如果他们不在意,那更糟糕,因为如果一个程序员明知这样写有问题还是要这样写,很显然,他不认为他的工作有价值,他不关心他的程序,他的团队,他的公司,以及他的客户。

如果你奇怪我是从哪里找到这段代码的…是在Robert C(敏捷软件开发理论的创始人)那里。他的《敏捷软件开发:原则、模式与实践(C#版)》这 边书里。是的,是 Robert C。Martin,也就是Uncle Bob。我也许不该批评面向对象领域里如此著名的人物,可是,说真的,Bob,你脑袋进水了吗?你的整本书的目的都是在教育人如何写出优质的代码,里面可 以找到大量很有价值的教导。但把这样的代码当作例子实在是不可宽恕。

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net]
本文标题:一个程序员怎么能做出这样的事情?
加载中

最新评论(49

y
yhkyo321
没什么好纠结的,就是一段还可以接着优化的代码而已. 他的目的只是为了实现.
凯旋1985
凯旋1985

引用来自“sevk”的评论

要分场合的,如果有100万条记录,全部取出来肯定吃内存,如果内存正好没了,肯定卡你30秒没商量.

如果记录不到1万条,那全部取出来是对的.

所以只看代码,不看场合是错误的.

如果是100万条记录,可以分100次,每次只取1W条,少量数据不能这样处理,海量数据更不能这样处理!数据库是个仓库,而不是缓存!
Chiroc
Chiroc
这有什么,很多书都直接“教导”我们用变量连接SQL的,还是某某知名大学出的书!
老zhang
老zhang

引用来自“北落”的评论

很明显这样代码是影响效率的,大的公司员工数量顶多上万人。
而且把数据库表优化下,全部读取到内存中也用不了多少内存,远远比一次一次的查询数据库来的高效

那是你没遇到过这种情况吧?要分场合的,如果有100万条记录,全部取出来肯定吃内存,如果内存正好没了,肯定卡你30秒没商量.

如果记录不到1万条,那全部取出来是对的.

所以只看代码,不看场合是错误的.
老zhang
老zhang

引用来自“zhao_rong”的评论

你没有明白作者的意思,他得意思是说一次把员工的所有信息查询出来,比如员工编号,姓名等等,而不应该首先查询出ID,然后遍历ID,对每个ID查询其他信息

不一样的,你没明白
晓亮
晓亮
也许作者的本意不是来宣扬这段代码的呢,我觉得代码要放在环境里面看,什么样的环境应该对什么样的代码
风雨路
不可妄下论断,如果他的人员资料已经全部成为内存数据了。这样做当然没问题,他只是利用id去内存数据库检索而已。
这不和key-value的内存数据一样的原理吗?

我们不要忽略人家要说明的问题,而一定要用另外一角度却分析。
W
WuHellwen
对于这种情况非常感同身受,我之前是做了4年的开发,现在转做DBA。你可以想象从开发到被开发的这个过程是思维转变和看法的结合。在一次面试中停下来思考的时候突然意识的开发人员对数据库方法的认识和重视严重不足,有可能这个开发人员的开发能力非常强,但他往往犯下一些简单错误导致数据库服务器的负担。所以我觉得作为DBA有义务为所有的开发人员转达这方面的知识。
W
WuHellwen

引用来自“sevk”的评论

要分场合的,如果有100万条记录,全部取出来肯定吃内存,如果内存正好没了,肯定卡你30秒没商量.

如果记录不到1万条,那全部取出来是对的.

所以只看代码,不看场合是错误的.

非常反对你的想法,我认为不管是什么表、不管又多少字段都不应该这么做。至于你设计表的时候又下多少时间用来考虑表的字段和表的记录数呢?
返回顶部
顶部