觀察者模式
簡(jiǎn)介:一個(gè)對(duì)象狀態(tài)改變時(shí)通知其他對(duì)象。
背景
現(xiàn)在Jack的水果店的某種水果賣的很好,現(xiàn)在已經(jīng)短缺,但是已經(jīng)有很多客戶訂購(gòu)了該水果,所以需要水果到店時(shí)通知這些客戶。
設(shè)計(jì)實(shí)現(xiàn)

image.png
代碼實(shí)例
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
interface Observer {
fun update()
}
class CustomerObserver(val name:String):Observer {
override fun update() {
println("${name}購(gòu)買成功")
}
}
abstract class Attention {
//關(guān)注客戶列表
var observers:MutableList<Observer> = ArrayList()
//關(guān)注客戶
fun add(observer: Observer){
observers.add(observer)
}
//取消關(guān)注
fun remove(observer: Observer){
observers.remove(observer)
}
//發(fā)送通知
abstract fun notifyObservers()
}
class MangoAttention:Attention() {
override fun notifyObservers() {
//遍歷觀察者集合,調(diào)用每一個(gè)客戶的購(gòu)買方法
for (obs in observers){
obs.update()
}
}
fun perform(){
notifyObservers()
}
}
測(cè)試
class ObserverClient {
companion object{
@JvmStatic
fun main(args: Array<String>) {
val attention = MangoAttention()
attention.apply {
this.add(CustomerObserver("joker"))
this.add(CustomerObserver("rose"))
this.add(CustomerObserver("jetty"))
this.add(CustomerObserver("mark"))
}
attention.perform()
}
}
}
測(cè)試結(jié)果

image.png
應(yīng)用場(chǎng)景
1、當(dāng)一個(gè)對(duì)象的改變需要通知其他對(duì)象改變時(shí),而且它不知道具體有多少個(gè)對(duì)象有待改變時(shí)。
2、當(dāng)一個(gè)對(duì)象必須通知其他對(duì)象,而它又不能假定其他對(duì)象是誰(shuí)。
3、跨系統(tǒng)的信息交換場(chǎng)景,如信息隊(duì)列、事件總線的處理機(jī)制。
在Android中的應(yīng)用:Android中的許多控鍵都能設(shè)置監(jiān)聽(tīng)者,其機(jī)制就是觀察者模式。
優(yōu)點(diǎn)
- 解除觀察者與主題之間的耦合。讓耦合的雙方都依賴于抽象,而不是依賴具體。從而使得各自的變化都不會(huì)影響另一邊的變化。
- 易于擴(kuò)展,對(duì)同一主題新增觀察者時(shí)無(wú)需修原有代碼。
缺點(diǎn)
- 依賴關(guān)系并未完全解除,抽象主題仍然依賴抽象觀察者。
- 使用觀察者模式時(shí)需要考慮一下開(kāi)發(fā)效率和運(yùn)行效率的問(wèn)題,程序中包括一個(gè)被觀察者、多個(gè)觀察者,開(kāi)發(fā)、調(diào)試等內(nèi)容會(huì)比較復(fù)雜。
- 可能會(huì)引起多余的數(shù)據(jù)通知。