版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxccxzzxz/article/details/79404405
背景描述
根据后台配置进行不同的广告加载策略,例如有广告 A / B / C,某个时段后台配置播放广告 C,默认播放 A;
普通的实现方式
- 创建广告管理类,实现广告加载/播放的控制:
class AdManager(adName: String) {
var ad = adName
fun initAd() {
when (ad) {
"A" -> initA()
"B" -> initB()
"C" -> initC()
}
}
fun playAd() {
when (ad) {
"A" -> initA()
"B" -> initB()
"C" -> initC()
}
}
fun stopAd() {"A"
when (ad) {
"A" -> initA()
"B" -> initB()
"C" -> initC()
}
}
private fun initA() {
print("init A")
}
// 代码省略...
private fun playA() {
print("play A")
}
// 代码省略...
private fun stopA() {
print("stop A")
}
// 代码省略...
}
- 使用方式:
class ConcreteAd {
fun main() {
var adManager = AdManager("A")
adManager.initAd()
adManager.playAd()
adManager.stopAd()
}
}
- 缺点:从上面看到,充斥着大量的if…else…(Kotlin 中用的 when 语法),并且耦合度很高,想要增加广告就要在同一个类中进行修改。
策略模式
那么使用策略模式来进行优化后,大致是这样的:
- 创建广告策略接口 IAdStrategy 类:
interface IAdStrategy {
abstract fun initAd()
abstract fun playAd()
abstract fun stopAd()
}
- 针对不同的广告进行策略的实现(下面以广告A为例):
class A : IAdStrategy {
override fun initAd() {
print("init A")
}
override fun playAd() {
print("play A")
}
override fun stopAd() {
print("stop A")
}
}
- 创建策略相关的Context来绑定广告和策略接口之间的关系:
class AdStrategyContext {
private lateinit var mAdStrategy: IAdStrategy
constructor(adStrategy: IAdStrategy) {
this.mAdStrategy = adStrategy
}
fun initAd() {
mAdStrategy.initAd()
}
fun playAd() {
mAdStrategy.playAd()
}
}
- 使用方式:
class ConcreteAd {
fun main() {
// 普通
var adManager = AdManager("A")
adManager.initAd()
adManager.playAd()
adManager.stopAd()
// 策略模式
var adCtx = AdStrategyContext(A())
adCtx.initAd()
adCtx.playAd()
adCtx.stopAd()
}
}
- 优点:上面可以看到,一旦需要增加广告D的话,去实现对应的 IAdStrategy 接口即可,和之前的代码没有耦合,符合设计原则。
- 缺点:如果广告很多的话,会存在很多类文件,并且一旦接口需要补充和修改,那么所有的实现类都会变动。