android listener 模式,Android设计模式(三) 观察者模式

Android开发中的基于观察者模式实现的设计还是很多的,比如rxjava、LiveData...常见的按钮点击事件

Button ---> 被观察者

OnClickListener ---> 观察者

setOnClickListener() ---> 订阅

OnClick() ---> 事件

观察者模式定义可一对多的依赖关系,让多个观察者同时监听某一个对象,当这个主体对象在状态上发生变化时,会通知所有观察者对象 ,使他们能自动更新自己,叫法也有很多,发布-订阅(Publish-Subscribe)、模型-视图(Model-View)等等

Java对于观察者模式在java.util包中提供了Observer接口和Observable抽象类。注册,删除,通知观察者等功能已内置。kotlin同样支持使用Java中提供的观察者模式

例如电商项目中的动态更新价格

// 被观察者

class PriceSubject : Observable() {

// 定义一组观察者对象

private val observers = mutableSetOf()

// 订阅

fun subject(ob: Observer) {

observers.add(ob)

}

// 解除订阅

fun UnSubject(ob: Observer) {

observers.remove(ob)

}

// 价格赋值

fun setPrice(price:Int ){

notify(price)

}

//更新数据

private fun notify(msg: T) {

for (ob in observers) {

ob.update(this,msg)

}

}

}

// 观察者

class PriceOb(private val channel:String):Observer{

override fun update(o: Observable?, price: Any?) {

if (o is PriceSubject){

print("接收赋值-观察者:$channel - 价格:$price\n")

}

}

}

class PriceOb1 :Observer by PriceOb("第三方")

fun main(args: Array) {

PriceSubject().apply {

// 订阅

subject(PriceOb("自营"))

subject(PriceOb1())

setPrice(100)

}

}

接收赋值-观察者:自营 - 价格:100

接收赋值-观察者:第三方 - 价格:100

委托属性

kotlin中的委托属性官方文档

其中我们需要的是

可观察属性(observable properties): 监听器会收到有关此属性变更的通知

inline fun observable(

initialValue: T,

crossinline onChange: (property: KProperty, oldValue: T, newValue: T) -> Unit

): ReadWriteProperty

若是我们赋予价格属性更多定义,我们需要发布者对外提供一个API接口而不是在实现Observer接口的类中区分不同的逻辑。

Delegates.observable()中提供了代表委托属性三个参数:元数据property: KProperty对象,新旧值。

// 观察者

interface PriceChangedListener {

// 定义一系列事件

//

fun onNormalPrice(price: Price)

// 秒杀价

fun onSpikePrice(price: Price)

// 预购价

fun onAdvancePrice(price: Price)

// 会员价

fun onVIPPrice(price: Price)

//

}

class PriceObserver : PriceChangedListener {

override fun onNormalPrice(price: Price) {

print("常规价${price.newPrice}")

}

override fun onSpikePrice(price: Price) {

print("秒杀价${price.newPrice}")

}

override fun onAdvancePrice(price: Price) {

print("预购价${price.newPrice}")

}

override fun onVIPPrice(price: Price) {

print("会员价${price.newPrice}")

}

}

data class Price(val newPrice: Int, //新价格

val oldPrice: Int, //旧价格

val type: Int, //价格属性类型

val discount: Boolean //是否能抵用折扣

)

// 被观察者

class PriceSubject {

// 观察者对象

private var listeners = mutableSetOf()

fun subject(ob: PriceChangedListener) {

listeners.add(ob)

}

fun unSubject(ob: PriceChangedListener) {

listeners.remove(ob)

}

var price: Price by Delegates.observable(Price(0, 0, 0, false)) { property, oldValue, newValue ->

listeners.forEach {

when (newValue.type) {

0 -> it.onNormalPrice(newValue)

1 -> it.onSpikePrice(newValue)

2 -> it.onAdvancePrice(newValue)

3 -> it.onVIPPrice(newValue)

}

}

}

}

fun main(args: Array) {

PriceSubject().apply {

subject(PriceObserver())

price = Price(199, 0, 0, false)

price = Price(99, 100, 3, false)

}

}

Vetoable

inline fun vetoable(

initialValue: T,

crossinline onChange: (property: KProperty, oldValue: T, newValue: T) -> Boolean

): ReadWriteProperty

在观察者模式中,如果我们不想被观察的值被任意的修改,可以利用Vetoable在新的值被赋值生效之前进行截获,然后根据相关业务逻辑处理它。

var price: Price by Delegates.vetoable(Price(0, 0, 0, false)) { property, oldValue, newValue ->

listeners.forEach {

when (newValue.type) {

0 -> it.onNormalPrice(newValue)

1 -> it.onSpikePrice(newValue)

2 -> it.onAdvancePrice(newValue)

3 -> it.onVIPPrice(newValue)

}

}

// 添加自定义规则

if (newValue.type==3&&newValue.oldPrice < newValue.newPrice)

true else throw IllegalArgumentException("会员价格不合理")

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值