策略模式
一般在实现某个功能有多种方法的场景,这些方法都能完整实现该功能,但不同方法间又各有优劣,希望能通过简单的设置便能在不同方法间切换;比如项目中使用Glide来实现图片加载,现在希望用Fresco来加载,如果每个地方去修改任务将变的繁重,策略模式便能很好地解决这类问题,属对象行为型模式,其缺点在于使用方需清楚不同策略的不同来决定使用何种策略。
类图
## 实现
定义各策略间共有的方法
interface ImgLoadStrategy {
fun loadImg(url:String)
}
实现具体策略
class GlideLoadStrategy : ImgLoadStrategy {
//使用Glide加载策略
override fun loadImg(url: String) {
TODO("Not yet implemented")
}
}
封装实现,用策略决定实现类
class LoadImgUtil(private var strategy:ImgLoadStrategy){
public fun loadingImg(url:String){
strategy.loadImg(url);
}
}
这样根据传入的策略,加载工具类会调用对应的对象实现行为,这点与工厂模式创建对象类似,但工厂模式的目的是创建对象,策略是执行行为,只在初始化是决定执行对象,执行行为时屏蔽执行者,且策略模式可以中途改变策略,来执行不同的行为
调用
public fun initStrategy(){
val imgLoad:LoadImgUtil= LoadImgUtil(GlideLoadStrategy());
imgLoad.loadingImg("");
imgLoad.setStrategy(FrescoLoadStrategy());
imgLoad.loadingImg("")
}
状态模式
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。一般状态模式来修饰对象在不同状态执行某一固定操作行为或结果不同,类似ifelse的判断,只是状态模式将这些判断转移到状态子类中省去了if的判断,在抽象类中抽象出状态相关的行为
类图
其类图结构与策略模式类似,不同的是策略模式分类的是不同的实现方案,每个方案都是完整的个体,而状态模式分类的是对象的状态,将状态具象化一个个的类,且每个状态间有一定的联系
实现
抽象行为
interface AbstraState {
var stateName:String //状态名
//状态变化可能的操作
fun stopPlay(play: MyMediaPlay)
fun playIngPlay(play: MyMediaPlay)
}
子类根据状态处理行为
class PlayingState :AbstraState {
override var stateName: String
get() = “PlayingState”
set(value) {}
override fun stopPlay(play: MyMediaPlay) {
TODO("Not yet implemented")
play.setState(StopState())//实现状态的切换
}
override fun playIngPlay(play: MyMediaPlay) {
//show("当前已是播放状态")
}
}
对象主体持有状态
class MyMediaPlay {
//假设这是一个具有播放功能的播放类
//使用状态模式对播放状态进行管理(init,playing,stop,destroy)
private var state:AbstraState=InItState();
public fun setState(state:AbstraState){
this.state=state
}
public fun stopPlay(){
//do stop Action
state.stopPlay(this)
}
fun startPlay(){
state.playIngPlay(this)
}
}
命令模式
命令模式分离了调用者与实现者,类似于遥控板的功能(有遥控板后我就不需要直接在电视上操作,而是通过遥控器发出命令),使得上层感知不到具体的实现者,一般某项需求具有命令语义,且不同命令对应不同实现时,考虑使用命令模式
类图
该模式结构通过抽象实现类,提取共用方法,抽象类的实现类都是命令的执行者,调用者传入实例化的命令执行抽象的方法,这样可以不用感知具体的实现,前提是调用者知道有这些命令的存在,拿上图举例,与策略模式相比多了个Invoker类(调用者),相当于是对策略的封装,同时通过调用者可以知道上次使用的命令