---
# System prepended metadata

title: 4/13 (三)

---

# 4/13 (三)


:::warning
- Next: 分享 web player 專案的現況
- Kotlin 的 error handling 
- JS 的 error handling
- ~~MVC~~
- MVP
- MVVM (android 教學)
- @Ralf & @Isaac 教學 `*` `&` (C++)
- @Ralf 說要研究 js 的 null & undefined & ??
- 版號使用
- ~~git branch 的使用~~
:::


### git branch 的使用

- iOS 會習慣在 feature branch 之外再開 implement feature branch，然後開 MR 合回去 feature branch
- Android 說這樣很好，也想要跟進


### iOS MVVM 

- 當我們在講 MVC, MVP, MVVM 等這類的軟體架構，都是在講 不同的責任角色

```swift=
class Model {
    
    var updateCallback: ((Model) -> Void)?
    
    var bufferRange: Int = 0 {
        didSet {
            updateCallback?(self)
        }
    }
    
    func loadBuffer() {
        
    }
    
    func binding(_ updateCallback: (Model) -> Void) {
        
    }
}

class BobViewController: UIViewController {
    
    var model = Model()
    var playerView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // view setup
        playerView.backgroundColor = .red
        
        // model initial setup
        model.loadBuffer()
        
        model.binding() { newModel in
            // playerView.updateUI(newModel.bufferRange)
            
            DispatchQueue.mian.async {
                // 更新 UI
            }
            
        }
    }
}
```



### android 軟體架構

你們就是 MVP 

View <-> Presenter <-> Model


## MVC (android)
### View
- 他會是個 XML
```
    <Layout>
        <TextView>
            android:id = "+id/tv_name"
        </TextView>
    </Layout>
```
### Controller
```kotlin=
class MainActivity : Activity, View.OnClickListener {
    
    var model: MainModel? = null
    val tvName: TextView? = null
    
    interface ModelCallback {
        fun fetched(data: FetchedData)
    }
    val modelCallback = object : ModelCallback {
        override fun fetched(data) {
            runOnUIThread {
                tvName.text = data.name
            }
        }
    }
    
    override fun onCreate() {
        setContentView(R.layout.xxxx.xml)
        
        // setOnClickEvent register
        tvName = findViewById(R.id.tv_name)
        tvName.setOnClickListener(this)
    }
    
    override fun onStart() {
        model = MainModel(modelCallback)
    }
    
    override fun onClick(view: View) {
        if (view.id == R.id.tv_name) {
            model.saveName()
        }
    }
}
```


## background thread / main thread
```kotlin=
val ioScope = CoroutineScope(Dispatcher.IO + Job())
ioScope.lanch {
    // post API ....
}
```

## process

- Chrome 的每個分頁都會是一個 process