---
# System prepended metadata

title: CodeingStyle1.1

---

# CodeingStyle1.1
enum、interface如果只有一個地方使用可以放在CLASS裡面就好
如果有共用頁面的話可以把文案或圖片設定使用XML方式，這樣也可以方便預覽


# CodeingStyle1.0
**codeing style想法收集區**
### 命名
#### colors.xml? 色碼取名 name=顏色英文名 ,顏色英文名_透明度 color_aa00ff00 小雞，pink_red_700_aa熊班、pink_red_700_50(%)結婚吧
#### style命名方式? tvBlack16Bold，目前還是直接set在元件上，通常用在同一頁
#### dimension...設定屬性for元件，*需要再確認
#### 圖片取名?(目前依照zp上給的)，
依功能性命名也許會比較好
ic_heart_on_blue_16_16，
~~ic_heart_off，ic_good，ic_good_blue，ic_good_yellow ic_search_16 ic_search_18~~

#### 內部名稱，跟外部有重複的話，使用this方式即可，如果暫時用加tmp(隆)
![](https://i.imgur.com/1TtuDvX.png)
有趣的是，包名是採全小寫...XDD，保持駝峰(可讀性高)
![](https://i.imgur.com/CCIRFKc.png)


### 結構
#### 分包規範
PBF（按功能分包 Package By Feature）
PBL（按層分包 Package By Layer）
![](https://i.imgur.com/nM0ltGA.png)![](https://i.imgur.com/CsCRTqO.png)



PBF 與 PBL 相比較有如下優勢：
#### package 内高内聚，package 间低耦合
哪块要添新功能，只改某一个 package 下的东西。
PBL 降低了代碼耦合，但帶來了 package 耦合，要添新功能，需要改 model、dbHelper、view、service 等等，需要改動好幾個 package 下的代碼，改動的地方越多，越容易產生新問題，不是嗎？

#### package 有私有作用域（package-private scope）
你負責開發這塊功能，這個目錄下所有東西都是你的。
PBL 的方式是把所有工具方法都放在 util 包下，小張開發新功能時候發現需要一個 xxUtil，但它又不是通用的，那應該放在哪裡？沒辦法，按照分層原則，我們還得放在 util 包下，好像不太合適，但放在其它包更不合適，功能越來越多，util 類也越定義越多。後來小李負責開發一塊功能時發現需要一個 xxUtil，同樣不通用，去 util 包一看，怎麼已經有了，而且還沒法復用，只好放棄 xx 這個名字，改為 xxxUtil……，因為 PBL 的 package 沒有私有作用域，每一個包都是 public（跨包方法調用是很平常的事情，每一個包對其它包來說都是可訪問的）；如果是 PBF，小張的 xxUtil 自然放在 featureA 下，小李的 xxUtil 在 featureB 下，如果覺得 util 好像是通用的，就去 util 包看看要不要把工具方法添進 xxUtil, class 命名衝突沒有了。
PBF 的 package 有私有作用域，featureA 不應該訪問 featureB 下的任何東西（如果非訪問不可，那就說明接口定義有問題）。
PBF 的話 featureA 相關的所有東西都在 featureA 包，feature 內高內聚、高度模塊化，不同 feature 之間低耦合，相關的東西都放在一起，還好找。

#### 很容易删除功能
統計發現新功能沒人用，這個版本那塊功能得去掉。
如果是 PBL，得從功能入口到整個業務流程把受到牽連的所有能刪的代碼和 class 都揪出來刪掉，一不小心就完蛋。
如果是 PBF，好說，先刪掉對應包，再刪掉功能入口（刪掉包後入口肯定報錯了），完事。


#### 只通过 class 来分离逻辑代码
PBL 既分離 class 又分離 package，而 PBF 只通過 class 來分離邏輯代碼。
沒有必要通過 package 分離，因為 PBL 中也可能出現尷尬的情況：
├── service
├── MainService.java
**按照 PBL, service 包下的所有東西都是 Service，應該不需要 Service 後綴，但實際上通常為了方便，直接 import service 包，Service 後綴是為了避免引入的 class 和當前包下的 class 命名衝突，當然，不用後綴也可以，得寫清楚包路徑，比如 new com.domain.service.MainService()，麻煩；而 PBF 就很方便，無需 import，直接 new MainService() 即可。 **


### 


**google architecture sample**
*viewModel跟著view資料夾走，採用功能命名
![](https://i.imgur.com/AFM2FCh.png)


熊班 目前是 **view{} viewModel{} data{}** 三層資料夾
基本上ViewModel不會共用，會共用的是 Repository
![](https://i.imgur.com/2jCY0kR.png)

![](https://i.imgur.com/oguGa1Y.png)

依照介紹，資料應該放在model層才對
![](https://i.imgur.com/sMbQkbM.png)

***LiveData vs MutableLiveData**
![](https://i.imgur.com/oaobYIT.png)

![](https://i.imgur.com/807Wohx.png)
LiveData的postValue和setValue方法是protected，而MutableLiveData這兩個方法則是public，也就是說Livedata只允許調用observe方法被動監聽數據變化，而MutableLiveData除了監聽變化外，還可以用postValue和setValue方法發射數據
![](https://i.imgur.com/J72WKTu.png)



### 好習慣
* 為了消滅小黃標，有空白的block，可以加上備註，以讓其他人可以了解到用意

#### 多寫註解，enum放在外層， enum & interface如果有其他地方共用的話，再把他拉出來共用
 ![](https://i.imgur.com/MuloZuR.png)

 ![](https://i.imgur.com/WT3uotT.png)
 
#### 多使用throw excception
```
fun transform(color: String): Int =
    when (color) {
        "Red" -> 0
        "Green" -> 1
        "Blue" -> 2
        else -> 
            throw IllegalArgumentException("Invalid color")
}
```

![](https://i.imgur.com/E16tqsm.png)

![](https://i.imgur.com/RoIy4pn.png)

#### 關於迴圈
```
//過去這樣寫 index 不好取得
for (i=0 ; i<=9 ; i++){
    
}

for (i in 0..9) {
  // todo somethings
}

for (i in 0..9 step 3) {
  // todo somethings
}

//現在可以改成這樣

 (0..9).forEach{
    println("it:$it")
 }
 
 (0..9 step 3).forEach{
    println("it:$it")
 }
    
 (0 until 9 step 2).forEachIndexed{ index,value->
    println("\$index:\$value")
 }
```

#### 多個參數返回可以參考
```
val (a, b) = Pair(1, "x")
println(a) // 1
println(b) // x

val (a, b, c) = Triple(2, "x", listOf(null))
println(a) // 2
println(b) // x
println(c) // [null]
```

![](https://i.imgur.com/alDBhE6.png)

#### 類成員的順序
這並沒有唯一的正確解決方案，但如果都使用一致的順序將會提高代碼的可讀性，推薦使用如下排序：

1. 常量
2. 字段
3. 構造函數
4. 重寫函數和回調
5. 公有函數
6. 私有函數
7. 內部類或接口

```
public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private String mTitle;
    private TextView mTextViewTitle;

    @Override
    public void onCreate() {
        ...
    }

    public void setTitle(String title) {
    	mTitle = title;
    }

    private void setUpView() {
        ...
    }

    static class AnInnerClass {

    }
}
```

#### 函數參數的排序

在 Android 開發過程中，Context 在函數參數中是再常見不過的了，我們最好把 Context 作為其第一個參數。

正相反，我們把回調接口應該作為其最後一個參數。

例如：
```
// Context always goes first
public User loadUser(Context context, int userId);

// Callbacks always go last
public void loadUserAsync(Context context, int userId, UserCallback callback);
```

####  responseResult 除非一樣否則盡量避免共用


 0
 0
 0
 0
 



