走穿java23种设计模式–22状态模式详解
状态模式又称为状态对象模式,该模式允许一个对象在其内部状态改变的时候改变行为。
一.状态模式的现实场景
现在电视上广告比电视剧的时间还长,很多人对此感到很无奈,只能傻傻地等待。而习大看电视从来不看广告,他是怎么做到的呢?原来,他是先挑出他喜欢的电视台,然后以其中一个为主,如果出现了广告就换台去看另一个电视台的节目,如果另一个电视台也有广告就看第三个电视台的节目。。。。。。这样的话他几乎就不用看广告了,而且他还能看到更多自己喜欢的节目。
在上面的这个场景中,习大看电视节目的时候经常换台,这其实是通过改变电视机的内部状态来达到不看广告,看不同的电视节目的效果,这类似于设计模式中的状态模式。
二.状态者模式(State Pattern)的定义
允许一个对象内在状态改变时改变行为,使得这个对象看起来像改变了类型。
状态改变的封装,状态的变更引起行为的变更,从外部看来就好像该对象对应的类发生改变一样。
三.状态模式的类图
四.状态模式的三个角色
1.抽象状态(State)角色
该角色用封装环境对象的一个特定的状态对应的行为。
2.具体状态(Concrete State)角色
该角色实现环境的某一个状态所对应的行为。
3.环境(Context)角色
该角色定义客户端需要的接口。并负责具体状态的切换。它会保留一个具体状态类的实例,该实例给出环境对象的现有状态。
五.状态模式的优缺点
状态模式中的优点
1.结构清晰
2.遵循设计原则
3.封装性非常好
状态模式的缺点
1.子类太多,不易管理
六.状态模式的使用场景
1.对象的行为依赖于他所在的状态,即行为随状态改变而改变的场景。
2.对象在某个方法中依赖于一重或多重条件分支语句,
此时可以使用状态模式将每一个分支语句都包装到一个单独的类中,使得这些条件分支语句能够以类的方式独立存在和演化,如此,维护这些独立的类就不会影响到系统的其他部分。
七.状态模式的示例
这里使用上面的现实场景做代码示例。
示例的类图
示例的代码
###1.抽象状态:频道Channel
package p22_state;
/**
* 抽象状态:频道
*/
public interface Channel {
//播放频道中的节目
void display();
}
###2.具体状态:CCTV1
package p22_state;
/**
* 具体状态角色CCTV1
*/
public class CCTV1 implements Channel {
@Override
public void display() {
System.out.println("CCTV1 新闻联播");
}
}
###3.具体状态:CCTV2
package p22_state;
/**
* 具体状态角色CCTV2
*/
public class CCTV2 implements Channel {
@Override
public void display() {
System.out.println("CCTV2 财经半小时");
}
}
###4.具体状态:CCTV3
package p22_state;
/**
* 具体状态角色CCTV3
*/
public class CCTV3 implements Channel {
@Override
public void display() {
System.out.println("CCTV3 星光大道");
}
}
###5.环境角色:电视机TV
package p22_state;
/**
* 环境角色:电视机TV
*/
public class TV {
//电视机可以看的频道(状态)
private Channel CCTV1 = new CCTV1();
private Channel CCTV2 = new CCTV2();
private Channel CCTV3 = new CCTV3();
//当前频道
private Channel channel;
//设置频道
public void setChannel(Channel channel) {
this.channel = channel;
}
//播放CCTV1频道
public void disCCTV1() {
setChannel(CCTV1);
channel.display();;
}
//播放CCTV2频道
public void disCCTV2() {
setChannel(CCTV2);
channel.display();;
}
//播放CCTV3频道
public void disCCTV3() {
setChannel(CCTV3);
channel.display();;
}
}
###6.测试类:TVDemo
package p22_state;
/**
* Created by wenzhi on 2018/5/8.
*/
public class TVDemo {
public static void main(String[] arg){
TV tv=new TV();
//看CCTV3
tv.disCCTV3();
System.out.println("进入广告时间,换台");
tv.disCCTV2();
System.out.println("进入广告时间,换台");
tv.disCCTV1();
System.out.println("估计CCTV3的广告已经播放完,换台");
tv.disCCTV3();
}
}
程序运行结果;
状态模式模式就为大家介绍到这里。
大家如果对其他设计模式有兴趣可以看看我之前的博客:
21访问者模式:https://blog.csdn.net/wenzhi20102321/article/details/80546326
20备忘录模式:https://blog.csdn.net/wenzhi20102321/article/details/80468151
19观察者模式:https://blog.csdn.net/wenzhi20102321/article/details/80330335
18中介者模式:https://blog.csdn.net/wenzhi20102321/article/details/79394668
17迭代器模式:http://blog.csdn.net/wenzhi20102321/article/details/79343423
16策略模式:http://blog.csdn.net/wenzhi20102321/article/details/79336521
15责任链模式:http://blog.csdn.net/wenzhi20102321/article/details/79333899
14命令模式:http://blog.csdn.net/wenzhi20102321/article/details/79323404
13模板方法模式:http://blog.csdn.net/wenzhi20102321/article/details/79284870
12享元模式:http://blog.csdn.net/wenzhi20102321/article/details/78724677
11外观模式:http://blog.csdn.net/wenzhi20102321/article/details/78639087
10桥梁模式:http://blog.csdn.net/wenzhi20102321/article/details/78566532
9组合模式:http://blog.csdn.net/wenzhi20102321/article/details/78463190
8适配器模式:http://blog.csdn.net/wenzhi20102321/article/details/78389326
7装饰模式:http://blog.csdn.net/wenzhi20102321/article/details/78336273
6代理模式:http://blog.csdn.net/wenzhi20102321/article/details/78209493
创建型模式详解:http://blog.csdn.net/wenzhi20102321/article/details/78175558
5原型模式:http://blog.csdn.net/wenzhi20102321/article/details/78167984
4建造者模式:http://blog.csdn.net/wenzhi20102321/article/details/78163855
3抽象工厂模式:http://blog.csdn.net/wenzhi20102321/article/details/78153437
2工厂方法模式:http://blog.csdn.net/wenzhi20102321/article/details/78129065
可以仔细对比一下工厂方法模式和抽象工厂模式,看看概念,看看类图,看看代码,就会明白了。
1单例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203
java 23种设计模式介绍:http://blog.csdn.net/wenzhi20102321/article/details/54601909