1. 什么是软件开发中的过度设计
过渡设计的概念不太好确定。
下面是我的个人经验:
1)设计的人力成本过高。
例如开发一个团队内部使用的软件。该软件只需要在项目持续的6个月内进行使用。但是开发人员从界面到性能,从功能到安全性全方面的设计。最终导致该软件的开发消耗了3个月的时间。这时,不如用半个月的时间开发一个界面常简陋,甚至偶尔会崩溃的小程序。
2)设计的功能使用率很低。
例如开发一个P2P下载软件。该软件主要是提供下载的功能。但是实际开发过程中将10%的成本投入到软件的语音识别功能上。此时需要评估该功能的使用人群,使用频率,产品实际效果是否能达到预期等等。
3)实现该设计导致代码易读性,可维护性,性能下降。
我们在进行开发时就遇到该情况。实际产生作用的代码很少,但是在设计时强行追加了很多设计模式。虽然看上去“高大上”了,实际维护时,却需要花费大量的人力去维护该设计。有时甚至会出现这种设计模式导致功能复杂度上升的情况。这类问题往往是大型项目在进行设计时易出现的。总设计师希望把该设计贯穿到每个功能模块,但是却忽略了某些模块的特殊性。
2. 什么是软件开发中的过度设计
1)设计的人力成本过高。
例如开发一个团队内部使用的软件。该软件只需要在项目持续的6个月内进行使用。但是开发人员从界面到性能,从功能到安全性全方面的设计。最终导致该软件的开发消耗了3个月的时间。这时,不如用半个月的时间开发一个界面常简陋,甚至偶尔会崩溃的小程序。
2)设计的功能使用率很低。
例如开发一个P2P下载软件。该软件主要是提供下载的功能。但是实际开发过程中将10%的成本投入到软件的语音识别功能上。此时需要评估该功能的使用人群,使用频率,产品实际效果是否能达到预期等等。
3)实现该设计导致代码易读性,可维护性,性能下降。
我们在进行开发时就遇到该情况。实际产生作用的代码很少,但是在设计时强行追加了很多设计模式。虽然看上去“高大上”了,实际维护时,却需要花费大量的人力去维护该设计。有时甚至会出现这种设计模式导致功能复杂度上升的情况。这类问题往往是大型项目在进行设计时易出现的。总设计师希望把该设计贯穿到每个功能模块,但是却忽略了某些模块的特殊性。
3. 过度设计什么意思
以前总是举不出过度设计的例子,今天遇上一件事,总算有了一个反例:
程序员A编写代码,记录用户购买商品记录,设计1个8字节字段,前4个放用户ID,后4个放商品ID。
粗看设计没有太大问题。实际编码中,发现数据库中商品ID,是long long类型,8个字节。他遇上困难,卡在那里了。他找上leader,说明要改设计,需要更多时间,完美兼容这种情况。
但是现在没有足够的时间,来做大的变动,于是找了个折中方案,整个字段8字节放商品ID,另外再用一张表去关联用户ID同商品ID的购买关系。
在我看来,这就是过度设计了。
我的方案,仍然坚持原有设计,前4字节放用户ID,后4个字节放商品ID的后4字节。这个方案,是有缺陷的,商品ID是一个自增的循环数,存在一种 用户ID+商品ID后4字节 重复的可能性。
但是我们考虑一下,现有商品ID增长到:约2亿,4个字节能够支撑40亿商品,现有商品库运营4年了。
按照现在的业务发展速度,无论如何,2年内,我看不到一点重复的可能。不需要重新设计,简单把功能实现。并记录,规划在1年后重构这部分代码。(很可能在1年内,这个模块就因为其它原因要重构)
为什么要为了未来的支撑能力,耗费现在的开发资源呢?做一个额外的表,不是增加新的逻辑吗?
再举一个例子,对闰年的判断逻辑:
1、 if($Year%4==0) return True; else return Fasle;
2、if ( ($Year%4==0 && $Year%100!=0 ) || $Year%400==0 ) retrue True; else return False;
我选择了第一种逻辑,当然第二种更为标准。我的原因是:
1、第一种逻辑速度够快;
2、我做的不是日历程序,只是一个应用需要判断闰年;2100年,对我来说太遥远,我的编码活不到那一年,中间肯定被别人废弃了。在未来的80多年中,我的代码都不会出问题。
过度设计,需要更多设计时间和测试成本,如无必要,还是尽量简洁一些好。
4. 如何学好编程
前几天重读Eric S. Raymond的How to become a hacker,看到他推荐编程入门选用Python,突然觉得很压抑,有了些想法。我建议编程入门的人学C或者Pascal,如果更进一步的话可以用汇编语言,因为这样能更清楚的了解底层。 下面针对一些支持选用java, Python, C++(指用了非C特性的C++)等高级的OO语言入门的人可能的原因作些说明。 1. Pascal, C太老了,过时了,平时用得很少,现在流行Java等等。 标准Pascal的确是比较老了,不过有Delphi后继呢,说C老恐怕就是无知了,C现在用得很广泛,似乎sourceforge.net上的项目还是 C的最多。推荐Pascal不是因为Delphi。选择Pascal, C是觉得两个现在很常见,语法很有代表性,简洁明了。 不要动不动觉得什么东西过时了,COBOL还有OO版本面世,还有FORTRAN,LISP,好古老的语言吧,现在还用得很广呢。 2.入门要从OO开始,培养用OO方式思考的习惯。 首先要说明,OO是方法,不是语言,初学者一入门便摆弄Java, Python, Delphi等很容易形成误解,似乎OO=Java, Python, C++... 其次,过程式语言(或者说结构化方法)的精髓不会消亡,OO里面也不可能摆脱掉一条条的语句、函数调用,结构化方法还是需要提倡的。OO方法不是那么容易学会的(OO语言的语法弄得很熟练不代表你懂OO),而结构化那套方法,自个写个千把行的程序就很能体会了,我是说写个实用点的东西,比如试着自个实现一些数据结构和算法,写几个小游戏等。写个一千行Hello world等于没写。 我觉得方法是实践中体会出来的,不是看看书就能学会的,你看Design Patterns等把模式背的滚瓜烂熟很可能会陷入过度设计的泥潭,你写了几千行代码,然后再去读一读,改改调试调试,慢慢增加功能,你就会发现自己代码写的有多么臭了,然后看看书听听别人意见你就知道什么叫Best practice了,最好的经验就是在焦头烂额之际得到的。 过程式语言的代码一般比较简练,我们编程序最终的目的是要解决问题,是要计算,是要获取信息,不要被OO, pattern, EJB, Web Services等迷糊了(我不是反对这些技术). 强烈建议各位多读代码,你去看看莱昂氏的那本UNIX v6源码分析,仔细看,慢慢看,你就能体会到什么叫精致的代码了,然后尝试按照那个风格写代码。 3.过程式语言弄久了,很难转入OO的思维模式 我以前也没有深想过这个理由,不过时间久了,发觉自己不过是把数据和方法集中在一起而已,看着方便,其实有很多不合理的东西,这里头就需要OO 的理论指导了,还是需要时间来体会。我相信有很多用OO语言的人也不过是在框架里头添添代码,调用来调用去而已,把人类当作数据和操作的打包器。 个人觉得只有在用过程式方法做了十来年,编码上十万行后才有思维定势,难以习惯用OO的眼光看待系统,然而这个转变,我仍觉得比改变一个人的恶习容易许多。OO方法不是学了个Java, Python, C++等就能掌握的,需要实践,需要时间。过程式语言也容易培养一个人严谨的做事态度,比如用Pascal, C等写代码,没有namespace,没有function overload, 没有reference(Pascal有,呵呵,我喜欢),没有template, 没有exception, 你要花很多心思处理一些细节,比如警惕数组索引越界,悬挂指针,野指针等等,请不要觉得麻烦,这个就是计算机啊,底层就是这样的啊。 4.别用C, Pascal了,看我用Java, Python, Delphi, VB, VC等轻轻松松就写了个PP的GUI,NB的分布式应用... 这篇文章是给初学者看的,也可以给一些浮躁的人看看(我也反省,呵呵),初学编程的人精力应该放在数据结构、算法上面,尽量多看一些底层的东西,数字逻辑,操作系统,编译原理,计算机组成、体系结构,计算机网络等等基础知识。编写GUI拖几个控件有什么好吹的,你懂界面设计的原则么,你知道窗口消息怎么回事么,你编的界面是把易用放在第一位呢还是把漂亮放在第一位呢,你的GUI程序容易修改吗?比如我一会要加个button,一会去个 listbox,你会不会改的疯掉呢?你是不是在OnClick里头写了大段大段的代码,做类似“从edit1.text中去掉不是数字的字符,搜索 xxx再转成16进制,再复制到edit2.text”的事? 嗯,你socket弄得熟练,recv来,send去,可是如果你不懂tcp/ip协议那就有点可笑了,除了用别人做好的函数库你还能搞出什么新花样?弄分布式应用的知道“分布式”怎么回事吗, 你是否只是在用API堆砌代码呢?倘若有一天这个函数库没人支持了,你是不是就傻眼了? 比如编游戏,没看过3D图形学便搞DirectX,也是比较可笑的。 我并不是说你编比较高层的东西就必须先得透彻了解底层怎么实现的,我只是建议你好歹把底层的东西混个脸熟,遇到问题时心里有个谱,查查资料,别动不动扑某个论坛求救。以前在BBS上看到某人的话,说BBS不是学习的地方,是开拓眼界的地方。深以为然。 学习还是找纸版的书老实的看比较好,想想你积攒了多少电子书而又看了多少。 底层不了解,仅多也就飘在别人上头,别人一闪身,你就得摔下来。 初学编程的人一来就IDE, GUI, Network啥的猛搞,能不浮躁么?还是沉下心来研究一下基础知识吧,我以脑袋担保你有生之年会觉得他们有用的(呵呵,你转行我就没辙了),别看着别人弄JFC, Socket了你还在头大这个quick sort怎么就不对呢就心里惶惶的,你要知道在一批API不被支持后不少人心里空空的没个着落:天啊,我除了那个就啥都不会了,郁闷啊,花了我那么久时间钻研那套API,呜呜。。。。 5. C好难啊,我入门还是从Java,Python开始吧 首先,是自个要做程序员的吗?是想编程还是想赚钱啊? 其次,我们来比较一下难易: C: k&r那本书真的不算厚,经典的C的书很少,说C难,大概是传说中C的指针很难吧,C的语法很简明的,就是指针,只要你认真看看书,写几个程序试一试,那几个指针的用法不难掌握,另外大家千万不要去死钻*++ ++*之类的语法,关于这点在《开发高手》最后一期上裘宗燕老师有一篇精彩的文章。大家记住写代码是要维护的,别耍弄语法技巧给自己或后人制造麻烦,你想想自己看别人写的天书代码是赞叹还是咒骂? Java: 书太多了啊,就说Gosling(没拼错吧)那本,相当厚,学Java的人一开始都被classpath和package的问题烦过吧,还有Java的关键字,语法,Sun鼓捣出来的一堆堆Java技术名词,是不是有点晕了? C++的确有难度,你可以看看C++语言的设计和演化,就可以知道C++怎么这个德行了,呵呵。有意思的是Java现在加入模版,而且因为伪模版的实现被人诟病,还有那个EJB的转变,有意思,大家可以思考一下“复杂”、“实用”这些词。 Python的确比较清爽,不过深入一点后其内部对象模型也不简单,想想操作一个列表有多少方法,各种功能强大的操作符,而且现在的OO语言逼着你OO, 结果往往是语法OO而已,没多大新意,我还是欣赏Perl, C++这类语言,你想怎么就怎么,重要的是要用合适方法,趁手工具,最少的时间做有价值的东西,把你钻研语言的语法的时间拿来锻炼一下身体,泡杯茶看看小说我觉得更好一些。 语言只是表达思想的工具,不要只局限于一种语言,不要狂热于某一门语言。 学编程时选书最好先看一看书中的代码,是取自实际应用中的吗?写的漂亮吗?(指代码自身的精致,以及排版是否工整)代码中有语法错误吗?(鄙视某些没编译试试就把代码到书里的作者) 有本Essential C#,取的是.Net类库的代码,很棒,讲delegate(希望没拼错,好久没弄这个了)时举的例子很清楚地让人看到这个东西该怎么用。 另外推荐Learning Perl,我个人觉得是我看过的最好的关于编程的书,该讲么,不该讲什么,按什么顺序讲,很好,也许是Perl的精神的感染吧,当初看这本书很有震惊的感觉,原来程序设计语言还可以这么使!爽!参考资料: http://..com/question/7355632.html?fr=qrl3
5. 哪种编程语言最令人讨厌
本排名是根据Quora、Stack Overflow 和 Hacker News 上相关帖子统计出来的。
1.Visual Basic
上榜理由:它的语法被认为过于冗长和陌生,需要动态链接库才能去运行它的代码;对于面向对象编程的支持很有限;事实上,自从1998年以来,微软已经不再提供正式支持了。
如何避免:避免为开发老旧的 Windows 应用程序的公司工作。
2.Perl
上榜理由:Perl中完成一件事有太多种方法,使得你很难去理解其他人编写的代码;太简洁,即使一段代码实现的是最简单的事情,看起来也难以去阅读、维护。
如何避免:不要成为一个程序员。
3.Java
上榜理由:语法冗长;慢;不容易传递函数;API过度设计;它能做的,其他语言也都能做,并且更加高效。
如何避免:不要使用Android SDK来开发任何应用程序。
6. java面向对象程序设计有什么缺点
这个问题好奇怪,问有什么缺点?那应该是要跟其他什么东西作比较
一般说面向对象程序设计的缺点都是和面向过程程序设计比较的
面向对象程序设计的主要缺点就是会让人陷入一种设计深渊之中
什么程序都想着要继承,都想着要面向对象,容易忽略问题的本质,尤其是对象继承,超过三层以后,整个项目的复杂度会变得非常高
简单说就是面向对象会使人过度设计
7. 什么是设计模式,该如何使用设计模式
设计模式是面向对象编程的热门话题之一,越来越多的开发人员认识到设计模式的重要性。采用各种语言实现设计模式的文章也越来越多,但是很多开发人员发现很难将设计模式与实际开发中需要解决的具体问题相联系。因为使用设计模式的难点往往不在于模式的实现,而在于很难确定哪种模式可以在现实的应用场景中采用,从而导致了在现实的项目中,面对客户的压力,我们总是采用最直截了当的方法解决问题,来不及多考虑这些方法的优劣,即使明知将带来更大的麻烦也必须如此。有些时候因为选择了不恰当的设计模式,使原本简单的问题变得复杂化。
总是有些优秀的设计人员可以在同样短的时间内做出正确对待的判断,他们同样是依靠本能和直觉,只是这种本能是在日常编程开发中一点一滴积累起来的。如同一个剑客在危机时刻的一击,并不是一时的灵光乍现,而是平时刻苦修炼的结果。
俗话说,紧靠背棋谱成不了围棋高手。只在概念上理解设计模式而不实现,同样成不了架构设计师。在软件设计时,要有意识地问自己使用还是不使用设计模式,不要匆忙下结论。重视软件质量的改进,如果有可能,则在项目后期重构代码。同时注意学习同行的经验,很多开放源码项目是值得学习的。
(1)正确理解设计模式
模式所关注的不仅是重复的解决方案,更主要的是关注重复出现的应用场景和与场景相关的各种作用力。很多使用设计模式失败的原因,并不是实现设计模式的方法有问题,而是采用的设计模式不适合应用场景。这往往导致设计过度,使软件应得复杂,进而丧失对使用设计模式的信心。
(2)编程语言与设计模式的实现
尽管设计模式本身并不要求一定用某种语言来实现,但脱离了具体的实现,就无法真正理解设计模式。GOF的《设计模式》是经典之作,但毕竟距现在已经十几年了。这个期间开发平台已经进化了多代,很多新技术已经应用到编程中。有些技术可以简化设计模式的实现,有些技术已经采用了设计模式。因此,学习设计模式必须针对所使用的编程语言和开发平台。一定要注意,不是将《设计模式》中的例子转换为C#或者其他语言就等于知道如何实现设计模式了,而是要关注设计模式的精髓,并结合具体的语言特点完成其实现。就.NET而言,很多技术可以简化设计模式的实现,例如采用反射技术实现工厂和采用委托技术实现模板方法等。
(3)需求驱动
需求驱动不仅仅是功能性需求,还包括性能需求及运行时的需求,如软件的可维护性和可复用性等方面。
设计模式是针对软件设计的,而软件设计是针对需求的,一定不要为了使用模式而使用模式。在不合适的场合生搬硬套地使用模式反而会使设计应得复杂,使软件难以调试和维护。
(4)分析成功的模式应用项目
置之死地而后生可以说是一种解决方案,而不是模式,或者说仅仅给出了模式的实现,而没有交代使用的场合。项羽采用这个方案把秦军打败了,但马谡却丢了街亭。
(5)充分了解所使用的开发平台。
总的来说,设计模式是针对面向对象的软件设计的,因此在理论上适合任何面向对象的语言。但随着技术的发展和编程环境的改善,设计模式的实现方式会有很大的差别。在某些平台下,某些设计模式是自然实现的,某些模式已经被平台所实现,某些模式存在的上下文已经消失。
这里的平台不仅指编程语言,还包括平台引入的技术。.NET平台引进了反射、委托,以及属性等新技术,这些技术的使用使设计模式的实现方式有了很大的改变。例如,工厂方法通过采用反射技术,可以将其中的子类去掉。这实际上已经是一个.NET下的新模式,或者说是.NET的方言。
(6)在编程中领悟模式
软件开发是一项实践工作,最直接的方法就是编程。没有定式很熟却从来不下棋的围棋高手,也没有不会编程就成为架构设计师的先例。对设计模式的掌握是水到渠成的事情,你可能是顿悟,也可能是渐悟,但前提是必须有相当的实践积累。当然,并不是不需要看书学习,但实践仍然是必须首先要重视的。
认为编程如同写文章,提高需要有一个过程。在多多编程的同时,需要有一定的技巧。如果希望水平有较大提高,则需要对自己编写的代码不断重构。力求最优是个很好的习惯,当然前提是项目进度允许。即使项目时间紧张,也需要进行适当的总结。隔一段时间检查一下以前的工作,会发现自己是否已经有了提高。
(7)避免设计过度
设计模式解决的是设计不足的问题,但同时也要避免设计过度。一定要牢记简洁原则(Keep It Simple, Stupid, KISS),要知道,设计模式是为了使设计简单,而不是更复杂。如果引入设计模式使设计变得复杂,只能说我们把简单的问题复杂化了,问题本身不需要设计模式。
这里需要把握的是需求变化的程度,一定要区分需求的稳定篇和可变篇。一个软件必然有稳定的篇,这个篇就是核心业务逻辑。如果核心业务逻辑发生变化,软件就没有存在的必要,这个篇的逻辑是我们需要固化的。对于可变的篇,需要判断可能发生变化的程度来确定设计策略和设计风险。要知道,设计过度与设计不足同样对项目有害。
(8)合理看待设计模式的实现实例
现在,从各种途径可以发现各种设计模式的实现实例。需要说明的是,其中很多实例所说明的仅仅是设计模式的解决方案的实现,并没有分析模式使用的上下文。实际上,这也是最困难的篇——从而导致实例中的设计模式使用从实践的角度看,往往是过度设计,也就是有小题大做的嫌疑。
对模式感兴趣的朋友可以从下面的几个开源项目中学习模式的成功应用。以后可能会把模式在下面几个开源代码中的应用的文章与大家共享。