一,状态模式和策略模式得区别
1,状态模式和策略在代码写法上非常类似,而且UML图也是非常类似,甚至通用,但是在需求方面和差别挺大的
2,策略模式: 在不同的行为下使用不同的算法,或者是不同的需求随时改变的他的行为
3, 状态模式 :是根据当前用的状态,执行不同的算法,根据不同的状态改变他们的行为
对于我来讲,两种方式差不多,而且不同场景下 使用不同行为,比如,我家有炒菜锅,煮粥锅,蒸米锅,就是我做不同的饭,我用相应的锅,比如,我又买来一个砂锅,用来做米线,当做米线的时候,我会选择砂锅,这种我会选择策略模式,不同情况使用不同东西。
比如,我当前是一个电锅设计师,这个锅可以煮粥,蒸米,热饭,等功能,当用户点击那个按钮我就做什么,这种方式我选择用状态模式,因为我不想让用户知道我怎么实现的,或者里面的所有操作步骤完全对他屏蔽,他只需要点击按钮就够了!所以这种方式我选择用状态模式
二,UML图查看
image.png三,业务场景分析
根据不同病人的病情进行评分,有胸痛,创伤,卒中,每个评分里面有三种或者四种评分项,每一种评分项可能在其他评分能用到
每种评分项有几个功能1,查询评分2,更新评分3,获取当前评分值获取当前评分等级
每一种评分就有一个功能, 就是获取当前评分项的
目前我采用状态模式,因为我们评分项 不仅仅我们这边用得到,可能后台评分用的到,而且以后的三大中心也用得到,我觉得不一定是一个人写的,也可能对外开放,所以 根据不同状态加载不同的数据比较好
代码实现和原理
1,先创建一个接口 每个评分项都实现这个接口
interface IScoreState {
fun loadScoreList(scoreId: String): List<String>
fun updateScore(mList: List<String>, scoreId: String)
fun getScoreDesc(scoreId: String): String
fun getScoreKey(): String
}
loadScoreList 方法是从数据库加载数据
updateScore 方法是把数据更新到数据库
getScoreDesc 根据当前评分获取等级描述
getScoreKey 因为这个类我们可能多次用到,我想方法集合里面,当创建后,可以复用,也是享元模式 ,能够 获取这个类的一个表示
2,创建Fast,Gcs评分,NIhss评分,TI评分实现类,并继承IScoreState
//Fast
class FastScoreState : IScoreState {
override fun loadScoreList(scoreId: String): List<String> {
println("Fast评分内容获取评分")
return mutableListOf("1", "2", "3")
}
override fun updateScore(mList: List<String>, scoreId: String) {
println("Fast评分内容更新评分")
}
override fun getScoreDesc(scoreId: String): String {
return "病情严重"
}
override fun getScoreKey(): String {
return "Fast"
}
}
//Gcs
class GcsScoreState : IScoreState {
override fun loadScoreList(scoreId: String): List<String> {
println("Gcs评分内容获取评分")
return mutableListOf("1", "2", "3")
}
override fun updateScore(mList: List<String>, scoreId: String) {
println("Gcs评分内容更新评分")
}
override fun getScoreDesc(scoreId: String): String {
return "病情严重"
}
override fun getScoreKey(): String {
return "Gcs"
}
}
//NIhss评分
class NIhssScoreState : IScoreState {
override fun loadScoreList(scoreId: String): List<String> {
println("NIhss评分内容获取评分")
return mutableListOf("1", "2", "3")
}
override fun updateScore(mList: List<String>, scoreId: String) {
println("NIhss评分内容更新评分")
}
override fun getScoreDesc(scoreId: String): String {
return "病情严重"
}
override fun getScoreKey(): String {
return "Nihss"
}
}
//Ti评分
class TIScoreState : IScoreState {
override fun loadScoreList(scoreId: String): List<String> {
println("Fast评分内容获取评分")
return mutableListOf("1", "2", "3")
}
override fun updateScore(mList: List<String>, scoreId: String) {
println("Fast评分内容更新评分")
}
override fun getScoreDesc(scoreId: String): String {
return "病情严重"
}
override fun getScoreKey(): String {
return "TI"
}
}
3,因为我们上面说到类的重复使用,减少对象创建 下面我们利用集合进行保存我们的对象
object ScoreFlyweight {
private val flyweights: HashMap<String, IScoreState> = HashMap()
fun getIScoreState(key: String): IScoreState {
val iScoreService = flyweights[key]
if (iScoreService != null) {
return iScoreService
} else {
val fastScoreService = FastScoreState()
val gcsScoreService = GcsScoreState()
val nIhssScoreService = NIhssScoreState()
val tiScoreService = TIScoreState()
flyweights[fastScoreService.getScoreKey()] = fastScoreService
flyweights[gcsScoreService.getScoreKey()] = gcsScoreService
flyweights[nIhssScoreService.getScoreKey()] = nIhssScoreService
flyweights[tiScoreService.getScoreKey()] = tiScoreService
return getIScoreState(key)
}
}
}
4,因为我们每个评分下面包括多个评分,就是要获取好几个评分项的描述,所以就是调用IScoreState 好几个实现类的描述,因为是固定死的,如果我们单独调用,这样弄得很乱,所以我们封装一遍
object FacadePattern {
/**
* 获取卒中评分Service
*/
fun getCZScore(scoreId: String): List<String> {
val fastScoreService = ScoreFlyweight.getIScoreState("Fast")
val gcsScoreService = ScoreFlyweight.getIScoreState("Gcs")
val nIhssScoreService = ScoreFlyweight.getIScoreState("Nihss")
return mutableListOf(
fastScoreService.getScoreDesc(scoreId),
gcsScoreService.getScoreDesc(scoreId),
nIhssScoreService.getScoreDesc(scoreId)
)
}
/**
* 获取创伤评分Service
*/
fun getCSScore(scoreId: String): List<String> {
val tiScoreService = ScoreFlyweight.getIScoreState("Ti")
val gcsScoreService = ScoreFlyweight.getIScoreState("Gcs")
return mutableListOf(
tiScoreService.getScoreDesc(scoreId),
gcsScoreService.getScoreDesc(scoreId)
)
}
}
5,一切都准备好了,那就在写个控制创建类
object ScoreController {
fun getScoreService(stateKey: String): IScoreState {
return ScoreFlyweight.getIScoreState(stateKey)
}
fun getScoreContent(state: Int, scoreId: String): List<String> {
when (state) {
1 -> return FacadePattern.getCSScore(scoreId)
2 -> return FacadePattern.getCZScore(scoreId)
}
return FacadePattern.getCSScore(scoreId)
}
}
6,封装就是为了维护和方便,那我们看看怎么使用
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val scoreService = ScoreController.getScoreService("Fast")
scoreService.loadScoreList(scoreId = "123")
scoreService.updateScore(listOf(),"123")
val scoreContent = ScoreController.getScoreContent(1, "123")
}
}
7,上面说了封装为了维护,和方便,那么我们新增一个胸痛评分那么方面吗
1,我们创建胸痛分评分项实现IScoreState 这个很简单,对原来代码没有改变,然后对FacadePattern 添加胸痛分评分项,ScoreController 根据状态获取评分描述列表,需要改变,天你啊一个功能修改了修改了两个类,我觉得不太合适,下一遍文章我们用策略模式写一下,看能否实现 只修改一个类 就能实现添加一个功能
网友评论