State状态模式
1、简介
在日常开发中,某些对象的状态如果发生改变,对应的行为也将发生改变,那么如何在运行时根据对象的状态动态的改变对象的行为,同时不产生紧耦合关系(即使用if else或者swith所带来的紧耦合关系).即对扩展开放,对修改关闭一开闭原则.
2、案例
假设用户提出了一个需求,有三类文档对象,他们都由Read、Update、Write的功能,且分为只读文档、只改文档、只写文档,且在编写代码时,他们的RUW(R-Read)功能各不相同,即每一类的状态文档,在运行时,他们的Read、Write、Update的代码逻辑各不相同,这个时候该如何通过状态模式编写代码,很显然,如果不用State模式,可以通过if else或者swith可以很轻松的完成需求.但是那样的代码耦合度高,且修改时,代价太大,容易影响现有代码的逻辑,给测试增加压力,因为你每一次对单一文档对象的修改都会影响其他所有文档对象的运行.下面使用State状态模式来完成这个需求.
3、代码实战
public static void Main(string[] args) { var manager = new DocumentManage(new ReadOnlyDocument()); var content=manager.Read(); Console.WriteLine(content); Console.ReadKey(); } /// <summary> /// 状态文档方法约束接口 /// </summary> public interface IStatedDocument { string Read(); void Write(); void Update(); } /// <summary> /// 抽象状态文档对象 /// </summary> public abstract class StatedDocument: IStatedDocument { public abstract string Read(); public abstract void Write(); public abstract void Update(); } /// <summary> /// 只读文档对象 /// </summary> public class ReadOnlyDocument : StatedDocument { public override string Read() { return "只读文档内容"; } public override void Update() { throw new Exception("只读文档,无法修改其内容"); } public override void Write() { throw new Exception("只读文档,无法写入内容"); } } /// <summary> /// 文档管理对象 /// </summary> public class DocumentManage: IStatedDocument { private StatedDocument _statedDocument; /// <summary> /// 可以通过构造函数传入具体的文档,或者Set方法 /// </summary> public DocumentManage(StatedDocument statedDocument) { _statedDocument = statedDocument; } public string Read() { return _statedDocument.Read(); } public void Update() { _statedDocument.Update(); } public void Write() { _statedDocument.Write(); } }
ok,可以看到state状态模式很好的完成了需求,而且每当用户提出一种新的需求,如编写一个只读只写文档,你就可以通过扩展类的方式,通过编写一个只读只写文档类,来完成他的需求,而且每次发布模块,只需要测新类型的功能是否ok,不需要测其他的功能,因为状态模式是符合开闭原则,对扩展方法,对修改关闭.且所有的上下文共享一个State对象,各个状态文档对象通过子类的方法展现,如果状态发生改变,那么其状态下的方法全都会改变.