颜值10分姐姐带我玩转java设计模式(内附照片)- 状态模式

Posted 浦江之猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了颜值10分姐姐带我玩转java设计模式(内附照片)- 状态模式相关的知识,希望对你有一定的参考价值。

先不说话,直接来张姐姐照片,称呼上官姐姐即可,希望上官姐姐能带飞

原创不易,麻烦先三连,再细看,谢谢

示例的源码可以直接通过csdn下载也可以通过git导出:https://github.com/igdnss/java_state.git

设计模式共有23种,可以分为三大类:创建型模式,结构型模式,行为型模式。学好这三大类,基本可以闯荡整个武林了。
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、门面(外观)模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

本篇就有情上官姐姐带我们一起见识一下行为型模式中的状态模式。

前言

我:上官姐姐您好,好久不见了,您还是这么漂亮。
上官姐姐:心大,漂亮无处不在。
我:哈,那烦请姐姐用最漂亮的方式介绍一下状态模式。
上官姐姐:咦,这个模式我用的不是很多,怎么突然想起来让我介绍这个模式?
我:最近在写一个仓储管理系统(wms),在跟踪订单的状态时打算用状态模式来封装一下每个状态所对应的行为。
上官姐姐:嗯,你的应用场景使用的没问题,那我么就开始吧。
我:对了,姐姐,我之前使用过状态模式,发现状态模式和策略模式好像哦。
上官姐姐:对的,策略模式和状态模式从类图上看基本一样,但是它们的行为完全不一样。状态模式强调的是每一个状态对应不同的行为,而策略模式是每一个策略对应的行为都一样,只是实现方式不一样,最经典的策略例子就是商品打折,策略一打1折,策略二打2折,策略三打骨折,看,都是打折。而状态模式中,状态1:睡觉,状态2:上厕所。说的专业点就是状态模式中没有共同的抽象行为,而策略模式则不然
我:嗯,明白了,继续吧!

定义

我:介绍之前,能说一下状态模式是哪一类型的设计模式吗?
上官姐姐:状态模式是用来描述每一个状态下的行为,所以它属于行为模式的范畴。
我:哇,是的哦,好简单,那到底什么是状态模式。
上官姐姐:其实刚刚已经介绍过了,如果要给它一个定义,我认为是这样的:状态模式允许一个对象在其内部状态改变的时候改变其行为,给人的感觉就像是换了一个类在操作一样。其实人的感觉是错的,只是对象的状态改变了,它的行为改变了而已,对象还是那个对象。
我:还是有点点抽象,能给一个具体化的例子吗?
上官姐姐:比如说,上幼儿园的小朋友,他有三个状态:上课,午餐,运动。当它处于上课状态时,他的行为是:小手放放好,屁股坐坐好,眼睛看前面,闭上小嘴巴,认真听讲讲;当它处于午餐状态时,他的行为是:吃饭饭,不挑食,吃光光;当它处于运动状态时,他的行为是:爬高高,躲猫猫等等。整个过程一直都是这个小朋友,只是他的行为随着他的状态的变化而变化。可以通过类图来看一下。

在这里插入图片描述

我:哈哈,好形象的例子。那么烦请姐姐再介绍一下它的应用场景吧

使用场景

上官姐姐:可以设想一下上面幼儿园小朋友,如果用java代码去实现是不是要用if分支或者switch去实现。
我:对啊,很简单的逻辑。
上官姐姐:那如果又加了一个状态呢,比方说午休。
我:那就在if下面再加一个else不就行了吗。
上官姐姐:你觉得这样合理吗,你一个类都写好了,然后又去修改它,这难道没有违背软件开发中的开闭原则吗?
我:对哦,我怎么把这给忘了,那应该怎么弄?
上官姐姐:所以这就是状态模式的使用场景了。当操作中含有庞大的多分支条件语句时,且这些分支依赖于此对象的状态,就应该使用状态模式。其实我觉得啊,状态模式的出现就是为了克服if多分支,代码可读性与维护性的问题。
我:嗯嗯,那这里的状态使用枚举常量可以吗。
上官姐姐:不错,通常情况下这个状态就是使用枚举来定义的。另外,这里再补充一下,使用状态模式一定要满足一个对象的行为取决于它的状态,并且必须在运行时刻根据状态改变它的行为。
我:Nice, 使用场景基本没问题了,姐姐可不可以用代码实现一下小朋友的例子。
上官姐姐:没问题,这里为了衬托出状态模式的优势,我会用两种方式来实现,示例1不使用状态模式,示例2使用状态模式。

示例1:非状态模式实现

/**
 *使用枚举定义状态
 */
public enum KinderState {
	ATTENDSTATE,
	LUNCHSTATE,
	SPORTSTATE;
}
/**
 *通过if分支去处理每种状态的业务逻辑
 */
public class KinderStateContext {
	KinderState state;

	public KinderStateContext(KinderState state) {
		super();
		this.state = state;
	}
	public void switchKinderState() {
		if(state == KinderState.ATTENDSTATE) {
			System.out.println("小手放放好,屁股坐坐好,眼睛看前面,闭上小嘴巴,认真听讲讲");
		}else if(state == KinderState.LUNCHSTATE) {
			System.out.println("吃饭饭,不挑食,吃光光");
		}else if (state == KinderState.SPORTSTATE) {
			System.out.println("爬高高,躲猫猫");
		}else {
			System.out.println("do nothing");
		}
	}
	
}
/**
 *测试
 */
public class Client {
	public static void main(String[] args) {
		//这里可以切换状态
		KinderStateContext kinderStateContext = new KinderStateContext(KinderState.ATTENDSTATE);
		kinderStateContext.switchKinderState();
	}
}

示例2:状态模式实现

/**
 *定义一个状态接口
 */
public interface KinderState {
	void kinderService();
}
/**
 *通过状态模式去处理每种状态的业务逻辑
 */
public class KinderStateContext {
	KinderState kinderState;
	public KinderStateContext(KinderState kinderState) {
		this.kinderState = kinderState;
	}
	
	public void switchKinderState(){
		kinderState.kinderService();
	}
}

/**
 * 上课状态业务逻辑
 *
 */
public class AttendState implements KinderState {

	@Override
	public void kinderService() {
		System.out.println("小手放放好,屁股坐坐好,眼睛看前面,闭上小嘴巴,认真听讲讲");
	}

}

/**
 * 午餐状态业务逻辑
 *
 */
public class LunchState implements KinderState {

	@Override
	public void kinderService() {
		System.out.println("吃饭饭,不挑食,吃光光");
	}

}

/**
 *运动状态业务逻辑
 */
public class SportState implements KinderState {

	@Override
	public void kinderService() {
		System.out.println("爬高高,躲猫猫");
	}

}

/**
 *测试
 */
public class Client {
	public static void main(String[] args) {
		//这里可以切换状态
		KinderStateContext kinderStateContext = new KinderStateContext(new AttendState());
		kinderStateContext.switchKinderState();
	}
}

我:代码看懂了,示例1使用了多重if,示例2充分使用了java动态。
上官姐姐:是的,两者的扩展性完全不一样。示例1如果想增加一个午休状态,需要修改KinderState,KinderStateContext, 而示例2只需要添加一个实现类。这里的修改添加有着本质上的区别,添加不会影响其他的代码,而修改可能会牵一发而动全身,这就是所谓的开闭原则
我:原来是这样,但是示例2需要创建好多业务类啊。
上官姐姐:怎么说呢,这或者就是状态模式的一个缺点吧,但这个缺点完全小于其优点,可以忽略的。
我:嗯,懂了懂了,好开心,又学会了一个设计模式

结束语

上官姐姐:懂了就好,关于状态模式就介绍完了,很简单,很实用。希望本文能帮助大家,上官姐姐在此祝大家在IT之路上少走弯路,一路绿灯不堵车,测试一性通过,bug秒解!
我:感谢上官姐姐的细心讲解,很精彩,期待下一个设计模式,也祝上官姐姐越长越漂亮。

以上是关于颜值10分姐姐带我玩转java设计模式(内附照片)- 状态模式的主要内容,如果未能解决你的问题,请参考以下文章

姐姐带我玩转java设计模式(内附照片)- 代理模式

照片颜值测试工具- 自拍测颜值

我用Python爬取了女神视界,爬虫之路永无止境「内附源码」

曾贤志Excel答疑课-我玩转Excel有哪些诀窍?

国庆在家太无聊, 用Java爬了上千张小姐姐照片...

国庆在家太无聊, 用Java爬了上千张小姐姐照片...