C#状态模式中ChangeState方法私有可见性的实现疑问
C#状态模式:隐藏状态切换接口的实现方案
问题背景
我正在实现状态模式,状态类需要修改Context的状态,但要求ChangeState方法仅对状态类可见,不能暴露给客户端。我尝试用接口分离,但不知道如何在对外暴露的Context类中实现私有接口供状态类使用。
以下是我的初步代码:
对外暴露的Context接口与类
public interface IContext { string Input { get; set; } void DoTransition(); } public class Context : IContext { public string Input { get; set; } private AbstractState _state; public void DoTransition() { _state.DoTransition(); } }
状态切换接口(需隐藏)
public interface IChangeState { void ChangeState(IState state); }
状态类实现
public interface IState { void DoTransition(); } public abstract class AbstractState : IState { private IChangeState _stateChanger; public AbstractState(IChangeState stateChanger) => _stateChanger = stateChanger; public virtual void DoTransition() { _stateChanger.ChangeState(new NextState(_stateChanger)); } } public class NextState : AbstractState { public NextState(IChangeState stateChanger) : base(stateChanger) { } public override void DoTransition() { base.DoTransition(); } }
解决方案
在C#中可以通过显式接口实现来隐藏IChangeState的方法,这样客户端通过IContext接口无法访问ChangeState,只有状态类持有IChangeState引用时才能调用。
修改后的完整代码如下:
调整后的Context类(显式实现IChangeState)
public interface IContext { string Input { get; set; } void DoTransition(); } public interface IChangeState { void ChangeState(IState state); } public class Context : IContext, IChangeState { public string Input { get; set; } private AbstractState _state; // 构造函数初始化初始状态,将自身作为IChangeState传入 public Context() { _state = new InitialState(this); } public void DoTransition() { _state.DoTransition(); } // 显式实现IChangeState,对外不可见 void IChangeState.ChangeState(IState state) { if (state is AbstractState abstractState) { _state = abstractState; } } }
状态类保持不变(可按需扩展)
public interface IState { void DoTransition(); } public abstract class AbstractState : IState { protected IChangeState StateChanger { get; } public AbstractState(IChangeState stateChanger) { StateChanger = stateChanger; } public virtual void DoTransition() { // 示例:切换到下一个状态 StateChanger.ChangeState(new NextState(StateChanger)); } } public class InitialState : AbstractState { public InitialState(IChangeState stateChanger) : base(stateChanger) { } public override void DoTransition() { // 初始状态的切换逻辑 StateChanger.ChangeState(new NextState(StateChanger)); } } public class NextState : AbstractState { public NextState(IChangeState stateChanger) : base(stateChanger) { } public override void DoTransition() { // 下一个状态的切换逻辑,比如切换回初始状态 StateChanger.ChangeState(new InitialState(StateChanger)); } }
关键说明
- 显式接口实现:
void IChangeState.ChangeState(...)这种写法让方法只能通过IChangeState类型的引用访问,客户端拿到IContext实例时看不到这个方法。 - 状态类依赖IChangeState:状态类通过构造函数注入
IChangeState,仅能调用状态切换方法,无法访问Context的其他公开成员,符合单一职责原则。 - 客户端使用方式:客户端仅需依赖
IContext接口,完全感知不到IChangeState的存在:
// 客户端代码 IContext context = new Context(); context.Input = "test"; context.DoTransition(); // 此处无法调用ChangeState方法,因为IContext中未定义
内容的提问来源于stack exchange,提问作者Felix Arnold
相关产品推荐
相关产品推荐

