原文地址:http://te-amo.site/user/article/info/ARTICLE20180420073600309
文章中部分定義和解釋性文字,都是引用百度百科,主要的代碼及場景應用爲本人原創
狀態模式允許一個對象的內在狀態改變時改變其行爲,這個對象看起來像是改變了其類。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。
場景:我的個人網站中的文章管理的一個需求,文章的狀態有:待發布、正常、封禁、置頂、刪除。這五個狀態之間可以裝換,但是有一定限制:
- 待發布的文章,可以發佈(正常狀態),可以刪除(刪除狀態)
- 正常的文章,可以封禁(封禁狀態),可以置頂(置頂狀態),可以刪除(刪除狀態)
- 封禁的文章,可以解封(正常狀態),可以刪除(刪除狀態)
- 置頂的文章,可以取消置頂(正常狀態),可以封禁(封禁狀態),可以刪除(刪除狀態)
- 刪除的文章,什麼都不可做
設計
實現
代碼地址:https://github.com/telundusiji/designpattern
狀態接口
public interface ArticleState {
void publish(Article article);
void ban(Article article);
void pick(Article article);
void sticky(Article article);
void off(Article article);
void delete(Article article);
}
封禁狀態
@Slf4j
public class BanState implements ArticleState {
@Override
public void publish(Article article) {
}
@Override
public void ban(Article article) {
}
@Override
public void pick(Article article) {
log.info("文章:{}----解封成功!",article.getTitle());
article.setCurrentState(Article.normalState);
}
@Override
public void sticky(Article article) {
}
@Override
public void off(Article article) {
}
@Override
public void delete(Article article) {
log.info("文章:{}----刪除成功!",article.getTitle());
article.setCurrentState(Article.deleteState);
}
}
刪除狀態
public class DeleteState implements ArticleState {
@Override
public void publish(Article article) {
}
@Override
public void ban(Article article) {
}
@Override
public void pick(Article article) {
}
@Override
public void sticky(Article article) {
}
@Override
public void off(Article article) {
}
@Override
public void delete(Article article) {
}
}
正常狀態
@Slf4j
public class NormalState implements ArticleState {
@Override
public void publish(Article article) {
}
@Override
public void ban(Article article) {
log.info("文章:{}----封禁成功!",article.getTitle());
article.setCurrentState(Article.banState);
}
@Override
public void pick(Article article) {
}
@Override
public void sticky(Article article) {
log.info("文章:{}----置頂成功!",article.getTitle());
article.setCurrentState(Article.stickyState);
}
@Override
public void off(Article article) {
}
@Override
public void delete(Article article) {
log.info("文章:{}----刪除成功!",article.getTitle());
article.setCurrentState(Article.deleteState);
}
}
待發布狀態
@Slf4j
public class ReadyState implements ArticleState {
@Override
public void publish(Article article) {
log.info("文章:{}----發佈成功!",article.getTitle());
article.setCurrentState(Article.normalState);
}
@Override
public void ban(Article article) {
}
@Override
public void pick(Article article) {
}
@Override
public void sticky(Article article) {
}
@Override
public void off(Article article) {
}
@Override
public void delete(Article article) {
log.info("文章:{}----刪除成功!",article.getTitle());
article.setCurrentState(Article.deleteState);
}
}
置頂狀態
@Slf4j
public class StickyState implements ArticleState {
@Override
public void publish(Article article) {
}
@Override
public void ban(Article article) {
log.info("文章:{}----封禁成功!",article.getTitle());
article.setCurrentState(Article.banState);
}
@Override
public void pick(Article article) {
}
@Override
public void sticky(Article article) {
}
@Override
public void off(Article article) {
log.info("文章:{}----取消置頂成功!",article.getTitle());
article.setCurrentState(Article.normalState);
}
@Override
public void delete(Article article) {
log.info("文章:{}----刪除成功!",article.getTitle());
article.setCurrentState(Article.deleteState);
}
}
文章容器
@Data
public class Article{
private String title;
public final static BanState banState = new BanState();
public final static NormalState normalState = new NormalState();
public final static ReadyState readyState = new ReadyState();
public final static StickyState stickyState = new StickyState();
public final static DeleteState deleteState = new DeleteState();
private ArticleState currentState;
public void setState(ArticleState articleState){
currentState = articleState;
}
public void publish() {
currentState.publish(this);
}
public void ban() {
currentState.ban(this);
}
public void pick() {
currentState.pick(this);
}
public void sticky() {
currentState.sticky(this);
}
public void off() {
currentState.off(this);
}
public void delete() {
currentState.delete(this);
}
}
適用場景
- 一個對象的行爲取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行爲。
- 一個操作中含有龐大的多分支結構,並且這些分支決定於對象的狀態。