好的,我需要一些帮助。
这与“无法使用接口(interface)强制执行构造函数/静态方法” 问题相同。
那么正确的 OO 设计是什么??
我有一组数据实体( Entity Framework 的东西),我为此编写了部分类方法来转换为 XML(XElement 对象)/从 XML(XElement 对象)。
我有一个实例方法来“保存”XML:
// Convert entity to XML
public XElement ToXml() {}
...我有一个构造函数来“读取”XML:
// Create entity from XML constructor.
public MyEntity(XElement) {}
或者,我可以使用静态工厂方法来“读取”XML:
public static MyEntity ParseXml(XElement) {}
困境:
我可以创建一个接口(interface)来强制执行“保存”
ToXml()
方法,但如果它只能解决一半的问题,那又有什么用呢?接口(interface)不能强制执行任何一种“加载”方法。我可以依靠自己的良好意愿来创建这些方法,而无需任何形式的契约(Contract)。
我可以创建一个充满冗余方法的静态类,例如
XmlToEntity1()
和XmlToEntity2()
等...(现在我已经描述了一个很好的“泛型”问题。)但是,特定的转换代码(特定于每个实体)会为每个创建单独的方法或开关/案例,并且似乎属于实体类,而不属于其他类,不是吗?
如果有经验的 C# 编码人员能够针对这个常见问题展示一个好的设计,我想我会从中学到很多东西。
7 月 4 日快乐!
可能的解决方案1
具有两个静态泛型方法的单个 XmlSerializer
类:
public static T Deserialize<T>(XElement xml) {}
public static XElement Serialize<T>(T entity) {}
- 优点:只有一个类(不需要接口(interface))
- 优点:将序列化责任与实体类分开。
- 缺点:对于支持的每种实体类型,仍然需要单独的方法或 switch/case block 。
- 缺点:?不可扩展——每次更改或添加/删除实体时都必须修改此类。
可能的经验教训?
“不能为构造函数和静态方法使用接口(interface)”问题可能是以下症状:
- 违反 SRP(单一职责原则)。
- 违反 SoC(关注点分离)原则。
最佳答案
使用简单的实例方法从 XML 加载怎么样?您的界面将类似于:
public interface XmlSerializableEntity
{
XElement Serialize(); // or ToXml() if you prefer..
void Deserialize(XElement e); // or Load() or something like that..
}
或者您可以使用通用解决方案:
public interface Serializable<T>
{
T Serialize();
void Deserialize(T e);
}
缺点是您必须在加载之前初始化实体对象,这可能意味着您将拥有一个处于无效状态的对象。但我确实相信这是一种常见的模式。
关于C# "can' t specify constructor/static method in interface"问题所需的正确解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6577677/