# 设计模式


### 设计模式

| 范围 |                            创建型                            |                            结构型                            |                            行为型                            |
| :--: | :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: |
| 对象 | Factory Method (工厂方法)<br />Abstract Factory (抽象工厂)<br/>`Builder` (建造者)<br/>Prototype (原型)<br />`Singleton` (单例) | `Adapter` (适配器)<br />Bridge (桥接)<br />Composite (组合)<br />Decorator (装饰者)<br />Facade (外观)<br />Flyweight (享元)<br />`Proxy` (代理) | Interpreter (解释器)<br />`Template Method` (模板方法)<br />Chain of Responsibility (职责链)<br/>Command (命令)<br/>lterator (迭代器)<br />Mediator (中介者)<br />Memento (备忘录)<br />`Observer` (观察者)<br/>State (状体)<br />Strategy (策略)<br />Visitor (访问者) |

高亮的是 Android 开发(我)常用的.

1. **Factory Method** 工厂方法: 用于生产类  
   如: ThreadFactory, BitmapFactory...

2. **Builder** 建造者: 当构造一个对象需要很多参数的时候，并且参数的个数或类型不固定的时候用到  
   如: AlertDialog、Glide、OkHttp...

3. **Adapter** 适配器: 用于将一种类或一种接口转换成另一种类或者接口  
   如: RecyclerView.Adapter...

4. **Decorator** 装饰者: 动态的给一个对象增加或删除功能  
   如: 在四大组件中, 他们都继承自`Context`父类, `Context`类在这里充当了抽象组件，`ContextImpl`类则是具体的组件，而`ContextWrapper`就是具体的装饰角色，通过扩展`ContextWrapper`增加不同的功能，就形成了`Activity`、`Service`...
   
   再如: BufferedReader BufferedWriter...
   
5. **Composite** 组合: 把一组比较相似的对象当做一样的对象处理, 然后提供统一方法去访问这些对象  
   如: View ViewGroup

6. **Template Method** 模板方法: 定义一个骨架，而将步骤延迟到子类  
   如: Activity和Fragment生命周期、AsyncTask

7. **Observer** 观察者模式: 定义对象间的一对多依赖关系，每当一个对象状态发生改变时，其相关依赖对象得到通知并被自动更新  
   如: RxJava, EventBus, LiveData

8. **Proxy** 代理模式: 类的某个属性值不是在类中直接进行定义，而是将其托付给一个代理类，从而实现对该类的属性统一管理  

   如: kotlin `by` 关键字

#### 单例模式

>  事实上, 在 kotlin  中你只需要使用 lazy 罢了

##### 懒汉模式

- 调用时进行实例化

```kotlin
class LazyCreate {
    companion object {
        private var INSTANCE: LazyCreate? = null
        fun getInstance(): LazyCreate {
            return if (INSTANCE == null) LazyCreate()
            else INSTANCE!!
        }
    }
}
```

- 如何做多线程安全? 使用双检查锁，避免过度同步导致的性能开销

```kotlin
class LazyCreate {
    companion object {
        private var INSTANCE: LazyCreate? = null
        fun getInstance(): LazyCreate {
            if (INSTANCE == null) synchronized(this) {
                if (INSTANCE == null) INSTANCE = LazyCreate()
            }
            return INSTANCE!!
        }
    }
}
```

- 上面其实还不够好, 我们可以利用 jvm 自身的制度保证懒加载

```kotlin
class LazyCreate {
    object Factory {
        val INSTANCE: LazyCreate = LazyCreate()
    }

    companion object {
        fun getInstance() = Factory.INSTANCE
    }
}
```

##### 饿汉模式

- 提前实例化, 无懒加载

```kotlin
class LazyCreate {
    companion object {
        private var INSTANCE: LazyCreate = LazyCreate()
        fun getInstance() = INSTANCE
    }
}
```

##### 常用用途

Application 全局 context, EventBus...

#### 六大原则

**1、开闭原则（Open Close Principle）**

对扩展开放，对修改关闭  
*在程序需要进行拓展时，不去修改原有的代码，实现一个热插拔的效果。我们需要使用接口和抽象类*

**2、里氏代换原则（Liskov Substitution Principle）**

任何基类可以出现的地方，子类一定可以出现

**3、依赖反转原则（Dependence Inversion Principle）**

面向接口编程，依赖于抽象而不依赖于具体。

**4、接口隔离原则（Interface Segregation Principle）**

使用多个隔离的接口, 比使用单个接口要好, 降低依赖，降低耦合。

**5、迪米特法则（最少知道原则）（Demeter Principle）**

一个实体应当尽量少的与其他实体之间发生相互作用，使得系统功能模块相对独立。

**6、合成复用原则（Composite Reuse Principle）**

尽量使用合成/聚合的方式，而不是使用继承。
