新聞中心
1、過度設(shè)計(jì)有意義嗎?
看著自己每次根據(jù)設(shè)計(jì)原則及模式的代碼重構(gòu),雖效果不錯(cuò),但也自?。喝绻业拿慷未a都這么寫,是不是過度設(shè)計(jì)?把握設(shè)計(jì)的度,需長(zhǎng)久錘煉。行業(yè)也總結(jié)了很多原則,幫助我們把握設(shè)計(jì)的度。它們是一種思考方法、一種行為準(zhǔn)則。

創(chuàng)新互聯(lián)公司專注于沙雅網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供沙雅營(yíng)銷型網(wǎng)站建設(shè),沙雅網(wǎng)站制作、沙雅網(wǎng)頁設(shè)計(jì)、沙雅網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造沙雅網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供沙雅網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
2、KISS
Keep it simple, stupid,保持簡(jiǎn)單、愚蠢。提醒我們大多數(shù)系統(tǒng),與其變得復(fù)雜,保持簡(jiǎn)單能讓系統(tǒng)運(yùn)行更好。越資深的人,越覺得這大有道理。因?yàn)榇罄袀円娮R(shí)過因?yàn)閺?fù)雜而引發(fā)的各種問題。堆太多功能,調(diào)整起來就很費(fèi)勁:
- ? 有現(xiàn)成庫,就不自己寫
- ? 能用文本做協(xié)議,就別用二進(jìn)制
- ? 方法越短小精悍越好
- ? 能把一個(gè)基本流程打通,軟件就能發(fā)布,無需那么多功能(MVP)
真是吸引crud boy,但無法指導(dǎo)具體工作。啥叫保持簡(jiǎn)單,怎么就叫復(fù)雜?這都沒標(biāo)準(zhǔn)。有人基于自己的理解給具體原則:
3、YAGNI
You aren’t gonna need it,你用不著它。如非必要,勿增功能。軟件設(shè)計(jì)對(duì)抗的是需求規(guī)模:
- ? 通過努力,讓軟件在需求規(guī)模膨脹之后,依然能平穩(wěn)發(fā)展
- ? 努力控制需求規(guī)模
很多需求不需要做。很多產(chǎn)品經(jīng)理以為很重要的功能實(shí)際上是沒什么用的。真正重要的功能大約只占20%。做了更多的功能,并不會(huì)得到更多的回報(bào),但是,做了更多的功能,軟件本身卻會(huì)不斷地膨脹,越難維護(hù)。
所以,在現(xiàn)實(shí)經(jīng)常看到一些功能簡(jiǎn)單的東西不斷涌現(xiàn),去顛覆更復(fù)雜東西。如Word強(qiáng)大,但只是個(gè)寫字工具,重點(diǎn)排版功能都用得少。而Markdown簡(jiǎn)單地讓我們專注寫內(nèi)容,而且簡(jiǎn)單的幾個(gè)排版標(biāo)記在日常溝通中就完全夠用。盡量可能不去做不該做的事,從源頭堵住問題。
4、DRY
Don’t repeat yourself,不要重復(fù)自己。在一個(gè)系統(tǒng)中,每一處知識(shí)都必須有單一、明確、權(quán)威地表述。Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
即不要做cv工程師。這還遠(yuǎn)遠(yuǎn)不夠,DRY針對(duì)的是你對(duì)知識(shí)和意圖的復(fù)制:在兩個(gè)不同地方的兩樣?xùn)|西表達(dá)形式不同,但表達(dá)內(nèi)容卻可能相同。如下打印賬戶信息:
public void printBalance(final Account account) {
System.out.printf("Debits: %10.2f\n", account.getDebits());
System.out.printf("Credits: %10.2f\n", account.getCredits());
if (account.getFees() < 0) {
System.out.printf("Fees: %10.2f-\n", -account.getFees());
} else {
System.out.printf("Fees: %10.2f\n", account.getFees());
}
System.out.printf(" ----\n");
if (account.getBalance() < 0) {
System.out.printf("Balance: %10.2f-\n", -account.getBalance());
} else {
System.out.printf("Balance: %10.2f\n", account.getBalance());
}
}這段隱藏一些重復(fù)。如對(duì)負(fù)數(shù)的處理顯然是復(fù)制的,可通過增加一個(gè)方法消除:
String formatValue(final double value) {
String result = String.format("%10.2f", Math.abs(value));
if (value < 0) {
return result + "-";
} else {
return result + " ";
}
}
void printBalance(final Account account) {
System.out.printf("Debits: %10.2f\n", account.getDebits());
System.out.printf("Credits: %10.2f\n", account.getCredits());
System.out.printf("Fees:%s\n", formatValue(account.getFees()));
System.out.printf(" ----\n");
System.out.printf("Balance:%s\n", formatValue(account.getBalance()));
}數(shù)字字段格式反復(fù)出現(xiàn),不過,格式與我們抽取出來的方法一致,復(fù)用:
String formatValue(final double value) {
String result = String.format("%10.2f", Math.abs(value));
if (value < 0) {
return result + "-";
} else {
return result + " ";
}
}
void printBalance(final Account account) {
System.out.printf("Debits: %s\n", formatValue(account.getDebits()));
System.out.printf("Credits: %s\n", formatValue(account.getCredits()));
System.out.printf("Fees:%s\n", formatValue(account.getFees()));
System.out.printf(" ----\n");
System.out.printf("Balance:%s\n", formatValue(account.getBalance()));
}打印格式其實(shí)也重復(fù),如果我要在標(biāo)簽和金額之間加一個(gè)空格,相關(guān)的代碼都要改,所以,這也是一個(gè)可以消除的重復(fù):
String formatValue(final double value) {
String result = String.format("%10.2f", Math.abs(value));
if (value < 0) {
return result + "-";
} else {
return result + " ";
}
}
void printLine(final String label, final String value) {
System.out.printf("%-9s%s\n", label, value);
}
void reportLine(final String label, final double value) {
printLine(label + ":", formatValue(value));
}
void printBalance(final Account account) {
reportLine("Debits", account.getDebits());
reportLine("Credits", account.getCredits());
reportLine("Fees", account.getFees());
System.out.printf(" ----\n");
reportLine("Balance", account.getBalance());
}重構(gòu)后:
- ? 改金額打印格式,就去改formatValue
- ? 改標(biāo)簽格式,就去改reportLine
有人說這種調(diào)整粒度太小。如你這樣感覺,證明你看問題的粒度太大。品味這個(gè)修改,與分離關(guān)注點(diǎn)和單一職責(zé)原則異曲同工:粒度要小。
DRY不局限于寫代碼:
- ? 注釋和代碼之間存在重復(fù),可以嘗試把代碼寫得更清晰
- ? 內(nèi)部API在不同的使用者之間存在重復(fù),可以通過中立格式進(jìn)行API的定義,然后用工具生成文檔、模擬 API 等等
- ? 開發(fā)人員之間做的事情存在重復(fù),可以建立溝通機(jī)制降低重復(fù);……
都是在試圖減少重復(fù),其實(shí)也是減少了維護(hù)成本。
5、簡(jiǎn)單設(shè)計(jì)
Simple Design,提出者Kent Beck,只包含如下規(guī)則,后3條規(guī)則是重構(gòu)方向
(1)通過所有測(cè)試
保證系統(tǒng)能按預(yù)期工作。怎么知道系統(tǒng)按照預(yù)期工作,就需要有配套自動(dòng)化測(cè)試,最好能TDD,最根本的還是要懂設(shè)計(jì),否則,你的代碼就是不可測(cè)。
(2)消除重復(fù)
正如DRY,你得能發(fā)現(xiàn)重復(fù),就要會(huì)分離關(guān)注點(diǎn)
(3)表達(dá)出程序員的意圖
編寫有表達(dá)性的代碼,這也需要你對(duì)“什么是有表達(dá)性的代碼”有認(rèn)識(shí)。代碼要說明做什么,而不是怎么做
(4)讓類和方法的數(shù)量最小化
讓類和方法的數(shù)量最小化,不要過度設(shè)計(jì),除非你已看到這必須要做個(gè)設(shè)計(jì),比如,留下適當(dāng)擴(kuò)展點(diǎn),否則,就不要做。能做出過度設(shè)計(jì)的前提,是已懂得各種設(shè)計(jì),這時(shí)才需要用簡(jiǎn)單設(shè)計(jì)的標(biāo)準(zhǔn)對(duì)自己約束。所謂簡(jiǎn)單設(shè)計(jì),對(duì)大多數(shù)人并不“簡(jiǎn)單”。
沒有良好設(shè)計(jì),代碼就沒有可測(cè)試的接口,TDD就無從談起。不懂設(shè)計(jì),重構(gòu)就只是簡(jiǎn)單提取方法,改改名字,對(duì)代碼的改進(jìn)相當(dāng)有限。
簡(jiǎn)單設(shè)計(jì)的前提是,把編程基礎(chǔ)打牢。片面地追求敏捷實(shí)踐,而忽視基本功,是舍本逐末。
當(dāng)前標(biāo)題:代碼過度設(shè)計(jì),真的有意義嗎?
文章URL:http://www.dlmjj.cn/article/cosdhcs.html


咨詢
建站咨詢
