🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。
毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。每种设计模式都有相应的原理和最佳实践,它们描述了我们日常开发中不断遇到的问题,以及这些问题的核心解决方法。正是因为这种实用性和通用性,设计模式才能在软件开发中广泛地得以应用。设计模式是构建稳健、可扩展和可维护软件的关键工具,为开发者们提供了解决问题的智慧和指导。
状态模式属于行为型设计模式,它旨在允许一个对象在内部状态发生变化时,自动改变其行为方式,同时外部看起来似乎对象的类发生了变化。
状态模式的核心问题是解决当对象的行为在不同状态下需要根据复杂的条件表达式进行调整时的情况。通常情况下,这些条件表达式会导致代码复杂难以维护。通过状态模式,我们可以将状态的判断逻辑从主对象中分离出来,转移到一系列表示不同状态的类中,从而简化了复杂的条件判断。
在状态模式中,每个具体状态都有自己的类,它们实现了共同的状态接口或继承自共同的状态基类。主对象持有一个指向当前状态对象的引用,并且在状态发生变化时,切换到相应的状态对象。这种方式使得状态之间的转换变得清晰明了,同时也降低了主对象的复杂度。
状态模式提供了一种优雅的方式来管理对象的状态和行为,将状态判断逻辑封装在各个状态类中,提高了代码的可维护性和可扩展性。它是处理复杂状态机的有力工具,使代码更易于理解和维护。
在状态模式(State Pattern)中,抽象状态(State)是一个关键概念,它定义了所有具体状态类(Concrete State)必须遵循的接口或基类。抽象状态扮演了状态机中状态的抽象表示,具有以下作用:
抽象状态在状态模式中充当了状态的抽象定义和接口,它是状态模式的核心。通过使用抽象状态,状态模式将状态的行为封装在不同的状态类中,使得系统更加灵活、可扩展和易于维护。客户端代码与抽象状态交互,而不必担心具体状态的实现细节,从而实现了解耦和高内聚。这有助于更好地管理对象的状态
在状态模式(State Pattern)中,具体状态(Concrete State)是指实现了抽象状态(State)接口或继承了抽象状态基类的一组具体类。每个具体状态类代表了对象在特定状态下的行为和操作,具体状态的概念和作用如下:
具体状态在状态模式中扮演了非常重要的角色,它们定义了状态机中的各种具体状态,并封装了状态相关的行为和逻辑。通过将状态的不同方面分散到不同的具体状态类中,状态模式实现了状态和行为的松耦合,提高了系统的可维护性和可扩展性。客户端代码通常与具体状态类进行交互,而无需关心状态的具体实现细节。这有助于构建更灵活、可维护和可扩展的系统。
在状态模式(State Pattern)中,环境类(Context)是一个包含状态对象并委托给当前状态对象处理行为的类。环境类的作用是管理对象的状态以及根据当前状态来执行适当的行为。以下是环境类的概念和作用:
环境类在状态模式中充当了状态的管理者和委托者的角色。它通过持有当前状态对象的引用,动态地改变对象的行为,同时将状态判断和行为执行的职责分离,提高了系统的可维护性和可扩展性。客户端代码与环境类进行交互,而不必了解状态的具体实现,这有助于构建更清晰、灵活和可维护的代码。
命名空间StatePattern中包含抽象状态类State,代表水的3种状态,0度及以下时为SolidState固体状态,0到100度为LiquidState液体状态,100度及以上时为GasState气体状态,并且不同的状态可以改变水类Water中喝水Drink方法的行为。本案例尝试以水的3种不同状态来向大家阐述状态模式在实际开发中的应用。
public class Water {
public State State { get; set; }
public double Temperature { get; set; } = 0;
public Water() {
State = new SolidState();
State.Water = this;
}
public Water Increase(int value) {
State.Increase(value);
return this;
}
public Water Reduce(int value) {
State.Reduce(value);
return this;
}
public Water Drink() {
if (this.State is LiquidState) {
Console.WriteLine("You can drink!");
}
else {
Console.WriteLine("You can not drink!");
}
Console.WriteLine(Const.LINE_BREAK);
return this;
}
}
Water水类充当环境类,公开一个状态基类,并在内部维护一个温度。Increase调用State的升温,而Reduce调用State的降温,最后的Drink方法会因为水的状态的不同而拥有不同的行为。为了简化逻辑,在本例中,只有当水为液体时才能被饮用。
public abstract partial class State {
public static Water Water { get; set; }
protected static string StateName { private get; set; }
public void Increase(int value) {
if (value == 0) return;
if (value < 0) throw new ArgumentException();
OnStateChanging();
Water._temperature += value;
ChangeState();
}
public void Reduce(int value) {
if (value == 0) return;
if (value < 0) throw new ArgumentException();
if (Water._temperature - value <= Const.ABSOLUTE_ZERO) {
throw new UnReachableException();
}
OnStateChanging();
Water._temperature -= value;
ChangeState();
}
}
抽象状态基类,首先公开一个水的引用,并在所有实现类中共享StateName状态名,Increase为水升高一个温度,而Reduce为水降温。
public abstract partial class State {
private void ChangeState() {
if (Water._temperature <= 0) {
Water.State = new SolidState();
}
else if (Water._temperature > 0 && Water._temperature < 100) {
Water.State = new LiquidState();
}
else {
Water.State = new GasState();
}
OnStateChanged();
}
protected virtual void OnStateChanging() {
Console.WriteLine(Const.ON_STATE_CHANGING);
Console.WriteLine(
string.Format(Const.TEMPERATURE_INFO,
Water._temperature, StateName));
}
protected virtual void OnStateChanged() {
Console.WriteLine(Const.ON_STATE_CHANGED);
Console.WriteLine(
string.Format(Const.TEMPERATURE_INFO,
Water._temperature, StateName));
Console.WriteLine(Const.LINE_BREAK);
}
}
抽象状态基类的第2部分(partial ),定义ChangeState方法以在改变温度时更改状态,另外定义OnStateChanging和OnStateChanged这2个受保护的虚方法以便提供“子类可以决定是否重写相应的方法来影响父类”的这样一个功能(OOP特性)。
public class SolidState : State {
public SolidState() {
StateName = "Solid";
}
}
public class LiquidState : State {
public LiquidState() {
StateName = "Liquid";
}
}
public class GasState : State {
public GasState() {
StateName = "Gas";
}
}
水的3种状态的具体实现类,SolidState固体状态、LiquidState液体状态和GasState气体状态,由于我们在状态基类中封装了较多的功能,所以此处的3个具体类都比较精简,只在构造函数中更改共享的StateName状态名称字段。在实际开发过程中,应当尽可能的将具体的功能封装在状态实现类中。
public class Const {
public const double ABSOLUTE_ZERO = -273.15;
public const string LINE_BREAK =
"--------------------------------------------------";
public const string ON_STATE_CHANGING = "OnStateChanging()";
public const string ON_STATE_CHANGED = "OnStateChanged()";
public const string TEMPERATURE_INFO = "The temperature is {0} °C" +
" and state name is {1}!";
}
常量类,维护一些在本案例中经常使用到的字符串或数值。在实际开发过程中不应当有此类,应该将相应的常量放在具体要使用的类中。2017年,阿里发布《阿里巴巴Java开发手册》,其中有一节提到此准则,所有使用面向对象编程语言的开发人员都应当遵从。
public class UnReachableException : Exception {
public UnReachableException()
: base("Absolute zero cannot be reached!") {
}
public UnReachableException(string message, Exception innerException)
: base(message, innerException) {
}
}
绝对零度无法到达异常类UnReachableException,进行简单的异常处理。
public class Program {
private static Water _water = new Water();
public static void Main(string[] args) {
try {
_water.Increase(68)
.Drink()
.Increase(82)
.Drink()
.Reduce(90)
.Drink()
.Reduce(0)
.Reduce(80)
.Drink()
.Reduce(300)
.Drink();
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
Console.WriteLine(Const.LINE_BREAK);
}
Console.ReadKey();
}
}
以上是本案例的调用方代码,升温方法Increase、降温方法Reduce和喝水方法Drink经过特别的处理以支持方法链。以下是这个案例的输出结果:
OnStateChanging()
The temperature is 0 °C and state name is Solid!
OnStateChanged()
The temperature is 68 °C and state name is Liquid!
--------------------------------------------------
You can drink!
--------------------------------------------------
OnStateChanging()
The temperature is 68 °C and state name is Liquid!
OnStateChanged()
The temperature is 150 °C and state name is Gas!
--------------------------------------------------
You can not drink!
--------------------------------------------------
OnStateChanging()
The temperature is 150 °C and state name is Gas!
OnStateChanged()
The temperature is 60 °C and state name is Liquid!
--------------------------------------------------
You can drink!
--------------------------------------------------
OnStateChanging()
The temperature is 60 °C and state name is Liquid!
OnStateChanged()
The temperature is -20 °C and state name is Solid!
--------------------------------------------------
You can not drink!
--------------------------------------------------
Absolute zero cannot be reached!
--------------------------------------------------
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
状态模式(State Pattern)是一种设计模式,它在处理对象状态和行为的关系时提供了一些重要的优点:
状态模式是一种有助于管理对象状态和行为的优秀设计模式,它提供了松耦合、可扩展和易维护的解决方案,可以用于处理复杂的状态机和对象行为。
虽然状态模式(State Pattern)在某些情况下非常有用,但它也具有一些缺点和局限性,需要在使用时考虑:
状态模式在某些情况下非常有用,特别是对于复杂的状态机和对象行为管理。然而,在简单的情况下,引入状态模式可能会显得过于繁琐。开发人员需要在使用状态模式时权衡其优点和缺点,确保选择合适的设计模式来满足系统需求。
状态模式(State Pattern)在以下情况下特别适用:
状态模式适用于那些具有多个状态且状态之间存在明确转换规则的场景,它能够帮助简化代码、提高可维护性,并支持动态切换对象的行为。它是一种有力的设计模式,用于处理对象状态