程序员

注册

 

发新话题 回复该主题

程序员内功心法设计模式之命令模式 [复制链接]

1#

基本定义

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

模式结构

Context(环境类):可以包括一些内部状态。

State(抽象状态类):所有具体状态的共同接口,任何状态都实现这个相同的接口,状态之间互相转换。

ConcreteState(具体状态类):用于处理来自Context的请求,每一个ConcreteState都提供了它对自己请求的实现,

模式实现

State抽象状态类

publicinterfaceState{//预定房间voidreservationRoom();//退订房间voidunsubscribeRoom();//入住voidcheckinRoom();//退房voidcheckoutRoom();}

ConcreteState具体状态类

空闲状态

Slf4jpublicclassFreeStateimplementsState{Roomroom;publicFreeState(Roomroom){this.room=room;}/***房间状态改变,还需修改内部状态*/

OverridepublicvoidreservationRoom(){log.info("您已预定房间");room.setState(room.reservationState);}

OverridepublicvoidunsubscribeRoom(){}

OverridepublicvoidcheckinRoom(){log.info("您已入住成功");room.setState(room.checkinState);}

OverridepublicvoidcheckoutRoom(){}}

预定状态

Slf4jpublicclassReservationStateimplementsState{Roomroom;publicReservationState(Roomroom){this.room=room;}

OverridepublicvoidreservationRoom(){log.error("预定失败,该房间已经被预定");}

OverridepublicvoidunsubscribeRoom(){log.info("您已经取消预定");room.setState(room.freeState);}

OverridepublicvoidcheckinRoom(){log.info("您已入住成功");room.setState(room.checkinState);}

OverridepublicvoidcheckoutRoom(){}}

入住状态

Slf4jpublicclassCheckinStateimplementsState{Roomroom;publicCheckinState(Roomroom){this.room=room;}

OverridepublicvoidreservationRoom(){log.error("预定失败,该房间已经入住");}

OverridepublicvoidunsubscribeRoom(){}

OverridepublicvoidcheckinRoom(){log.error("入住失败,该房间已经入住");}

OverridepublicvoidcheckoutRoom(){log.info("您已退房");room.setState(room.freeState);}}

Context环境类

/***状态模式特点一、除了关联抽象状态,还需要关联我们具体状态。*状态模式特点二,提供所有的抽象与具体的状态类。并且在无参构造方法初始化状态类。*还需要提供所有属性的set方法,供状态类使用,需要提供调用状态类的方法。**/

Slf4jpublicclassRoom{Statestate;/***状态模式特点一、除了关联抽象状态,还需要关联我们具体状态*/StatefreeState;StatereservationState;StatecheckinState;//初始化全部状态,且绑定关系publicRoom(){freeState=newFreeState(this);reservationState=newReservationState(this);checkinState=newCheckinState(this);state=freeState;}publicvoidsetState(Statestate){this.state=state;}/***核心方法*

return*/publicStategetState(){returnstate;}publicvoidsetFreeState(StatefreeState){this.freeState=freeState;}publicvoidsetReservationState(StatereservationState){this.reservationState=reservationState;}publicvoidsetCheckinState(StatecheckinState){this.checkinState=checkinState;}publicvoidreservationRoom(){state.reservationRoom();}publicvoidunsubscribeRoom(){state.unsubscribeRoom();}publicvoidcheckinRoom(){state.checkinRoom();}publicvoidcheckoutRoom(){state.checkoutRoom();}publicvoidshowCurrState(){log.info("当前房间状态{}",this.state.getClass().getSimpleName());}}

测试类

publicclassTest{publicstaticvoidmain(String[]args){Roomroom=newRoom();room.reservationRoom();room.showCurrState();room.checkinRoom();room.showCurrState();room.checkinRoom();room.checkoutRoom();room.showCurrState();}}

输出结果:

FreeState-您已预定房间

Room-当前房间状态ReservationState

ReservationState-您已入住成功

Room-当前房间状态CheckinState

CheckinState-入住失败,该房间已经入住

CheckinState-您已退房

Room-当前房间状态FreeState

优点

状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。

减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。

有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

缺点

状态模式的使用必然会增加系统的类与对象的个数。

状态模式的结构与实现都较为复杂。

适用场景

当对象的状态很多时,程序会变得很复杂。而且增加新的状态要添加新的if-else语句,这违背了“开闭原则”,不利于程序的扩展。

对象的行为依赖于它的状态并且可以根据它的状态改变而改变它的相关行为。

总结

状态模式允许一个对象基于内部状态而拥有不同的行为。

Context会将行为委托给当前状态对象。

预览时标签不可点收录于话题#个上一篇下一篇
分享 转发
TOP
2#
白癜风中药药方 http://m.39.net/pf/a_6199962.html

基本定义

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

模式结构

Command:抽象命令类

ConcreteCommand:具体命令类

Invoker:调用者,命令的传递者

Receiver:接收者,执行命令功能的相关操作,是具体命令对象业务的真正实现者。

Client:客户类

模式实现

Command

publicabstractclassCommand{//需要加载接收者类,将receiver加载finalstaticReceiverreceiver=newReceiver();intmemoryValue;publicabstractintexecute(intvalue);//撤销操作publicabstractintreset();}

ConcreteCommand具体命令类

publicclassAddCommandextendsCommand{

Overridepublicintexecute(intvalue){super.memoryValue=value;returnsuper.receiver.add(value);}

Overridepublicintreset(){returnsuper.receiver.subtract(memoryValue);}}

publicclassMultiCommandextendsCommand{

Overridepublicintexecute(intvalue){super.memoryValue=value;returnthis.receiver.multi(value);}

Overridepublicintreset(){returnreceiver.division(super.memoryValue);}}

Invoker调用者

Slf4jpublicclassInvoker{//调用者发送命令,所以需要将命令类关联进来Command
TOP
发新话题 回复该主题