广西南宁市网站建设服务中心,建行官方网站多少,价格网打不开,龙岩到永定我是荔园微风#xff0c;作为一名在IT界整整25年的老兵#xff0c;今天总结一下Windows环境下如何编程实现状态模式#xff08;设计模式#xff09;。不知道大家有没有这样的感觉#xff0c;看了一大堆编程和设计模式的书#xff0c;却还是很难理解设计模式#xff0c;无…我是荔园微风作为一名在IT界整整25年的老兵今天总结一下Windows环境下如何编程实现状态模式设计模式。不知道大家有没有这样的感觉看了一大堆编程和设计模式的书却还是很难理解设计模式无从下手。为什么因为你看的都是理论书籍。我今天就在Windows操作系统上安装好JAVA的IDE编程工具并用JAVA语言来实现一个状态模式真实的实现一个你看懂代码后自然就明白了。状态模式State Pattern行为型设计模式定义允许一个对象在其内部状态改变时改变它的行为对象看起来似乎修改了它的类。上面定义听懂了吗莫名其妙看不懂对吧。所以我们还是来看看实现生活中的例子。在日常生活中人们总是有些各种喜怒哀乐的表情而且这四种状态还会互相转化包括人在内很多事物都具有多种状态而且在不同状态下会具有不同的行为这些状态在特定条件下还将发生相互转换。而状态模式就是要模拟这种同一事物存在多种状态但又会变化转化的情况。状态模式是一种较为复杂的设计模式它用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中的某个对象存在多个状态这些状态之间可以进行转换而且对象在不同状态下行为不相同时可以使用状态模式。在软件系统中有些对象具有多种状态这些状态在某些情况下能够相互转换而且对象在不同的状态下也将具有不同的行为。通常可以使用复杂的条件判断语句if else之类来进行状态判断和转换操作但这样会导致代码的可维护性和灵活性下降。状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态这些状态之间可以进行转换而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来封装到专门的状态类中使得对象状态可以灵活变化对于客户端而言无须关心对象状态的转换以及对象所处的当前状态无论对于何种状态的对象客户端都可以一致处理。在状态模式结构图中包含如下三个角色Context环境类、State抽象状态类、ConcreteState具体状态类。环境类又称为上下文类它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例这个实例定义当前状态在具体实现时它是一个State子类的对象。抽象状态类用于定义一个接口以封装与环境类的一个特定状态相关的行为在抽象状态类中声明了各种不同状态对应的方法而在其子类中实现类这些方法由于不同状态下对象的行为可能不同因此在不同子类中方法的实现可能存在不同相同的方法可以写在抽象状态类中。具体状态类是抽象状态类的子类每一个子类实现一个与环境类的一个状态相关的行为每一个具体状态类对应环境的一个具体状态不同的具体状态类其行为有所不同。JAVA代码public abstract class State {//声明抽象业务方法不同的具体状态类可以不同的实现public abstract void handle();
}public class ConcreteState extends State {public void handle() {//方法具体实现代码}
}public class Context {private State state; //维持一个对抽象状态对象的引用private int value; //其他属性值该属性值的变化可能会导致对象状态发生变化//设置状态对象public void setState(State state) {this.state state;}public void request() {//其他代码state.handle(); //调用状态对象的业务方法//其他代码}
}Context环境类实际上是真正拥有状态的对象这个模式的主要精神就是将Context环境类中与状态有关的代码提取出来封装到专门的状态类中。在状态模式结构图中在Context中定义了一个State对象。Context环境类与抽象状态类State之间存在单向关联关系也可能存在依赖或者其他关联关系。好下面是关键的内容了这部分是这个模式和其他设计模式一个很大的不同点也是此模式复杂的地方也就是在状态模式的使用过程中一个对象的状态之间还可以进行相互转换通常有两种实现状态转换的方式(1) 统一由环境类来负责状态之间的转换此时环境类还充当了状态管理器(State Manager)角色在环境类的业务方法中通过对某些属性值的判断if else之类实现状态转换还可以提供一个专门的方法用于实现属性判断和状态转换如下所示public void changeState() {//判断属性值根据属性值进行状态转换if (value 0) {this.setState(new ConcreteStateA());}else if (value 1) {this.setState(new ConcreteStateB());}......
}(2) 由具体状态类来负责状态之间的转换可以在具体状态类的业务方法中判断环境类的某些属性值再根据情况为环境类设置新的状态对象实现状态转换同样也可以提供一个专门的方法来负责属性值的判断和状态转换。此时状态类与环境类之间就将存在依赖或关联关系因为状态类需要访问环境类中的属性值如下所示public void changeState(Context su) {//根据环境对象中的属性值进行状态转换if (su.getValue() 1) {su.setState(new ConcreteStateB());}else if (su.getValue() 2) {su.setState(new ConcreteStateC());}......
}应用实例某金融理财手机APP具有理财功能每位用户在其中会开通个人账户(Account)APP用户账户存在三种状态在不同状态下账户存在不同的行为如果账户中余额大于等于0则账户的状态为正常状态(Normal State)此时用户既可以向该账户存款也可以从该账户取款 如果账户中余额小于0并且大于-10000则账户的状态为透支状态(Overdraft State)此时用户既可以向该账户存款也可以从该账户取款但需要按天计算利息如果账户中余额等于-10000那么账户的状态为受限状态(Restricted State)此时用户只能向该账户存款不能再从中取款同时也将按天计算利息。还有最后一种情况如果取款导致金额小于10000元了怎么办我们这里要规定一下如果小于这个数马上宣布不正常状态不准用户操作。Check()用于在每一次执行存款和取款操作后根据余额来判断是否要进行状态转换并实现状态转换相同的方法在不同的状态中可能会有不同的实现。为了实现不同状态下对象的各种行为以及对象状态之间的相互转化。1Account:银行账户,环境类package designpatterns.state;public class Account {private AccountState state; //维持一个对抽象状态对象的引用private String owner; //开户名private double balance 0; //账户余额public Account(String owner,double init) {this.owner owner;this.balance init;this.state new NormalState(this); //设置初始状态System.out.println(this.owner 开户余额为 this.balance); }public double getBalance() {return this.balance;}public void setBalance(double balance) {this.balance balance;}public void setState(AccountState state) {this.state state;}public void deposit(double amount) {System.out.println(this.owner 存款 amount);state.deposit(amount); //调用状态对象的deposit()方法System.out.println(余额为 this.balance);System.out.println(帐户状态为 this.state.getClass().getName());}public void withdraw(double amount) {System.out.println(this.owner 取款 amount);state.withdraw(amount); //调用状态对象的withdraw()方法System.out.println(余额为 this.balance);System.out.println(帐户状态为 this. state.getClass().getName()); }public void Interest(){state.Interest(); //调用状态对象的Interest()方法}
}2AccountState:账户状态类抽象状态类package designpatterns.state;public abstract class AccountState {protected Account cp;public abstract void deposit(double amount);public abstract void withdraw(double amount);public abstract void Interest();public abstract void Check();
}3NormalState:正常状态类package designpatterns.state;public class NormalState extends AccountState {public NormalState(Account cp) {this.cp cp;}public NormalState(AccountState state) {this.cp state.cp;}public void deposit(double amount) {cp.setBalance(cp.getBalance() amount);Check();}public void withdraw(double amount) {cp.setBalance(cp.getBalance() - amount);Check();}public void Interest(){System.out.println(正常状态);}//状态转换public void Check() {if (cp.getBalance() -10000 cp.getBalance() 0) {cp.setState(new OverdraftState(this));}else if (cp.getBalance() -10000) {cp.setState(new RestrictedState(this));}else if (cp.getBalance() -10000) {System.out.println(不正常状态);} }
} 4OverdraftState:透支状态类package designpatterns.state;public class OverdraftState extends AccountState {public OverdraftState(AccountState state) {this.cp state.cp;}public void deposit(double amount) {cp.setBalance(cp.getBalance() amount);Check();}public void withdraw(double amount) {cp.setBalance(cp.getBalance() - amount);Check();}public void Interest(){System.out.println(利息数额);}//状态转换public void Check() {if (cp.getBalance() 0) {cp.setState(new NormalState(this));}else if (cp.getBalance() -10000) {cp.setState(new RestrictedState(this));}else if (cp.getBalance() -10000) {System.out.println(不正常状态);} }
} 5RestrictedState:透支状态类package designpatterns.state;public class RestrictedState extends AccountState {public OverdraftState(AccountState state) {this.cp state.cp;}public void deposit(double amount) {cp.setBalance(cp.getBalance() amount);Check();}public void withdraw(double amount) {System.out.println(不能);}public void Interest(){System.out.println(利息数额);}//状态转换public void Check() {if (cp.getBalance() 0) {cp.setState(new NormalState(this));}else if (cp.getBalance() -10000) {cp.setState(new OverdraftState(this));}}
} 6Client:客户端测试类package designpatterns.state;public class Client {public static void main(String args[]) {Account cp new Account(小牛,0.0);cp.deposit(5000);cp.withdraw(10000);cp.deposit(6000);cp.withdraw(4000);cp.Interest();}
}这篇设计模式文章是我写的最累的一篇了写到这里已经很晚了实在写不动了。输出结果大家自行推理就是了。无非就是随着用户又取钱又存钱的导致银行帐户出现各类状态转换问题。状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中通过设置不同的状态对象可以让环境对象拥有不同的行为而状态转换的细节对于客户端而言是透明的方便了客户端的使用。在实际开发中状态模式具有较高的使用频率在工作流和游戏开发中状态模式都得到了广泛的应用例如公文状态的转换、游戏中角色的升级等。各位小伙伴这次我们就说到这里下次我们再深入研究windows环境下的各类设计模式实现。作者简介荔园微风1981年生高级工程师浙大工学硕士软件工程项目主管做过程序员、软件设计师、系统架构师早期的Windows程序员Visual Studio忠实用户C/C使用者是一位在计算机界学习、拼搏、奋斗了25年的老将经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代我不知道未来还会有什么时代只记得这一路走来充满着艰辛与收获愿同大家一起走下去充满希望的走下去。