好的,我需要一些帮助。
这是旧的“不能使用接口强制构造函数/静态方法”的问题。
什么是合适的设计呢?
我有一组数据实体(Entity Framework的东西),我为此编写了部分类方法来转换为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) {}
困境:
我可以创建一个强制执行“保存”ToXml()
方法的界面,但如果它只能解决一半问题呢?接口无法强制执行任何“加载”方法。
我可以依靠自己的良好意图在没有任何合同的情况下创建这些方法。
我可以创建一个充满冗余方法的静态类,如XmlToEntity1()
和XmlToEntity2()
等...(现在我已经描述了一个很好的'泛型'问题。)但是,特定的转换代码(特定于每个实体)会为每个实体创建单独的方法或switch / case,并且似乎属于实体类,而不是在其他类中,不是吗?
如果有经验的C#编码器可以为这个常见问题展示一个好的设计,我想我会从中学到很多东西。
七月四日快乐!
具有两个静态通用方法的单个XmlSerializer
类:
public static T Deserialize<T>(XElement xml) {}
public static XElement Serialize<T>(T entity) {}
“不能使用构造函数和静态方法的接口”问题可能是以下症状:
答案 0 :(得分:5)
使用简单的实例方法从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);
}
缺点是你必须在加载实体对象之前对其进行初始化,这可能意味着你的对象处于无效状态。但我相信这是一种常见的模式。
答案 1 :(得分:4)
无论如何,将存储/检索与实体分开是一个很好的设计。在OO术语中,这可以称为单一责任原则。您的实体出于某种目的而存在(可能与您的域名相关)。该实体的存储是一项单独的责任,可以独立于域进行更改。 (例如,您可以从数据库,Web服务或文件系统中检索它。)
静态方法当然不是唯一的方法。您可以在保存/检索级别创建接口,并为每个实体实现该接口。然后,您可以轻松地以通用方式使用它们,而无需担心类型。
添加一些示例代码:
interface EntityGateway<TEntity> {
TEntity Load(String id);
void Save(TEntity entity);
}
public class XEntityGateway implements EntityGateway<XEntity> {
XEntity Load(String id) { ... implementation details }
void Save(XEntity entity) { ... implementation details }
}
XEntityGateway gw = new XEntityGateway();
XEntity entity = gw.Load("SOMEID");
// modify entity
gw.Save(entity);