Head First设计模式之状态模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Head First设计模式之状态模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6007字,纯文字阅读大概需要9分钟。
内容图文
![Head First设计模式之状态模式](/upload/InfoBanner/zyjiaocheng/1302/12ef0ec96a6847eab17580817dc73da3.jpg)
一、定义
定义:允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类。
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
何时使用:代码中包含大量与对象状态有关的条件语句。
如何解决:将各种具体的状态类抽象出来。
关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if...else 等条件选择语句。
二、结构图
Context类:维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。
State类:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
ConcreteStateA,ConcreteStateB,ConcreteStateC类:具体状态类,每一个子类实现一个与Context的一个状态相关的行为。
三、适用场景
1、行为随状态改变而改变的场景。
2、条件、分支语句的代替者。
四、优缺点
优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。
五、实现
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignPatterns.StatePattern { class Program { static void Main(string[] args) { // Open a new account Account account = new Account("Jim Johnson"); // Apply financial transactions account.Deposit(500.0); account.Deposit(300.0); account.Deposit(550.0); account.PayInterest(); account.Withdraw(2000.00); account.Withdraw(1100.00); // Wait for user Console.ReadKey(); } } class Account { private State _state; privatestring _owner; // Constructorpublic Account(string owner) { // New accounts are ‘Silver‘ by defaultthis._owner = owner; this._state = new SilverState(0.0, this); } // Propertiespublicdouble Balance { get { return _state.Balance; } } public State State { get { return _state; } set { _state = value; } } publicvoid Deposit(double amount) { _state.Deposit(amount); Console.WriteLine("Deposited {0:C} --- ", amount); Console.WriteLine("Balance = {0:C}", this.Balance); Console.WriteLine("Status = {0}",this.State.GetType().Name); Console.WriteLine(""); } publicvoid Withdraw(double amount) { _state.Withdraw(amount); Console.WriteLine("Withdrew {0:C} --- ", amount); Console.WriteLine(" Balance = {0:C}", this.Balance); Console.WriteLine(" Status = {0}\n", this.State.GetType().Name); } publicvoid PayInterest() { _state.PayInterest(); Console.WriteLine("Interest Paid --- "); Console.WriteLine(" Balance = {0:C}", this.Balance); Console.WriteLine(" Status = {0}\n", this.State.GetType().Name); } } ///<summary>/// The ‘State‘ abstract class ///</summary>abstractclass State { protected Account account; protecteddouble balance; protecteddouble interest; protecteddouble lowerLimit; protecteddouble upperLimit; // Propertiespublic Account Account { get { return account; } set { account = value; } } publicdouble Balance { get { return balance; } set { balance = value; } } publicabstractvoid Deposit(double amount); publicabstractvoid Withdraw(double amount); publicabstractvoid PayInterest(); } ///<summary>/// A ‘ConcreteState‘ class ///<remarks>/// Red indicates that account is overdrawn ///</remarks>///</summary>class RedState : State { privatedouble _serviceFee; // Constructorpublic RedState(State state) { this.balance = state.Balance; this.account = state.Account; Initialize(); } privatevoid Initialize() { // Should come from a datasource interest = 0.0; lowerLimit = -100.0; upperLimit = 0.0; _serviceFee = 15.00; } publicoverridevoid Deposit(double amount) { balance += amount; StateChangeCheck(); } publicoverridevoid Withdraw(double amount) { amount = amount - _serviceFee; Console.WriteLine("No funds available for withdrawal!"); } publicoverridevoid PayInterest() { // No interest is paid } privatevoid StateChangeCheck() { if (balance > upperLimit) { account.State = new SilverState(this); } } } ///<summary>/// A ‘ConcreteState‘ class ///<remarks>/// Silver indicates a non-interest bearing state ///</remarks>///</summary>class SilverState : State { // Overloaded constructorspublic SilverState(State state) : this(state.Balance, state.Account) { } public SilverState(double balance, Account account) { this.balance = balance; this.account = account; Initialize(); } privatevoid Initialize() { // Should come from a datasource interest = 0.0; lowerLimit = 0.0; upperLimit = 1000.0; } publicoverridevoid Deposit(double amount) { balance += amount; StateChangeCheck(); } publicoverridevoid Withdraw(double amount) { balance -= amount; StateChangeCheck(); } publicoverridevoid PayInterest() { balance += interest * balance; StateChangeCheck(); } privatevoid StateChangeCheck() { if (balance < lowerLimit) { account.State = new RedState(this); } elseif (balance > upperLimit) { account.State = new GoldState(this); } } } ///<summary>/// A ‘ConcreteState‘ class ///<remarks>/// Gold indicates an interest bearing state ///</remarks>///</summary>class GoldState : State { // Overloaded constructorspublic GoldState(State state) : this(state.Balance, state.Account) { } public GoldState(double balance, Account account) { this.balance = balance; this.account = account; Initialize(); } privatevoid Initialize() { // Should come from a database interest = 0.05; lowerLimit = 1000.0; upperLimit = 10000000.0; } publicoverridevoid Deposit(double amount) { balance += amount; StateChangeCheck(); } publicoverridevoid Withdraw(double amount) { balance -= amount; StateChangeCheck(); } publicoverridevoid PayInterest() { balance += interest * balance; StateChangeCheck(); } privatevoid StateChangeCheck() { if (balance < 0.0) { account.State = new RedState(this); } elseif (balance < lowerLimit) { account.State = new SilverState(this); } } } }
现实中还有其他很多例子,比如自动贩卖机、电梯等。
状态模式的关键在于 状态变化时引起行为的变化,它是被动的触发
策略模式的差别在于,它是由外部(client)主动引起行为的变化,可以随意控制它想要执行的行为。
参考文章:
http://www.cnblogs.com/ywqu/archive/2010/01/26/1656418.html
http://www.runoob.com/design-pattern/state-pattern.html
http://www.cnblogs.com/JsonShare/p/7246915.html
欢迎阅读本系列文章:Head First设计模式之目录
原文:http://www.cnblogs.com/xcsn/p/7492518.html
内容总结
以上是互联网集市为您收集整理的Head First设计模式之状态模式全部内容,希望文章能够帮你解决Head First设计模式之状态模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。