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)合理看待設計模式的實現實例
現在,從各種途徑可以發現各種設計模式的實現實例。需要說明的是,其中很多實例所說明的僅僅是設計模式的解決方案的實現,並沒有分析模式使用的上下文。實際上,這也是最困難的篇——從而導致實例中的設計模式使用從實踐的角度看,往往是過度設計,也就是有小題大做的嫌疑。
對模式感興趣的朋友可以從下面的幾個開源項目中學習模式的成功應用。以後可能會把模式在下面幾個開源代碼中的應用的文章與大家共享。