一、基本介绍
状态模式(行为型):对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
二、包含角色
1.环境角色:上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
2.抽象状态角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
3.具体状态角色:实现抽象状态所对应的行为。
三、案例及UML类图
案例说明:
文件一般有三种基本状态,可读、可写、可执行,每一种状态都能做对应的操作,如可读状态,能够读取文件内容,可写状态能够写入内容,每个状态对应一种行为。
UML类图:
类FileState:
public interface FileState {
/**
* 对文件进行处理,每个状态的具体操作都不一样
* @param str 内容
* @param fileContext 文件上下文环境
* @return 如果是读取,则返回内容
*/
String handel(String str, FileContext fileContext) throws IOException;
boolean changeState(FileContext fileContext);
}
说明:文件状态接口,抽象状态角色,定义状态的公共接口。
类Readable:
public class Readable implements FileState {
@Override
public String handel(String str, FileContext fileContext) throws IOException {
File file = fileContext.getFile();
FileInputStream inputStream = null;
String content = null;
try {
inputStream = new FileInputStream(file);
Long length = file.length();
byte[] bytes = new byte[length.intValue()];
inputStream.read(bytes);
content = new String(bytes);
}finally {
inputStream.close();
}
return content;
}
@Override
public boolean changeState(FileContext fileContext) {
fileContext.setFileState(this);
return true;
}
}
说明:文件可读状态类,具体状态角色,文件可读状态可进行读取文件内容操作。
类Writable:
public class Writable implements FileState {
@Override
public String handel(String str, FileContext fileContext) throws IOException {
File file = fileContext.getFile();
FileWriter writer = new FileWriter(file,true);
writer.append(str);
writer.close();
return null;
}
@Override
public boolean changeState(FileContext fileContext) {
fileContext.setFileState(this);
return true;
}
}
说明:文件可写状态类,具体状态角色,文件可写状态可进行文件写入操作。
类FileContext:
public class FileContext {
//要操作的文件
private File file;
//当前文件的状态
private FileState fileState;
public FileContext(File file) {
this.file = file;
//默认状态
fileState = new Writable();
}
/**
* 对文件进行处理,每个状态的具体操作都不一样
* @param str
* @return 如果是读取,则返回内容
*/
public String handel(String str) throws IOException {
return fileState.handel(str,this);
}
public File getFile() {
return file;
}
public void setFileState(FileState fileState) {
this.fileState = fileState;
}
}
说明:文件上下文环境类,环境角色,定义文件操作方法,具体操作通过当前的具体状态类去进行。
类StateTest:
public class StateTest {
public static void main(String[] args) throws IOException {
StringBuilder path = new StringBuilder();
path.append(StateTest.class.getClass().getResource("/").getPath());
//包名
String packageName = StateTest.class.getName().replaceAll("\\.\\w+","");
path.append(packageName).append("/").append("test.txt");
//文件
File file = new File(path.toString());
//文件环境,默认是可写的,所以直接写入即可
FileContext context = new FileContext(file);
//写入内容
context.handel("hello word!");
//改变状态读取刚才写入的内容
Readable readable = new Readable();
readable.changeState(context);
String content = context.handel("");
System.out.println(content);
}
}
说明:测试及客户端。
四、适用场景
1.当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。
2.一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。
五、其它
补充:上述案例中,并未写可执行,可读可写等状态,此模式是符合开闭原则的,如果要添加其它状态,直接实现接口进行添加即可。