软件真的好难做啊
还记得以前本站的那一篇“编程好难啊”吗,那是一篇众程序员调侃程序新手的文章,有恶搞的成分在里面。今天要和大家说的这个事没有一些恶搞和调侃的意思,是比较严肃的话题,你一定可以从中收获一些东西。这个话题来自StackOverflow上的一个问题——Cycle in Family Tree Software,这个程序员问了下面这个问题:
我是一个写家族族谱软件的程序员(我用的是C++和Qt),这个软件基本上没有什么问题,直到有一天有个用户报告了一个bug。这个问题是这样的——我这个用户和他女儿生了两个孩子。
于是,我程序员的一些断言和硬性条件导致程序报错,因为我的程序在处理这个关系的时候,其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。
请问,在不需要移除我的断言和数据验证的情况下,我怎么才能解决这个问题?
看到这里,请重点阅读一下下面的两点:
- 如果你看到这里开始兴奋了,请你为你阴暗的心理去面壁反省10分钟,因为这是一个很技术的问题。
- 如果你开始陷入了深深的思考如何解决这个问题,那么你绝对是一个合格的程序员,因为你已陷入技术已经很深了,有点呆了。
我在前面说过,“这个是一个严肃的话题,你可以从中收获一些东西”,当然,我并不希望你来收获乱伦的知识和心得,酷壳是一个技术博客,应该是收获技术方面的东西。
从技术的角度上来说,这是我们经常在设计软件时犯的错误——
1)作了错误的假设(Assumption)
Assumption是软件设计的重大天敌,Assumption的动词Assume意为Ass u me – Ass you and me 。你的假设做得越多,你的设计就越不靠谱。这里的假设是——我们以为family tree是一个tree,其实并不是tree。Assumption是魔鬼。
还有一些经典的Assumption如下所示
- 最著名的就是那个y2k臭虫。
- 不要以为没有2月30日,在瑞典1712年有2月30日
- 一分钟有60秒?闰秒呢?
- 双胞胎的生日是同一天吗?
- 双胞胎的父亲是同一个?
- 性别只有男和女?
- 婚姻只能是异性? 关于这一点,推荐一篇强文——Gay marriage: the database engineering perspective (同性婚姻:数据库工程)
2)没有认真分析用户案例(Use Case)
在设计软件时,我们需要考虑各种各样的用户案例,比如如下的东西:
- 私生子的问题
- 一夫多妻或一妻多夫,同父异母,同母异父
- 就算一夫多妻制违反法律,也会有离异再婚的情况
- 同性恋的问题,虽然不能繁衍,但可以领养。
- 换妻活动
- 各种乱伦关系——这种东西那个民族都不少,尤其是古时候,比如:
不想再列下去了,人类真TMD恶心,有点要吐了。
——————————为了缓解一下恶心的气氛,请允许我插入一个搞笑短文——————————
一位自杀者在他的遗书里讲述了他自杀的原因,听起来实在让人头痛。遗书这样写道:“我和一个寡妇结了婚,她有一个已成年的女儿,我父亲跟我妻子带过来的女儿结了婚。所以我父亲就成了我的女婿,女儿就成了我的后母,我管父亲叫爸爸,而我父亲也管我叫爸爸;我女儿管我叫爸爸,但我却管她叫妈妈;我还得管我妻子叫姥姥,因为她是我后母的母亲。不久我女儿,也就是我后母生了一个儿子,他是我同父异母的弟弟,他也得管我叫姥爷,因为他也是我的外孙。后来我妻子,也就是我姥姥生了一个儿子,他是我后母的弟弟,我是他的外甥,所以儿子管我叫爸爸,我管儿子叫舅舅。另外我是我妻子,也就是我姥姥的外孙,同时也是我姥姥的丈夫,所已我也是我的外祖父。又因为我妻子是我的外祖母,我的儿子,也就是我的舅舅是我的弟弟和我女儿的弟弟,所以我……我的天哪,这么复杂的关系实在让我伤透了脑筋,我只有一死才能得以解脱……”
————————————————————————插入完毕————————————————————
看完上面这个短文,不知道你是否和我一样,觉得这么一个简单的程序将是如此难做啊。另外,我决定在下一次的面试中让应聘者来设计Family Tree的程序。
我又说多了,现在还是让我们回到技术上来。除了上面那几个观点,我在回复中还看到了如入一些有意思的回复:
- “我的软件没有bug,是你的生活有bug”——让我想到了程序员惯用的借口
- “算法中不应该加太多的限制,限制多了反而让算法不灵活。”
- “移除断言,并不代表就不出错,对于这种rare case,我们最好给一个Warning提醒用户,让用户确认确实是这样的。”
- “关于解决这个问题,移除那个断言,如果显示上会有问题的话,那就复制一下有不同关系的人就可以了”
- “你真的应该想想你的软件的价值是什么?市场在哪里?你真的要照顾这样的用户吗?”
挺好的,相信你对软件开发又学到了一些东西。
(转载时请勿用于商业目的,并请注明作者和出处)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《软件真的好难做啊》的相关评论
其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。
。。。。。。。。。。。。。。。。。。。。
看来是X和其儿子生了Y
首先,吕后是刘邦的发妻,不是“母后”。
然后,在探讨伦理学问题的时候,应该考虑时代和地域造成的文化差异,事实上,在中国古代和当今世界不少国家和地区(包含港澳)表亲通婚都是合法的,如果你的软件期望国际化,这就是必须考虑的用例。
参见 http://en.wikipedia.org/wiki/Cousin_marriage
以及 http://zh.wikipedia.org/zh-cn/%E8%A1%A8%E5%93%A5
另外近亲结婚带来的并非全是风险,参见 http://www.sciencevie.cn/gb/article/200804/msgtree/20083191548226009.htm
以上
“我的软件没有bug,是你的生活有bug”
“你真的应该想想你的软件的价值是什么?市场在哪里?你真的要照顾这样的用户吗?”
对这两种意见再说几句。
发表这种意见的朋友似乎没有考虑到发帖求助的程序员维护的是“家谱”软件,而不是给新生儿上户口的系统。我想活在当下的人们似乎并无能力干涉祖宗之间的婚事,并且人类历史这么长,能拍着胸脯保证列祖列宗始终坚持着优生优育传统的人又有多大比例呢?如果用户仅仅因为祖上婚配不慎就遭系统拒绝,这不是歧视么?
打酱油,飘过
大叔网站要一直在,我要学东西。
我设计UI的,不懂这个!
可以做个PDM的东东吧,或做个UI设计吧。。。。。。。。。
这其实是一个哲学问题。想用计算机技术解决这个问题本身就是错误的。说到底软件只是一堆0或1,想用它来解决这种模棱两可没有绝对正确的答案的抽象问题是不可能的。所以,这个问题还是让人来解决比较好,例如弹出一个窗口,让用户来填写他觉得正确的答案。
生活太复杂
如果是单纯的制图,可以支持。
不然不解决,也无法解决。
程序不能超越程序员的思想。
人与人之间关系本来就不是唯一的, 这种断言本身就不合适
家族关系是基于血缘的, 应该以血缘为基础设计数据结构, 家族关系在这之上计算得到
其实这种乱伦现象在动物里变现得更明显,相对而言,我反倒觉得人类已经做得不错了。。
@soliton
其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。
一开始我也看不明白,估计他想表达的意思是:X:用户 Y:用户和用户的女儿所生的儿子
有点乱,不过感觉没必要为极少数人的需求进行修改!
针对特定情况
还真的是很难做啊。。
“真到有一天”?
笔者应该是要写”直到有一天”吧~
这个有点邪恶
看到这里,我突然想为什么族谱非得用树来表示,如果用具有树形显示双向图来表示,那任何包含自反关系的族谱都不会出现这种问题了.
比如一个双性人做了单性手术回到了过去与自己生了一个孩子,最后莫名其妙的发现原来自己的亲生父亲就是自己的未来.
不能再多想了,哈哈哈哈