首页 > 其他 > 详细

案例分析:设计模式与代码的结构特性

时间:2019-12-08 12:04:40      阅读:85      评论:0      收藏:0      [点我收藏+]

定义

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。 其别名为状态对象(Objects for States),状态模式是一种对象行为型模式

动机

在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。

结构

技术分享图片

组件

  • Context(环境类)
    环境类又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
  • State(抽象状态类)
    它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法,由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中
  • ConcreteState(具体状态类)
    它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。

实现

这里我们模拟一个QQ的状态转换过程

抽象状态类

1 package state;
2 ?
3 public interface State {
4     public void handle(Context context);
5 }

 

拥有多种状态的对象

 1 package state;
 2 ?
 3 public class Context {
 4     private State state;
 5 ?
 6     public State getState() {
 7         return state;
 8     }
 9 ?
10     public void setState(State state) {
11         this.state = state;
12     }
13 ?
14     public Context(State state) {
15         this.state = state;
16     }
17 ?
18     public void  contexthandle(){
19         state.handle(this);
20     }
21 }

 

具体状态类

 1 package state;
 2 ?
 3 public class ConcreteState implements State {
 4     @Override
 5     public void handle(Context context) {
 6         System.out.println("忙碌状态");
 7         //状态转换
 8         context.setState(new ConcreteStateC());
 9     }
10 }

 

具体状态类

 1 package state;
 2 ?
 3 public class ConcreteStateB implements State {
 4     @Override
 5     public void handle(Context context) {
 6         System.out.println("离线状态");
 7         //状态转换
 8         context.setState(new ConcreteState());
 9     }
10 }

 

具体状态类

 1 package state;
 2 ?
 3 public class ConcreteStateC implements  State{
 4     @Override
 5     public void handle(Context context) {
 6         System.out.println("在线状态");
 7         //状态转换
 8         context.setState(new ConcreteStateB());
 9     }
10 }

 

客户端

 1 package state;
 2 
 3 public class Clinet {
 4     public static void main(String[] args) {
 5         Context context = new Context(new ConcreteStateC());
 6         context.contexthandle();
 7         context.contexthandle();
 8         context.contexthandle();
 9         System.out.println();
10         context.contexthandle();
11         context.contexthandle();
12         context.contexthandle();
13     }
14 }

控制台输出

技术分享图片

应用案例

共同的特点:对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为

  • 按钮来控制一个电梯的状态,一个电梯开们,关门,停,运行。每一种状态改变,都有可能要根据其他状态来更新处理。例如,开门状体,你不能在运行的时候开门,而是在电梯定下后才能开门。
  • 我们给一部手机打电话,就可能出现这几种情况:用户开机,用户关机,用户欠费停机,用户消户等。 所以当我们拨打这个号码的时候:系统就要判断,该用户是否在开机且不忙状态,又或者是关机,欠费等状态。但不管是那种状态我们都应给出对应的处理操作
  • 如在政府OA办公系统中,一个批文的状态有多种:尚未办理;正在办理;正在批示;正在审核;已经完成等各种状态,而且批文状态不同时对批文的操作也有所差异。使用状态模式可以描述工作流对象(如批文)的状态转换以及不同状态下它所具有的行为。
  • TCP协议的实现:监听状态,建立连接的状态,关闭状态
  • qq登录有不同的状态:忙碌,在线,离线等,不同的状态决定不同的操作
  • TCP协议的实现:监听状态,建立连接的状态,关闭状态

优点

  • 基于继承的角度
    • 它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
    • 避免使用条件if else语句或switch case语句
    • 为不同的状态引入独立的对象使得转换变得更加明确
    • 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

 

  • 基于状态转换的角度
    • 可保证Context不会发生内部状态不一致的情况,因为从 Context的角度看,状态转换是原子的—只需重新绑定一个变量(即Context的State对象变量),而无需为多个变量赋值

 

  • 基于内存考虑
    • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

 

缺点

  • 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
  • 因为该模式将不同状态的行为分布在多个State子类中。这就增加了子类的数目
 

案例分析:设计模式与代码的结构特性

原文:https://www.cnblogs.com/lm273/p/12004783.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!