网站自己建机房,企业手机网站开发,电脑网站打不开是什么原因造成的,网站建设 博采网络 学校某信用卡业务系统#xff0c;银行账户存在3种状态#xff0c;且在不同状态下存在不同的行为#xff1a;
1#xff09;正常状态#xff08;余额大等于0#xff09;#xff0c;用户可以存款也可以取款#xff1b;
2#xff09;透支状态#xff08;余额小于0且大于-20… 某信用卡业务系统银行账户存在3种状态且在不同状态下存在不同的行为
1正常状态余额大等于0用户可以存款也可以取款
2透支状态余额小于0且大于-2000用户可以存款也可以取款但需要对欠款支付利息。
3受限状态余额小等于-2000用户只能存款还需要对欠款支付利息。 图 伪代码实现上述需求
上面代码存在以下问题
1获取状态时有好多个if分支如果再增加几个状态则需要增加判断条件同时也不符合开闭原则。
2在进行存取款操作时有对状态进行判断的条件行为受到状态的限制。
为了更好对具有多种状态的对象进行设计可以使用一种被称作状态模式的设计模式。
1 状态模式
状态模式State Pattern允许一个对象在其内部状态改变时改变它的行为对象看起来似乎修改了它的状态类。是一种对象行为型模式。 图 状态模式UML
Context环境类是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同因此将状态独立出去形成单独的状态类。
State抽象状态类用于定义一个接口以封装与环境类的一个特定状态相关的行为。在抽象状态类中声明各种不同状态对应的方法而在其子类中实现这些方法。
ConcreteState具体状态类是抽象状态类的子类每个子类实现与环境类的一个状态相关的行为。
public class UserAccount {private double balance;private CardState cardState;public UserAccount(double balance) {this.balance balance;cardState new NormalCardState(this);}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance balance;}public void deposit(double money) {System.out.println(存钱 money);cardState.deposit(money);changeState();System.out.println(信用卡余额: balance ,状态是 cardState.getState());System.out.println(------------------------------);}public void withdraw(double money) {if (balance - money 0) {System.out.println(借钱 money ,利息利率是0.01);} else {System.out.println(取款 money);}cardState.withdraw(money);changeState();System.out.println(信用卡余额: balance ,状态是 cardState.getState());System.out.println(------------------------------);}public void changeState() {if (balance 0) {if (!正常.equals(cardState.getState())) cardState new NormalCardState(this);} else if (balance -2000) {if (!透支.equals(cardState.getState())) cardState new OverdraftCardState(this);} else {if (!受限.equals(cardState.getState())) cardState new LimitationCardState(this);}}public void setCardState(CardState cardState) {this.cardState cardState;}
}public abstract class CardState {protected final UserAccount userAccount;public CardState(UserAccount userAccount) {this.userAccount userAccount;}public abstract void deposit(double money); // 存款public abstract void withdraw(double money); // 取款public abstract void payInterest(); // 支付利息public abstract String getState(); // 获取状态}public class BankService {public static void main(String[] args) {// 开户UserAccount userAccount new UserAccount(1000);userAccount.withdraw(500);userAccount.deposit(200);userAccount.withdraw(1000);userAccount.deposit(100);userAccount.withdraw(2000);userAccount.withdraw(500);}}//取款 500.0
//信用卡余额:500.0,状态是正常
//------------------------------
//存钱 200.0
//信用卡余额:700.0,状态是正常
//------------------------------
//借钱 1000.0,利息利率是0.01
//信用卡余额:-300.0,状态是透支
//------------------------------
//存钱 100.0
//支付利息-3.0
//信用卡余额:-203.0,状态是透支
//------------------------------
//借钱 2000.0,利息利率是0.01
//支付利息-2.0300000000000002
//信用卡余额:-2205.03,状态是受限
//------------------------------
//借钱 500.0,利息利率是0.01
//该账户已受限,不能取款
//信用卡余额:-2205.03,状态是受限
//------------------------------public class NormalCardState extends CardState{public NormalCardState(UserAccount userAccount) {super(userAccount);}Overridepublic void deposit(double money) {userAccount.setBalance(userAccount.getBalance() money);}Overridepublic void withdraw(double money) {userAccount.setBalance(userAccount.getBalance() - money);}Overridepublic void payInterest() {}Overridepublic String getState() {return 正常;}}public class OverdraftCardState extends CardState{public OverdraftCardState(UserAccount userAccount) {super(userAccount);}Overridepublic void deposit(double money) {payInterest();userAccount.setBalance(userAccount.getBalance() money);}Overridepublic void withdraw(double money) {payInterest();userAccount.setBalance(userAccount.getBalance() - money);}Overridepublic void payInterest() {System.out.println(支付利息 userAccount.getBalance() * 0.01);userAccount.setBalance(userAccount.getBalance() * ( 1 0.01));}Overridepublic String getState() {return 透支;}
}public class LimitationCardState extends CardState{public LimitationCardState(UserAccount userAccount) {super(userAccount);}Overridepublic void deposit(double money) {payInterest();userAccount.setBalance(userAccount.getBalance() money);}Overridepublic void withdraw(double money) {System.out.println(该账户已受限,不能取款);}Overridepublic void payInterest() {System.out.println(支付利息 userAccount.getBalance() * 0.01);userAccount.setBalance(userAccount.getBalance() * ( 1 0.01));}Overridepublic String getState() {return 受限;}
}
使用状态模式后在编码过程中可以不要在关系具体状态只需专注实现具体状态下的业务。
1.1 状态转换方式
在状态模式中环境类的状态转换方式有两种
1在环境类完成转换。上面代码是以这种形式
2在具体状态类中完成转换。 图 两种状态转换方式的比较
如果新增状态类则两种方式都需要在各自的类中做修改。都不符合开闭原则。
1.2 共享状态
在有些情况下多个环境类对象需要共享一个状态这时需要把状态对象定义为一个静态成员对象。
需求一个房间有两个开关来控制灯泡的开关。开关等功能是固定的打开只能使灯泡亮起关闭只能使灯泡熄灭。
public class LightSwitch {private final static LightState onState new OnLightState(),offState new OffLightState();private static LightState lightState offState;private final String name;public LightSwitch(String name) {this.name name;}public static void changeLightState(String type) {if (on.equalsIgnoreCase(type)) {lightState onState;} else {lightState offState;}}public void off() {System.out.println(name 关闭操作);lightState.off(this);}public void on() {System.out.println(name 打开操作);lightState.on(this);}}public abstract class LightState {public abstract void on(LightSwitch lightSwitch);public abstract void off(LightSwitch lightSwitch);
}public class OnLightState extends LightState{Overridepublic void on(LightSwitch lightSwitch) {System.out.println(灯泡已打开);System.out.println(--------------);}Overridepublic void off(LightSwitch lightSwitch) {System.out.println(关闭成功);LightSwitch.changeLightState(off);System.out.println(--------------);}}public class OffLightState extends LightState{Overridepublic void on(LightSwitch lightSwitch) {System.out.println(打开成功);LightSwitch.changeLightState(on);System.out.println(--------------);}Overridepublic void off(LightSwitch lightSwitch) {System.out.println(灯泡已关闭);System.out.println(--------------);}}public class PeopleOpera {public static void main(String[] args) {LightSwitch lightSwitch1 new LightSwitch(开关1);LightSwitch lightSwitch2 new LightSwitch(开关2);lightSwitch1.on();lightSwitch2.off();lightSwitch1.off();lightSwitch1.on();lightSwitch2.on();lightSwitch2.off();}
}//开关1打开操作
//打开成功
//--------------
//开关2关闭操作
//关闭成功
//--------------
//开关1关闭操作
//灯泡已关闭
//--------------
//开关1打开操作
//打开成功
//--------------
//开关2打开操作
//灯泡已打开
//--------------
//开关2关闭操作
//关闭成功
//--------------
2 优缺点
优点
1环境类转换状态方式封装状态的转换规则对状态转换代码集中管理。
2将所有与具体状态有关的行为都封装在一个类中。
3可以让多个环境对象共享一个状态对象从而减少系统中对象个数。
4在具体状态类中转换状态方式将状态转换逻辑与状态对象合成一起避免使用庞大的条件语句块来将业务方法和状态转换代码交织在一起。
缺点
1增加了类和对象的个数。
2实现较为复杂增加了系统设计难度。
3对开闭原则的支持并不好。
3 适用场景
1对象的行为依赖它的状态且状态之间互相转换。
2代码中包含大量与对象状态有关的条件语句。