### 軟件編程規范
在當前軟件行業迅猛的發展下,軟件逐漸走向大型化。在這種軟件走向大型化的形勢下,一個軟件需要眾多的人參與。比如一個操作系統的開發需要上千人的工作。這樣我們就不得不面臨著如何管理。
只要是一個有用的軟件就需要大量的工作,首先要進行[軟件需求分析](https://baike.baidu.com/item/%E8%BD%AF%E4%BB%B6%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90/10986816),然后要設計出軟件的框架,而實現軟件的代碼僅占很少一部分(約20%)。而你不要小看這代碼的實現,也是要很多人的參與的,一般[軟件代碼](https://baike.baidu.com/item/%E8%BD%AF%E4%BB%B6%E4%BB%A3%E7%A0%81/3030633)就有上千行,更別說操作系統了,據說Linux就有千萬行的代碼。這就需要把一個軟件分成很多小的模塊,分工完成。
搭建項目結構的起步過程,合適的命名規范、模塊的劃分、目錄(包)的命名,如果做的足夠好,別人導入項目后可能只需要10分鐘就可以大概了解系統結構。
### 開發規范的目的
* 養成良好的編程習慣;
* 寫出清楚、易懂、易維護的程序代碼;
* 提高協同、開發效率;
* 減少編碼過程中不必要的錯誤;
* 降低企業成本。
**制定一個符合自己公司情況的開發規范是很簡單的,重要的是我們能夠認識到規范的重要性,并堅持規范的開發習慣。**
#### HTML
省略圖片、樣式、腳本以及其他媒體文件 URL 的協議部分([http:,https:](http://%2Chttps/)),除非文件在兩種協議下都不可用。這種方案稱為 protocol-relative URL,好處是無論你是使用 HTTPS 還是 HTTP 訪問頁面,瀏覽器都會以相同的協議請求頁面中的資源,同時可以節省一部分字節。
**協議**
~~~
<!-- Not recommended -->
<script src="https://www.google.com/js/gweb/analytics/autotrack.js"></script>
<!-- Recommended -->
<script src="//www.google.com/js/gweb/analytics/autotrack.js"></script>
/* Not recommended */
.example {
background: url("https://www.google.com/images/example");
}
/* Recommended */
.example {
background: url("//www.google.com/images/example");
}
~~~
**縮進**
一次縮進2個空格,不要使用 tab 或者混合 tab 和空格的縮進。
~~~
<ul>
<li>Fantastic
<li>Great
</ul>
.example {
color: blue;
}
~~~
**大小寫**
推薦使用小寫字母,小寫風格看起來更加清爽,容易識別和編寫。
~~~
<!-- Not recommended -->
<A HREF="/">Home</A>
/* Not recommended */
color: #E5E5E5;
<!-- Recommended -->
<img src="google.png" />
/* Recommended */
color: #e5e5e5;
~~~
**代碼注釋**
采用類似標簽閉合的寫法,與HTML統一格式;注釋文案兩頭空格,與CSS注釋統一格式。
* 開始注釋:(注釋兩頭空格)。
* 結束注釋:(注釋前加`/`符號,類似標簽的閉合)。
* 允許只有開始注釋
~~~html
<body>
<!-- 側欄內容區 -->
<div class="m-side">
<div class="side">
<div class="sidein">
<!-- 熱門標簽 -->
<div class="sideblk">
<div class="m-hd3"><h3 class="tit">熱門標簽</h3> </div>
...
</div>
<!-- 最熱TOP5 -->
<div class="sideblk">
<div class="m-hd3">
<h3 class="tit">最熱TOP5</h3>
<a href="#" class="s-fc02 f-fr">更多?</a>
</div>
...
</div>
</div>
</div>
</div>
<!-- /側欄內容區 -->
</body>
~~~
**HTML 正確性**
盡可能使用正確的 HTML。
~~~
<!-- Not recommended -->
<title>Test</title>
<article>This is only a test.
<!-- Recommended -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test</title>
<article>This is only a test.</article>
~~~
**HTML 語義化**
根據使用場景選擇正確的 HTML 元素(有時被錯誤的稱為“標簽”)。例如,使用 h1 元素創建標題,p 元素創建段落,a 元素創建鏈接等等。正確的使用 HTML 元素對于可訪問性、可重用性以及編碼效率都很重要。
~~~
<!-- Not recommended -->
<div onclick="goToRecommendations();">All recommendations</div>
<!-- Recommended -->
<a href="recommendations/">All recommendations</a>
~~~
**多媒體元素降級**
對于像圖片、視頻、canvas 動畫等多媒體元素,確保提供其他可訪問的內容。圖片可以使用替代文本(alt),視頻和音頻可以使用文字版本。
~~~
<!-- Not recommended -->
<img src="spreadsheet.png">
<!-- Recommended -->
<img src="spreadsheet.png" alt="Spreadsheet screenshot.">
~~~
**合理的結構布局**
* 按照從上至下、從左到右的視覺順序書寫HTML結構。
* 用`<div>`代替`<table>`布局,但表現具有明顯表格形式的數據,首選`<table>`。
* 結構上如果可以并列書寫,就不要嵌套。
* 如果可以寫成`<div></div><div></div>`那么就不要寫成`<div><div></div></div>`
* 如果結構已經可以滿足視覺和語義的要求,那么就不要有額外的冗余的結構。
* 如果`<div><h2></h2></div>`已經滿足要求,那么就不要再寫成`<div><div><h2></h2></div></div>`
**頁面結構命名參考**
1. page: 代表整個頁面,用于最外層。
2. wrap: 外套,將所有元素包在一起的一個外圍包,用于最外層
3. wrapper: 頁面外圍控制整體布局寬度,用于最外層
4. container: 一個整體容器,用于最外層
5. head, header: 頁頭區域,用于頭部
6. nav: 導航條
7. content: 內容,網站中最重要的內容區域,用于網頁中部主體
8. main: 網站中的主要區域(表示最重要的一塊位置),用于中部主體內容
9. column: 欄目
10. sidebar: 側欄
11. foot, footer: 頁尾、頁腳。網站一些附加信息放置區域,(或命名為 copyright)用于底部
#### CSS
**語義化命名**
id和class的命名時要有效反應元素目的和用途的名稱,或其他通用的名稱,不要使用表象和晦澀難懂的名稱。應該根據`他們是什么`來為元素命名,而不應該根據`他們的外觀如何`來命名。
~~~xml
/* Not recommended */
<div class="red">
<div class="top_nav">
/* Not recommended */
<div class="button_green"></div>
<div class="clear "></div>
/* Recommended */
<div class="error"></div>
<div class="login"></div>
<div class="main_nav">
~~~
id 和 class 應該盡量簡短,同時要容易理解。
~~~
/* Not recommended */
#navigation {}
.atr {}
/* Recommended */
#nav {}
.author {}
~~~
**CSS書寫順序**
1. 位置屬性(position, top, right, z-index, display, float等)
2. 大小(width, height, padding, margin)
3. 文字系列(font, line-height, letter-spacing, color- text-align等)
4. 背景(background, border等)
5. 其他(animation, transition等)
~~~css
<!--推薦寫法-->
.heavy{
position: absolute;
top: 0;
left: 10px;
width: 100px;
color: #008000;
background: url(../img/logo.pg) no-repeat left center;
}
~~~
**選擇器**
除非需要,否則不要在 id 或 class 前加元素名。
~~~
/* Not recommended */
ul#example {}
div.error {}
/* Recommended */
#example {}
.error {}
~~~
**屬性簡寫**
盡量使用 CSS 中可以簡寫的屬性 (如 font),可以提高編碼效率以及代碼可讀性。
~~~
/* Not recommended */
border-top-style: none;
font-family: palatino, georgia, serif;
font-size: 100%;
line-height: 1.6;
padding-bottom: 2em;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;
/* Recommended */
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;
~~~
**0 和單位**
值為 0 時不用添加單位,值在 -1 和 1 之間時,不需要加 0。
~~~
margin: 0;
padding: 0;
font-size: .8em;
~~~
**推薦使用子選擇器,避免使用標簽名**
~~~xml
<!--推薦寫法-->
.warp> .heavy{
font-size: 14px;
}
<!--不推薦寫法-->
.warp span{
font-size: 14px;
}
~~~
**命名空間**
給最外層的父容器設置選擇器防止命名沖突,同時提高代碼可維護性。
~~~
.adw_container {}
#note_container {}
~~~
**選擇器命名分隔符**
選擇器中使用連字符可以提高可讀性。
~~~
/* Not recommended: does not separate the words “demo” and “image” */
.demoimage {}
/* Not recommended: uses underscore instead of hyphen */
.error_status {}
/* Recommended */
#video-id {}
.ads-sample {}
~~~
**內容縮進**
為了反映層級關系和提高可讀性,塊級內容都應縮進。
~~~
@media screen, projection {
html {
background: #fff;
color: #444;
}
}
~~~
**聲明結束**
每行 CSS 都應以分號結尾。
~~~
/* Not recommended */
.test {
display: block;
height: 100px
}
/* Recommended */
.test {
display: block;
height: 100px;
}
~~~
**屬性名結尾**
屬性名和值之間都應有一個空格。
~~~
/* Not recommended */
h3 {
font-weight:bold;
}
/* Recommended */
h3 {
font-weight: bold;
}
~~~
**聲明樣式塊的分隔**
在選擇器和 {} 之間用空格隔開。
~~~
/* Not recommended: missing space */
#video{
margin-top: 1em;
}
/* Not recommended: unnecessary line break */
#video
{
margin-top: 1em;
}
* Recommended */
#video {
margin-top: 1em;
}
~~~
**選擇器分隔**
每個選擇器都另起一行。
~~~
/* Not recommended */
a:focus, a:active {
position: relative; top: 1px;
}
/* Recommended */
h1,
h2,
h3 {
font-weight: normal;
line-height: 1.2;
}
~~~
**規則分隔**
規則之間都用空行隔開。
~~~
html {
background: #fff;
}
body {
margin: auto;
width: 50%;
}
~~~
**CSS 引號**
屬性選擇器和屬性值用單引號,URI 的值不需要引號。
~~~
/* Not recommended */
@import url("//www.google.com/css/maia.css");
html {
font-family: "open sans", arial, sans-serif;
}
/* Recommended */
@import url(//www.google.com/css/maia.css);
html {
font-family: 'open sans', arial, sans-serif;
}
~~~
**分段注釋**
用注釋把 CSS 分成各個部分。
~~~
/* Header */
#adw_header {}
/* Footer */
#adw_footer {}
/* Gallery */
.adw_gallery {}
~~~
**文本命名參考**
1. index.css: 一般用于首頁建立樣式
2. head.css: 頭部樣式,當多個頁面頭部設計風格相同時使用。
3. base.css: 共用樣式。
4. style.css: 獨立頁面所使用的樣式文件。
5. global.css: 頁面樣式基礎,全局公用樣式,頁面中必須包含。
6. layout.css: 布局、版面樣式,公用類型較多時使用,一般用在首頁級頁面和產品類頁面中
7. module.css: 模塊,用于產品類頁,也可與其它樣式配合使用。
8. master.css: 主要的樣式表
9. columns.css: 專欄樣式
10. themes.css: 主體樣式
11. forms.css: 表單樣式
12. mend.css: 補丁,基于以上樣式進行的私有化修補。
**導航命名參考**
1. nav, navbar, navigation, nav_wrapper: 導航條或導航包,代表橫向導航
2. top_nav: 頂部導航
3. main_nav: 主導航
4. sub_nav: 子導航
5. sidebar: 邊導航
6. left_sidebar: 左導航
7. right_sidebar: 右導航
8. title: 標題
9. summary: 摘要
10. menu: 菜單,區域包含一般的鏈接和菜單
11. sub_menu: 子菜單
12. drop: 下拉
13. dorp_menu: 下拉菜單
14. links: 鏈接菜單
**功能命名**
1. logo: 標記網站logo標志
2. banner: 標語、廣告條、頂部廣告條
3. login: 登陸,(例如登錄表單:form_login)
4. login_bar: 登錄條
5. register: 注冊
6. tool, toolbar: 工具條
7. search: 搜索
8. search_bar: 搜索條
9. search_input: 搜索輸入框
10. shop: 功能區,表示現在的
11. icon: 小圖標
12. label: 商標
13. homepage: 首頁
14. subpage: 二級頁面子頁面
15. hot: 熱門熱點
16. list: 文章列表,(例如:新聞列表:list_news)
17. scroll: 滾動
18. tab: 標簽
19. sitemap: 網站地圖
20. message: 提示信息
21. current: 當前的
22. joinus: 加入
23. status: 狀態
24. btn: 按鈕,(例如:搜索按鈕可寫成:btn_search)
25. tips: 小技巧
26. note: 注釋
27. guild: 指南
28. arr, arrow: 標記箭頭
29. service: 服務
30. breadcrumb: (即頁面所處位置導航提示)
31. download: 下載
32. vote: 投票
33. site_info: 網站信息
34. partner: 合作伙伴
35. link, friend_link: 友情鏈接
36. copyright: 版權信息
37. siteinfo_credits: 信譽
38. siteinfo_legal: 法律信息
### Javascript
**命名規范**
**駝峰式命名法介紹**
* 大駝峰式命名法 ```StudentInfo、UserInfo、ProductInfo```
* 小駝峰式命名法 ```studentInfo、userInfo、productInfo```
**變量**
* 命名方法:小駝峰式命名法
* 命名規范:前綴應當是動詞。(函數的名字前綴為動詞,以此區分變量和函數)。
* 命名建議:盡量在變量名字中體現所屬類型,如:length、count等表示數字類型;而包含name、title表示為字符串類型。
~~~csharp
// 推薦
const maxCount = 10;
const tableTitle = 'LoginTable';
// 不推薦
const setCount = 10;
const getTitle = 'LoginTable';
~~~
**函數**
* 命名方法:小駝峰式命名法
* 命名規范:前綴應當是名詞。(函數的名字前綴為動詞,以此區分變量和函數)
* 動詞建議:參考下表
| 動詞 | 含義 | 動詞 | 含義 |
| :---: | :---: | :---: | :---: |
| can | 能夠 | transfer | 轉換 |
| has | 含有 | finish | 完成 |
| is | 判斷是否為某值 | append | 添加 |
| get | 獲取某值 | set | 設置某值 |
| load | 加載數據 | save | 保存 |
| add | 添加 | remove | 刪除 |
| create | 創建 | destory | 銷毀 |
| start | 啟動 | stop | 停止 |
| open | 打開 | close | 關閉 |
| read | 讀取 | write | 寫入 |
| begin | 開始 | end | 結束 |
| backup | 備份 | restore | 恢復 |
| import | 導入 | export | 導出 |
| split | 分割 | merge | 合并 |
| inject | 注入 | extract | 提取 |
| attach | 附著 | detach | 脫離 |
| bind | 綁定 | separate | 分離 |
| view | 查看 | browse | 瀏覽 |
| edit | 編輯 | modify | 修改 |
| select | 選取 | mark | 標記 |
| copy | 拷貝 | paste | 粘貼 |
| undo | 撤銷 | redo | 重做 |
| insert | 插入 | delete | 移除 |
| clean | 清理 | clear | 清除 |
| index | 索引 | sort | 排序 |
| find | 查找 | search | 搜索 |
| increase | 增加 | decrease | 減少 |
| play | 播放 | pause | 暫停 |
| launch | 啟動 | run | 運行 |
| compile | 編譯 | execute | 執行 |
| debug | 調試 | trace | 跟蹤 |
| observe | 觀察 | listen | 監聽 |
| build | 構建 | publish | 發布 |
| input | 輸入 | output | 輸出 |
| encode | 編碼 | decode | 解碼 |
| compress | 壓縮 | decompress | 解壓縮 |
| pack | 打包 | unpack | 解包 |
| parse | 解析 | emit | 生成 |
| connect | 連接 | disconnect | 斷開連接 |
| send | 發送 | recive | 接收 |
| download | 下載 | upload | 上傳 |
| refresh | 刷新 | synchronize | 同步 |
| lock | 鎖定 | unlock | 解鎖 |
| check out | 遷出 | check in | 遷入 |
| update | 更新 | revert | 復原 |
| submit | 提交 | commit | 交付 |
| push | 推 | pull | 拉 |
| expand | 展開 | collapse | 折疊 |
| begin | 開始 | end | 結束 |
| enter | 進入 | exit | 退出 |
| abort | 放棄 | quit | 離開 |
| collect | 收集 | aggregate | 聚集 |
| obsolete | 廢棄 | depreciate | 廢舊 |
~~~jsx
// 是否可閱讀
function canRead() {
return true;
}
// 獲取名稱
function getName() {
return this.name;
}
~~~
**常量**
* 命名方法:名稱全部大寫。
* 命名規范:使用大寫字母和下劃線來組合命名,下劃線用以分割單詞。
~~~csharp
const MAX_COUNT = 10;
const URL = 'http://www.xxx.com';
~~~
**構造函數**
* 命名方法:大駝峰式命名法,首字母大寫。
~~~jsx
function Student(name) {
this.name = name;
}
var st = new Student('tom');
~~~
**類的成員**
* 公共屬性和方法:跟變量和函數的命名一樣
* 私有屬性和方法:前綴為\_(下劃線),后面跟公共屬性和方法一樣的命名方式
~~~jsx
function Student(name) {
// 私有成員
var _name = name;
// 公共方法
this.getName = function () {
return _name;
}
// 公共方式
this.setName = function (value) {
_name = value;
}
}
var st = new Student('tom');
st.setName('jerry');
// => jerry:輸出_name私有變量的值
console.log(st.getName());
~~~
**單行注釋**
* 說明:單行注釋以兩個斜線開始,以行尾結束
* 語法:// 這是單行注釋
* 使用方式://(雙斜線)與注釋文字之間保留一個空格。
~~~csharp
// 調用了一個函數
setTitle();
~~~
**多行注釋**
* 說明:以/*開頭,*/結尾
* 語法:/\* 注釋說明 \*/
* 使用方式:至少三行注釋時,第一行為/*,最后行為*/,其他行以*開始,并且注釋文字與*保留一個空格。
~~~cpp
/*
* 代碼執行到這里后會調用setTitle()函數
* setTitle():設置title的值
*/
setTitle();
~~~
**函數(方法)注釋**
* 說明:函數(方法)注釋也是多行注釋的一種,但是包含了特殊的注釋要求
* 語法:如下
~~~dart
/**
* 函數說明
* @關鍵字
*/
~~~
| 注釋名 | 語法 | 含義 | 示例 |
| :---: | :---: | :---: | :---: |
| @param | @param 參數名 {參數類型} 描述信息 | 描述參數的信息 | @param name {String} 傳入名稱 |
| @return | @return {返回類型} 描述信息 | 描述返回值的信息 | @return {Boolean} true:可執行;false:不可執行 |
| @autho | @author 作者信息 \[附屬信息:如郵箱、日期\] | 描述此函數作者的信息 | @author 張三 2015/07/21 |
| @version | @version XX.XX.XX | 描述此函數的版本號 | @version 1.0.3 |
| @example | @example 示例代碼 | 演示函數的使用 | @example setTitle('測試') |
~~~dart
/**
* 合并Grid的行
* @param {Grid} grid 需要合并的Grid
* @param {Array} cols 需要合并列的Index(序號)數組;從0開始計數,序號也包含。
* @param {Boolean} isAllSome 是否2個tr的cols必須完成一樣才能進行合并。true:完成一樣;false(默認):不完全一樣
* @return void
* @author polk6 2015/07/21
* @example
* _________________ _________________
* | 年齡 | 姓名 | | 年齡 | 姓名 |
* ----------------- mergeCells(grid,[0]) -----------------
* | 18 | 張三 | => | | 張三 |
* ----------------- - 18 ---------
* | 18 | 王五 | | | 王五 |
* ----------------- -----------------
*/
function mergeCells(grid, cols, isAllSome) {
// Do Something
}
~~~
**不要在循環里面進行DOM操作**
~~~java
//推薦
var htmlString = "";
for(var i =0; i<length;i++){
htmlString += html;
}
$(“.class”).append(htmlString);
//不推薦
for(var i =0; i<length;i++){
$(“.class”).append(html);
}
~~~
**能用CSS實現不用JS實現**
**減少js操作DOM**
在js操作DOM的過程中,要避免頻繁改動DOM結構,可以先使用字符串方式組裝html代碼,再插到DOM結構中去。
**使用事件委托**
* 對于多個同性質同輩節點,避免逐個進行事件綁定。而應該利用冒泡原理,將事件委托給父節點。
* 事件委托要接近事件觸發節點,避免將所有事件冒泡委托給body節點
~~~jsx
//推薦
$("table").on("click","td",function(){
})
//不推薦
$("td").on("click",function(){
})
~~~
#### **結語**
**堅持遵循代碼規范。**
**寫代碼前先看看周圍同事的代碼,然后決定代碼風格。**
**代碼規范的意義在于提供一個參照物,不會讓閱讀你代碼的人覺得很痛苦。**
*****
主要參考鏈接
[HTML規范 - 簡書 - 辣瓜瓜](https://www.jianshu.com/u/42285a60545e)
[前端開發規范 - codeceo](http://www.codeceo.com/article/google-html-css-style-guide.html)
[前端開發規范 - Google](http://www.chaozh.com/google-front-end-style-guide)
[Javascript開發規范 - Google](http://alloyteam.github.io/JX/doc/specification/google-javascript.xml)
*****
其他參考鏈接
[PHP開發規范 - W3C](https://www.w3cschool.cn/phpkfbmgf/apedj4.html)
[Java開發規范 - 華為](https://wenku.baidu.com/view/b9533dea647d27284a735199.html)
[Java開發規范 - 阿里巴巴](https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E5%8D%8E%E5%B1%B1%E7%89%88%EF%BC%89.pdf)
*****
- 版本控制之Git簡介
- Git工作流程
- Git工作區、暫存區、版本庫
- Git 指令匯總
- Git 忽略文件規則 .gitignore
- pull request
- HTTP簡介
- HTTP - Keep-Alive
- HTTP緩存
- XMLHttpRequest
- Fetch
- 跨域
- HTTP 消息頭
- TCP/IP
- TCP首部
- IP首部
- IP 協議
- TCP/IP漫畫
- 前端開發規范
- 前端開發規范整理
- 前端未來規劃
- HTML思維導圖
- CSS思維導圖
- 布局
- position,float,display的關系和優先級
- line-height、height、font-size
- 移動端適配
- JS 對象
- JS 原型模式 - 創建對象
- JS 預編譯
- 探索JS引擎
- ES