C# 我应该在这里使用哪种设计模式
出于学习目的,我正在编写一个基于套接字的客户机/服务器应用程序。我设计了一个自定义协议,以确保我能够正确处理数据包。今天在检查代码的一些旧部分时,我意识到我创建数据包的方法包含了很多冗余代码 我有不同类型的数据包,例如ImagePacket、MessagePacket等。所有类型的创建仅在次要内容上有所不同,例如,头和分隔符的创建是相同的 为了改进这一点,我提出了如下解决方案(简化): AddData方法作为抽象方法实现,并在具体类中重写,而AddHeader和AddDelimiter则在抽象类包本身中定义 这工作得很好,我没有以前那么多重复的代码,但我不满意 将对象传递给AddData,因为没有明确说明我不能向ImagePacket构造函数提供字符串C# 我应该在这里使用哪种设计模式,c#,design-patterns,C#,Design Patterns,出于学习目的,我正在编写一个基于套接字的客户机/服务器应用程序。我设计了一个自定义协议,以确保我能够正确处理数据包。今天在检查代码的一些旧部分时,我意识到我创建数据包的方法包含了很多冗余代码 我有不同类型的数据包,例如ImagePacket、MessagePacket等。所有类型的创建仅在次要内容上有所不同,例如,头和分隔符的创建是相同的 为了改进这一点,我提出了如下解决方案(简化): AddData方法作为抽象方法实现,并在具体类中重写,而AddHeader和AddDelimiter则在抽象类
// correct
Packet myMsgPacket = new MessagePacket("hello world");
Packet myImagePacket = new ImagePacket(image);
// wrong, but will be compiled :(
Packet myChaosPacket = new ImagePacket("muaha you're doomed");
如果我必须执行一项检查,以检查所传递的数据类型是否正确,那么最终会再次出现大量愚蠢的代码。
如何在减少重复代码的同时消除上述问题?听起来您需要使用工厂模式
Packet MyPacket = MyPacketFactory.CreatePacket(Data)
MyFactory.CreatePacket
然后将返回一个IPacket
更新:根据下面的评论,我应该更清楚。您的工厂可以有许多重载的CreatePacket()方法,这些方法采用不同的数据类型
IPacket CreatePacket(Image Data) {}
IPacket CreatePacket(String Data) {}
IPacket CreatePacket(Exception Data) {}
如果您有多个只包含字符串的数据包类型(例如消息数据包、状态数据包或类似数据包),您可以创建一个枚举,指示需要哪个字符串数据包
IPacket CreatePacket(String Data, StringPacketTypesEnum PacketType) {}
在包工厂内部,您可以使用处理所有重复代码的公共函数-例如
AddDelimiter()
-这将保留您的代码Ruby on Rails使用验证来解决此问题
如果您的addData()函数在输入上调用了validate(),那么您只需在每个子类中重写validate()。我将转到返回接口的工厂模式
除此之外,您不需要将ref用于引用类型。我认为您当前的解决方案还可以。您只需将传递给
ImagePacket
构造函数的数据类型缩小为Image
类型。例如:
class ImagePacket : Packet{
public ImagePacket(Image img) : base(img){}
}
这将在复印时检查数据是否为图像。当然,如果您确实必须传递一个
对象
类型,那么这可能不起作用。问题在于数据参数可以是什么。用户想知道数据可以是字符串还是图像。也许我应该更清楚一些,但当然,它可以-我会有很多重载,采用不同的数据类型,可能还有一个额外的enum
类型用于字符串数据
class ImagePacket : Packet{
public ImagePacket(Image img) : base(img){}
}