状态模式(State)就是根据对象的状态不同,将有不同的行为。很简单的方法我们可以做N个
if(){
}
else if(){
}
...
...
else{
}
但是这样可想而知工作量会相当的大,这样就引入了状态模式,能实现和前面一样的功能,但是没有判断语句,而且如果添加了新的功能模块或者是流程,只要添加一个状态类就可以了。下面是简单的状态模式的原理图:
这里我用了一个QQ登录的状态来简单的模拟了一下状态模式,因为QQ从离线到登录到忙碌到离线就是一个很好的状态模式:
简单的画了一个原理图:
首先建立一个state接口,主要用于实现用,通过接口编程方便:
package com.designpattern.state;
public interface State {
public void handle(QQ qq);
}
而后分别建立离线状态,Q我吧状态,忙碌状态,然后又回到离线,具体内容是一样的,就是一个状态里面的handle方法创建了下一个状态从而达到状态不断切换的功能:
package com.designpattern.state;
public class LeavingState implements State {
@Override
public void handle(QQ qq) {
qq.setState(new LoginningState());
System.out.println("QQ正在登陆在中······");
}
}
package com.designpattern.state;
public class LoginningState implements State {
@Override
public void handle(QQ qq) {
qq.setState(new ChattingState());
System.out.println("QQ登陆成功,Q我吧······");
}
}
package com.designpattern.state;
public class ChattingState implements State {
@Override
public void handle(QQ qq) {
qq.setState(new BusyingState());
System.out.println("QQ正在忙碌中······");
}
}
package com.designpattern.state;
public class BusyingState implements State {
@Override
public void handle(QQ qq) {
qq.setState(new LeavingState());
System.out.println("QQ已经离线······");
}
}
这样定义一个QQ类,主要是对QQ的各种状态的一个动态的变化,废话不多说,看代码就明了:
package com.designpattern.state;
public class QQ {
private State state;
public QQ() {
state = new LeavingState();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void handle() {
state.handle(this);
}
}
然后客户端调用输出:
package com.designpattern.state;
public class Client {
public static void main(String[] args) {
QQ qq = new QQ();
qq.handle();
qq.handle();
qq.handle();
qq.handle();
qq.handle();
qq.handle();
qq.handle();
qq.handle();
}
}
QQ正在登陆在中······
QQ登陆成功,Q我吧······
QQ正在忙碌中······
QQ已经离线······
QQ正在登陆在中······
QQ登陆成功,Q我吧······
QQ正在忙碌中······
QQ已经离线······
这样就简单的模拟了QQ的一系列的状态;
状态模式使代码种复杂而庸长的逻辑判断语句问题得到了解决,而且具体状态角色将具体的状态和它对应的行为封装起来了,这使得增加一种新的状态变得十分简单。但是每一个状态对应一个具体的状态类,是结构分散,逻辑不是很清楚,阅读代码工作量会大一些。
看到这里我不禁思考了一个问题,既然用状态模式可以模拟QQ的一系列的状态,那么我的状态的改变也一样能通知好友,让好友时时的关注我的状态情况,这时我就想到了刚刚学到的Observer模式,就是一个观察啊,我就想了一下,把两个模式用到一起,把每一个状态的变化都通知自己所有的好友,不多说,马上做的Demo试试:
和上面一样首先建立了一个公用的接口State.java
接着模式QQ的四种状态,这里就粘贴了一个实例,不过都差不多:
package com.designpattern.state_observer;
public class ChattingState implements State {
@Override
public void handle(QQ qq) {
qq.setState(new BusyingState());
qq.setMessage("QQ正在忙碌中······");
}
}
和上面不同的是堕落一个setMessage,这里是用来传递给QQ类,这样才能再次提醒观察的QQ好友,我的变化;
这里QQ类我定义成了一个抽象的类,不过大部分都封装好了,在让子类去继承的时候就继承一个handle方法就能实现操作,这样看起来比较简单:
package com.designpattern.state_observer;
import java.util.ArrayList;
import java.util.List;
public abstract class QQ {
private List<Friends> friends = new ArrayList<Friends>();
private String message;
private String name = "halberd";
private State state;
public QQ() {
this.state = new LeavingState();
}
public synchronized QQ addFriend(Friends friend) {
friends.add(friend);
return this;
}
public String getMessage() {
return message;
}
public State getState() {
return state;
}
public QQ handle() {
this.state.handle(this);
System.out.println(this.message);
this.notifyFriends();
return this;
}
public void notifyFriends() {
for (int i = 0; i < friends.size(); i++) {
Friends friend = (Friends) friends.get(i);
friend.recevie(this.message, this.name);
}
}
public synchronized QQ removeFriend(Friends friend) {
friends.remove(friend);
return this;
}
public void setMessage(String message) {
this.message = message;
}
public void setState(State state) {
this.state = state;
}
}
其实很简单,就是把两个模式结合了一个,之后就是具体的实例对象:
package com.designpattern.state_observer;
public class MyQQ extends QQ {
@Override
public QQ handle() {
return super.handle();
}
}
我起名为MyQQ意为我的QQ,然后在用我的QQ好友实现Friends接口:
package com.designpattern.state_observer;
public interface Friends {
public void recevie(String message,String name);
}
里面的两个参数一个是状态,一个是用户名(其实一个不写也行,我是想如果观察的不是我,就又可以复用了)
然后定义了两个朋友:
package com.designpattern.state_observer;
public class AndiMuise implements Friends {
@Override
public void recevie(String message, String name) {
System.out.println("AndiMuise已经知道 " + name + " : " + message);
}
}
客户端操作如下:
package com.designpattern.state_observer;
public class Client {
public static void main(String[] args) {
QQ qq = new MyQQ();
qq.addFriend(new AndiMuise()).addFriend(new Steve());
qq.handle().handle().handle();
}
}
实例一个QQ对象,这里当然是我自己了,MyQQ这里如果是别人的直接再继承一下就行了,也不用修改代码,之后添加了两个QQ好友作为监听者,然后开始我一系列的状态的变化:
QQ正在登陆在中······
AndiMuise已经知道 halberd : QQ正在登陆在中······
Steve已经知道 halberd : QQ正在登陆在中······
QQ登陆成功,Q我吧······
AndiMuise已经知道 halberd : QQ登陆成功,Q我吧······
Steve已经知道 halberd : QQ登陆成功,Q我吧······
QQ正在忙碌中······
AndiMuise已经知道 halberd : QQ正在忙碌中······
Steve已经知道 halberd : QQ正在忙碌中······
这样就大功告成了,其实这样挺好的,慢慢学会把几个模式综合一下,因为重复的代码比较多,没有贴全,上传到了:
http://download.csdn.net/detail/wclxyn/4230476
初学笔记,还望批评指正
(后来改成了这个样子,就是能调用了setName方法,当然返回值是QQ,这样就省事了,关键是我比较懒)
package com.designpattern.state_observer;
public class Client {
public static void main(String[] args) {
QQ qq = new MyQQ();
qq.setName("wclxyn").addFriend(new AndiMuise()).addFriend(new Steve())
.handle().handle().handle();
new MyQQ().setName("腾讯客服").addFriend(new AndiMuise()).addFriend(
new Steve()).handle().handle().handle();
}
}
QQ正在登陆在中······
AndiMuise已经知道 wclxyn : QQ正在登陆在中······
Steve已经知道 wclxyn : QQ正在登陆在中······
QQ登陆成功,Q我吧······
AndiMuise已经知道 wclxyn : QQ登陆成功,Q我吧······
Steve已经知道 wclxyn : QQ登陆成功,Q我吧······
QQ正在忙碌中······
AndiMuise已经知道 wclxyn : QQ正在忙碌中······
Steve已经知道 wclxyn : QQ正在忙碌中······
QQ正在登陆在中······
AndiMuise已经知道 腾讯客服 : QQ正在登陆在中······
Steve已经知道 腾讯客服 : QQ正在登陆在中······
QQ登陆成功,Q我吧······
AndiMuise已经知道 腾讯客服 : QQ登陆成功,Q我吧······
Steve已经知道 腾讯客服 : QQ登陆成功,Q我吧······
QQ正在忙碌中······
AndiMuise已经知道 腾讯客服 : QQ正在忙碌中······
Steve已经知道 腾讯客服 : QQ正在忙碌中······
分享到:
相关推荐
设计模式C++学习之状态模式(State)
状态模式(State) 用意:允许一个对象当状态改变时,改变其行为。
State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了. 不只是根据状态,也有根据属性.如果...
http://blog.csdn.net/feiyinzilgd/archive/2011/04/05/6302717.aspx (C++ State 设计模式博客)演示源代码。用C++实现并较详细的讲述了Sate模式的意图和工作状态。
C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式
NULL 博文链接:https://wy649898543.iteye.com/blog/1434590
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
Head First 设计模式 (十) 状态模式(State pattern) C++实现
在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
C++设计模式课件18_State_状态模式.pdf
第18章 状态模式(State) 第19章 备忘录模式(Memento) 第20章 享元模式(Flyweight) 第21章 解释器模式(Interpreter) 第22章 装饰模式(Decorator) 第23章 职责链模式(Chain of Responsibility) 第24...
主要介绍了Java设计模式之状态模式(State模式)介绍,本文讲解了何时使用状态模式、如何使用状态模式等内容,需要的朋友可以参考下
该PDF是我在学习state pattern时所做的笔记。里面包括了state pattern 的定义、何时使用、是否使用及实例四个部分,实例部分写的比较细,看完这个实例,相信大家也就知道怎么在自己的项目中应用state pattern了。这...
C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式 C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式 C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式 C#面向对象设计...
c++设计模式-行为型模式-状态模式;qt工程;c++简单源码; 状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
分享关于状态模式的c++实现,若理解有误,还请指正。
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题,而这样的问题,大部分人是采用switch-case语句进行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对...
NULL 博文链接:https://zhangyan19870108.iteye.com/blog/1992409
5.8 STATE(状态)—对象行为型模式 201 5.9 STRATEGY(策略)—对象行为型 模式 208 5.10 TEMPLATE METHOD(模板方法) —类行为型模式 214 5.11 VISITOR(访问者)—对象行为型 模式 218 5.12 行为模式的讨论 228 ...