[英]C# State-Pattern private ChangeState
I´m trying to implement the State-Pattern using C# following this page .我正在尝试在此页面之后使用 C# 实现状态模式。 Here the UML of a State-Pattern.
这里是状态模式的 UML。
The State it self sets the new sate in the context class. State 在上下文 class 中自行设置新状态。 But here is my problem: I want to use Interfaces but the ChangeState-Method should not be present to the client but available for the state.
但这是我的问题:我想使用接口,但 ChangeState-Method 不应该出现在客户端,但可用于 state。 But I don´t know how to implement a private interface within a class which I present for the client.
但我不知道如何在我为客户提供的 class 中实现私有接口。
Here my first shot of the pattern Context-Class which should implement the IChangeState interface:这是我应该实现 IChangeState 接口的模式 Context-Class 的第一张照片:
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();
}
}
And the IChangeState interface which does the main trick but should not be visibile to the client.和 IChangeState 接口,它起到了主要作用,但对客户端不应该是可见的。 So I assumed to make it private but how to share this interface with the state or even implement it?
所以我假设它是私有的,但是如何与 state 共享这个接口,甚至实现它?
public interface IChangeState
{
void ChangeState(IState state);
}
And at least the States:至少在美国:
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();
}
}
You can make the IChangeState internal if the client is in a different assembly.如果客户端位于不同的程序集中,您可以将 IChangeState 设为内部。 The solution should look as follow:
解决方案应如下所示:
//Start Assembly MyAssembly1
public interface IContext
{
string Input { get; set; }
void DoTransition();
}
internal interface IChangeState
{
void ChangeState(IState state);
}
public class Context : IContext, IChangeState
{
public string Input { get; set; }
private IState _state;
public void DoTransition()
{
_state.DoTransition();
}
void IChangeState.ChangeState(IState state) {
_state = state;
}
}
public interface IState
{
void DoTransition();
}
internal abstract class AbstractState : IState
{
private IChangeState _stateChanger;
public AbstractState(IChangeState stateChanger) {
_stateChanger = stateChanger;
}
public virtual void DoTransition()
{
_stateChanger.ChangeState(new NextState(_stateChanger));
}
}
internal class NextState : AbstractState
{
public NextState(IChangeState stateChanger)
: base(stateChanger)
{ }
public override void DoTransition()
{
base.DoTransition();
}
}
// End Assembly MyAssembly1
// Start Assembly MyAssembly2
public class AClient {
private IContext _context;
public AClient(IContext context)
{
_context = context;
// ((Context)_context).ChangeState is not visible
}
}
// End Assembly MyAssembly2
In this way the AClient class cannot see the methods exposed by the interface IChangeState, even if you inject a Context object instead of the IContext interface这样AClient class就看不到接口IChangeState暴露的方法了,即使你注入一个Context object而不是IContext接口
I´ve solved the issue with partial classes.我已经用部分类解决了这个问题。 There are all States and there Interfaces private so the Context-Class has access to all the interfaces and classes but the client not.
所有的状态和接口都是私有的,所以上下文类可以访问所有的接口和类,但客户端不能。 The IChangeState-Interface I´ve implemented in a seperate Class which is also private so only the Context can change the state.
我已经在单独的 Class 中实现了 IChangeState-Interface,它也是私有的,因此只有上下文可以更改 state。 Example as followed:
示例如下:
public interface IContext
{
string Input { get; set; }
void DoTransition();
}
public partial class Context : IContext
{
public string Input { get; set; }
private IChangeState _stateChanger;
public void DoTransition()
{
_stateChanger.CurrentState.DoTransition();
}
}
public partial class Context
{
private interface IChangeState
{
IState CurrentState { get; }
void ChangeState(IState state);
}
}
public partial class Context
{
private class ChangeState
{
IState CurrentState { get; private set; }
void ChangeState(IState state)
{
CurrentState = state;
}
}
}
public partial class Context
{
private interface IState
{
void DoTransition();
}
}
public partial class Context
{
private abstract class AbstractState : IState
{
private IChangeState _stateChanger;
public AbstractState(IChangeState stateChanger) => _stateChanger = stateChanger;
public virtual void DoTransition()
{
_stateChanger.ChangeState(new NextState(_stateChanger));
}
}
}
public partial class Context
{
private class NextState : AbstractState
{
public NextState(IChangeState stateChanger)
: base(stateChanger)
{ }
public override void DoTransition()
{
base.DoTransition();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.