一、模式簡(jiǎn)介
定義:對(duì)有狀態(tài)的對(duì)象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對(duì)象中,允許狀態(tài)對(duì)象在其內(nèi)部狀態(tài)發(fā)生改變時(shí)改變其行為。
場(chǎng)景:當(dāng)一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為時(shí)。當(dāng)一個(gè)操作中含有龐大的分支結(jié)構(gòu),并且這些分支決定于對(duì)象的狀態(tài)時(shí)。
- 角色結(jié)構(gòu):
- 環(huán)境(Context)角色:也稱為上下文,它定義了客戶感興趣的接口,維護(hù)一個(gè)當(dāng)前狀態(tài),并將與狀態(tài)相關(guān)的操作委托給當(dāng)前狀態(tài)對(duì)象來(lái)處理。
- 抽象狀態(tài)(State)角色:定義一個(gè)接口,用以封裝環(huán)境對(duì)象中的特定狀態(tài)所對(duì)應(yīng)的行為。
- 具體狀態(tài)(Concrete State)角色:實(shí)現(xiàn)抽象狀態(tài)所對(duì)應(yīng)的行為。
二、模式實(shí)現(xiàn)
public abstract class AbstractThreadState { -> 抽象狀態(tài)
protected String state;
protected abstract String state();
}
public class NewConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
public void start(ThreadContext context){
if("new".equals(context.getState().state())){
System.out.println("線程處于new狀態(tài),切換到runnable狀態(tài)");
context.setState(new RunnableConcreteThreadState());
}else{
System.out.println("線程不處于new狀態(tài),不能調(diào)用start方法");
}
}
@Override
protected String state() {
super.state = "new";
return this.state;
}
}
public class RunnableConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
@Override
protected String state() {
super.state = "runnable";
return this.state;
}
public void cpu(ThreadContext context){
if("runnable".equals(context.getState().state())){
System.out.println("線程處于runnable狀態(tài),切換到running狀態(tài)");
context.setState(new RunningConcreteThreadState());
}else{
System.out.println("線程不處于runnable狀態(tài),不能調(diào)用cpu方法");
}
}
}
public class RunningConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
@Override
protected String state() {
super.state = "running";
return this.state;
}
public void suspend(ThreadContext context){
if("running".equals(context.getState().state())){
context.setState(new BlockConcreteThreadState());
System.out.println("線程處于runnable狀態(tài),切換到block狀態(tài)");
}else{
System.out.println("線程不處于runnable狀態(tài),不能調(diào)用suspend方法");
}
}
public void stop(ThreadContext context){
if("running".equals(context.getState().state())){
context.setState(new DeadConcreteThreadState());
System.out.println("線程處于runnable狀態(tài),切換到deal狀態(tài)");
}else{
System.out.println("線程不處于runnable狀態(tài),不能調(diào)用stop方法");
}
}
}
public class BlockConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
@Override
protected String state() {
super.state = "block";
return this.state;
}
public void resume(ThreadContext context){
if("block".equals(context.getState().state())){
System.out.println("線程處于block狀態(tài),切換到runnable狀態(tài)");
context.setState(new RunningConcreteThreadState());
}else{
System.out.println("線程不處于block狀態(tài),不能調(diào)用resume方法");
}
}
}
public class DeadConcreteThreadState extends AbstractThreadState { -> 具體狀態(tài)
@Override
protected String state() {
super.state = "deal";
return this.state;
}
public void dead(){
System.out.println("線程處于deal狀態(tài)");
}
}
public class ThreadContext { -> 環(huán)境
private AbstractThreadState state;
public ThreadContext(AbstractThreadState state) {
this.state = state;
}
public void start() {
if(state instanceof NewConcreteThreadState){
((NewConcreteThreadState) state).start(this);
}else{
System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法start");
}
}
public void cpu() {
if(state instanceof RunnableConcreteThreadState){
((RunnableConcreteThreadState) state).cpu(this);
}else{
System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法cpu");
}
}
public void stop() {
if(state instanceof RunningConcreteThreadState){
((RunningConcreteThreadState) state).stop(this);
}else{
System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法stop");
}
}
public void suspend() {
if(state instanceof RunningConcreteThreadState){
((RunningConcreteThreadState) state).suspend(this);
}else{
System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法suspend");
}
}
public void resume() {
if(state instanceof BlockConcreteThreadState){
((BlockConcreteThreadState) state).resume(this);
}else{
System.out.println("線程正處于"+state.state()+"狀態(tài),無(wú)法resume");
}
}
public AbstractThreadState getState() {
return state;
}
public void setState(AbstractThreadState state) {
this.state = state;
}
}
以Java線程狀態(tài)切換為例子,狀態(tài)包含new、runnable、running、block、dead,每種狀態(tài)有各自的行為,當(dāng)調(diào)用者與線程對(duì)象產(chǎn)生互動(dòng)后,線程對(duì)象內(nèi)部的狀態(tài)隨之發(fā)生改變,線程對(duì)象的行為同時(shí)發(fā)生改變。
ThreadContext context=new ThreadContext(new NewConcreteThreadState());
context.start();
context.cpu();
context.suspend();
context.resume();
context.cpu();
context.stop();