c# - 在 C# 中实现 "foos"的集合,它具有 "bars"的子集

标签 c# oop casting object-oriented-analysis

我正在编写一个服务器来处理从客户端到主机的不同类型的消息。这些消息具有不同的内容和长度,并且将在前面加上标识符以标识消息的类型。一些消息(例如类型 A、B 和 C)应该只在机器之间转发。其他(例如类型 D、E 和 F)需要服务器执行特定操作:即。它们不只是被转发。

(注意:两端的客户端需要区分 A、B 和 C,但服务器只需要知道转发这些消息。服务器和客户端都需要能够区分 D、E、和 F.)

我试图找到的是一个很好的面向对象范例,用于表示消息“类型”的概念。所以澄清一下,假设服务器收到一条标记为“B 类”的消息,它需要简单地将其转发给适当的客户端。但是,如果它收到标记为“Type F”的消息,它将采取不同的、特定的操作。那么我如何在我的代码中表示“类型”呢?

我想要实现的理想解决方案是这样的;和枚举“类型”,其中命令的某个子集属于“可转发”类型。显然这是不可能的,所以我想到了一个静态类 Forwardable,它继承自静态基类 Type。再次,不可能。接口(interface)是可能的,但我真的宁愿不必为了解释类型而实例化实例。

让服务器解析消息的最直接的方式是这样的:

byte[] payload = GetPayload((byte[])rawMessage);
Type message = GetMessageType((byte[])rawMessage);
if(message is Forwardable)
{
  ForwardMessage(payload);
}
else
{
  switch(message)
   case 1:
     //
     break;
   case 2:
     //
     break;
}

那么最后,表示一组类型(其中这些类型的子集是子类型)的正确 OO 方法是什么?

编辑: 在某种程度上,我觉得这应该通过定义“Types”的静态类并定义另一个继承自“Types”的名为“Forwardable”的静态类来完成。然后我可以将我的服务器接收到的内容转换为“类型”并说出 if(header is Forwardable)。但不幸的是,你不能继承静态类。 . .

最佳答案

这里有一个将内容打包的想法,以便您可以将它们传递给其他人。您可以定义一个 MessageType 来包装整个消息加载和识别,PayloadType 来包装各种有效负载和子类 - ForwardMessage、ArchiveMessage - 来识别不同类型的有效负载。

  • Message负责接受你的原始流输入,

  • PayloadType负责加载其子类和common
    字段,包括 MessageType

  • ForwardMessage、ArchiveMessage 负责任何业务逻辑,它们不负责 必须了解有关从流中加载自身的任何信息。实现 更多这些用于不同类型的有效载荷。

使用示例代码:

Message msg = Message.FromStream(stream);
PayloadType payload = msg.GetPayload();
payload.Process();

示例代码如下:

public class Message{
      public int Prefix {get; private set;}
      public byte[] RawPayload {get;private set;}

      public PayloadType GetPayload(){
        PayloadType result = null;
        switch (Prefix){ // you can also convert that to enum and use "if" for more complicated identification
          case 1: 
            result = PayloadType.FromRaw<ForwardMessage>(RawPayload);
            break;
          case 2: 
            result = PayloadType.FromRaw<ArchiveMessage>(RawPayload);
            break;
          default:
            break;
        }
      }

      public static Message FromStream(Stream s){
        Prefix = ReadTwoBytes(s);
        RawPayload = ReadToEnd(s);
      }
    }

    public abstract class PayloadType{
      public abstract MessageType MessageType {get;} // enum goes better here
      public abstract Process();

      public static T FromRaw(byte[] raw) where T: PayloadType{
        // deserialize this as you wish
        // such as:
        using (MemoryStream s = new MemoryStream(raw)){
          XmlSerializer xser = new XmlSerializer(typeof(T));
          return xser.Deserialize(s) as T; 
        }
      }
    }

    public ForwardMessage : PayloadType{
      public override MessageType MessageType {return MessageType.Forward;}
      public override Process(){
          // send this message elsewhere
      }
    }

    public ArchiveMessage: PayloadType{
      public override MessageType MessageType {return MessageType.Archive;}
      public override Process(){
           // store this message somehow
      }
    }

    public enum MessageType{
        Unknown, Formward, Archive,
    }

关于c# - 在 C# 中实现 "foos"的集合,它具有 "bars"的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16170893/

相关文章:

c# - 添加鼠标点击事件到面板

c# - 如何从gridview向数据库添加信息?

c# - 如何将 List<System.IO.FileInfo> 的类型转换为 List<string>?

javascript - 一个简单的Javascript编写方法

postgresql - varchar postgresql 的 double

c# - 如何使用SharpPcap抓取HTTP数据包

java - 如何在一些子类之间共享代码?

scala - 如何在 Scala 中将 Long 转换为 Int?

在 C 中将二维数组中的 int 转换为 void

PHP 将当前目录设置为类常量