C# 如何在NModel中封装状态变量?
我有一个模型程序,表示沿服务器链的消息流:C# 如何在NModel中封装状态变量?,c#,nmodel,C#,Nmodel,我有一个模型程序,表示沿服务器链的消息流: public class MyModel { static bool x_send_msg1 = false; // has X sent msg1? static bool y_recv_msg1 = false; // has Y received msg1? static bool y_send_msg1 = false; // has Y sent msg1? static bool z_send_msg1 =
public class MyModel
{
static bool x_send_msg1 = false; // has X sent msg1?
static bool y_recv_msg1 = false; // has Y received msg1?
static bool y_send_msg1 = false; // has Y sent msg1?
static bool z_send_msg1 = false; // has Z received msg1?
// (etc for more servers and more messages)
[Action]
static void YSendMsg1()
{
// Y sends Msg1 to Z
y_send_msg1 = true;
z_recv_msg1 = true;
}
static bool YSendMsg1Enabled()
{
// in the simplest case, this can happen whenever Y has received the
// message but not yet forwarded it
return y_recv_msg1 && !y_send_msg1;
}
}
还有更多的信息。每个服务器和消息类型的Enabled()逻辑稍有不同,但状态相似,因此我想通过编写以下内容来封装它:
class State
{
public bool send_msg1 = false;
public bool recv_msg1 = false;
}
public static State X = new State();
public static State Y = new State();
然后在我的操作中使用封装状态:
[Action]
static void YSendMsg1()
{
// instead of y_qqq above, now we can write Y.qqq:
Y.send_msg1 = true;
Z.recv_msg1 = true;
}
static bool YSendMsg1Enabled()
{
return Y.recv_msg1 && !Y.send_msg1;
}
但是,NModel不允许我以这种方式使用对象来保存状态。是否有其他方法可以避免定义重复的布尔值组,链中的每台服务器一个布尔值组?我认为观察者模式可能会在这方面对您有所帮助-除了风格问题之外,如问题所示封装状态的主要好处是减少必须编写和读取的代码量。不必编写(#服务器*#消息)声明,只需要(#服务器+#消息) 通过使用NModel的内置
Set
类跟踪每条消息的状态,同样可以减少代码(相应地提高可读性并减少腕管综合征)。名为send\u msg1
的集合包含已发送msg1
的所有服务器的名称:
public class MyModel
{
static set<int> send_msg1 = set<int>.EmptySet; // has server #n sent msg #1?
static set<int> recv_msg1 = set<int>.EmptySet; // has server #n received msg #1?
// (etc for more messages)
static int X = 1;
static int Y = 2;
// (etc for more server names)
[Action]
static void YSendMsg1()
{
// Y sends Msg1 to Z
send_msg1 = send_msg1.Add(Y);
recv_msg1 = recv_msg1.Add(Z);
}
static bool YSendMsg1Enabled()
{
// in the simplest case, this can happen whenever Y has received the
// message but not yet forwarded it
return recv_msg1.Contains(Y) && !send_msg1.Contains(Y);
}
}
公共类MyModel
{
静态set send_msg1=set.EmptySet;//服务器#n已发送消息#1吗?
static set recv_msg1=set.EmptySet;//服务器#n是否接收到消息#1?
//(等以获取更多信息)
静态int X=1;
静态int Y=2;
//(等以获取更多服务器名称)
[行动]
静态void YSendMsg1()
{
//Y向Z发送Msg1
send_msg1=send_msg1.Add(Y);
recv_msg1=recv_msg1.Add(Z);
}
静态bool YSendMsg1Enabled()
{
//在最简单的情况下,只要Y收到
//消息,但尚未转发
返回recv_msg1.Contains(Y)和&!send_msg1.Contains(Y);
}
}
(可以进一步减少代码事件的数量,例如,通过使用集合映射将所有内容保存在单个变量中。但是,将状态空间分开的一个优点是,它可以在模型查看器中生成更清晰的状态摘要。)因为我写了上面的答案,我已经知道了另一个更接近我最初寻找的解决方案 要将对象与实例变量一起使用,可以从
LabeledInstance
派生,如下所示。应使用静态Create()
方法分配实例,并应使用重写的Initialize()
方法初始化字段
(您也可以对操作使用实例方法,但要执行此操作,必须为类指定一个域;该域的名称应对应于包含该类所有当前实例的静态集。)
在幕后,NModel将把这个类转换成一组映射,每个映射对应于类中的每个实例变量。这些映射中的键将为类名的实例编制索引,例如状态(1)
。在MVC工具中,这可能有点难以理解,因此您可能还希望保留某种实例变量,其中包含对象状态的清晰、合并摘要
class State : LabeledInstance<State>
{
public override void Initialize()
{
send_msg1 = false;
recv_msg1 = false;
}
public bool send_msg1;
public bool recv_msg1;
}
public static State X = State.Create();
public static State Y = State.Create();
类状态:标签状态
{
公共覆盖无效初始化()
{
send_msg1=false;
recv_msg1=假;
}
公共bool send_msg1;
公共图书馆;
}
公共静态状态X=State.Create();
公共静态Y=State.Create();
如果NModel引擎不让我分析简单的类/结构,为什么您认为它会让我分析多类模式?