策略模式和状态模式

一,状态模式和策略模式得区别

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 根据状态获取评分描述列表,需要改变,天你啊一个功能修改了修改了两个类,我觉得不太合适,下一遍文章我们用策略模式写一下,看能否实现 只修改一个类 就能实现添加一个功能

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。