Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 持久性设计模式_C#_Design Patterns - Fatal编程技术网

C# 持久性设计模式

C# 持久性设计模式,c#,design-patterns,C#,Design Patterns,我正在从事一个项目,我正在努力从一种持久性模式转移到另一种模式 我已经查看了企业应用程序体系结构模式、设计模式,以及MSDN文章中的帮助。我们当前的模式是MSDN文章中描述的活动记录模式。作为向更模块化的代码库过渡的第一步,我们正在尝试将一些业务对象(也称为表)分解为多个接口 例如,假设我有一个商店应用程序,如下所示: public interface IContactInfo { ... } public interface IBillingContactInfo: IContact

我正在从事一个项目,我正在努力从一种持久性模式转移到另一种模式

我已经查看了企业应用程序体系结构模式、设计模式,以及MSDN文章中的帮助。我们当前的模式是MSDN文章中描述的活动记录模式。作为向更模块化的代码库过渡的第一步,我们正在尝试将一些业务对象(也称为表)分解为多个接口

例如,假设我有一个商店应用程序,如下所示:

public interface IContactInfo
{
    ...
}

public interface IBillingContactInfo: IContactInfo
{
    ...
}

public interface IShippingContactInfo: IContactInfo
{
    ...

}

public class Customer: IBillingContactInfo, IShippingContactInfo
{
    #region IBillingContactInfo Implementation
    ...
    #endregion

    #region IShippingContactInfo Implementation
    ...
    #endregion

    public void Load(int customerID);
    public void Save();
}
Customer类表示Customer表中的一行。尽管Customer类是一行,但它实际上实现了两个不同的接口:IBillingContactInfo、IShippingContactInfo

历史上,我们没有这两个接口,我们只是到处传递整个客户对象,对其进行任何更改,然后保存它

这就是问题所在。现在我们有了这两个界面,我们可能有了一个控件,它获取IContactInfo,向用户显示它,并允许用户在错误时更正它。目前,我们的IContactInfo接口未实现任何Save(),以允许对其进行持久更改


在不完全切换到其他众所周知的解决方案的情况下,有什么好的设计模式可以绕过这一限制的建议吗?我真的不想在我所有的接口上都添加Save()方法,但这可能是我最终需要做的。

您可以简单地向继承的接口添加
Save()
方法约束,只需使用
IContactInfo
实现一个
IPersistable
接口,该接口强制执行
Save()
方法。因此,任何具有
IContactInfo
的内容也具有
IPersistable
,因此必须具有
Save()
。您还可以使用
ILoadable
Load(int-ID)
-或者使用语义正确性更高的
iRetrieve
Retrieve(int-ID)


这完全取决于您如何使用
ContactInfo
对象。如果这与您的使用不符,请留下评论/更新您的问题,我将重新考虑我的答案。

您计划使用多少种不同的
IContactInfo
衍生工具

也许我没有抓住重点,但我认为使用名为
ContactInfo
的类会做得更好,在每个
Customer
中使用
BillTo
ShipTo
实例。由于您的
ishipingcontactinfo
IBillingContactInfo
接口继承自同一
IContactInfo
接口,因此您的
Customer
类将通过一组字段同时满足
IContactInfo
基本接口。这将是一个问题

最好将这些实例分开。然后,保存您的
客户
要简单得多

您是否计划将序列化用于持久化或保存到数据库或其他方面

为Customer和ContactInfo使用具体类型肯定会涵盖前两种

(平面文件适用于您的原始设置,但我希望您不打算这样做。)


我认为这一切都取决于你期望得到多少IContactInfo的衍生物。在你的图表中增加一点地形并没有什么错。如果这意味着一条记录包含多个部分(您的示例),或者是一对多关系(我的示例),或者是多对多关系在联接表中列出了类型(ShipTo、BillTo等)。多对多确实减少了客户和各种ContactInfo类型之间的关系,但当您需要具体关系时,它会在应用程序开发中为场景带来开销

也许我没抓住重点。。但是您不能在
IContactInfo
界面中包含
Load
Save
方法吗?如果控件需要保存()的功能,为什么要使用IContactInfo?也许创建一个SavableContactInfo类型来实现IContactInfo,然后让控件获取一个SavableContactInfo对象怎么样?@SimonWhitehead我可以包含一个加载和保存,但有将近100个表,我们可能会将其分解到接口中。我想确保我没有遗漏更明显、更好的东西在我开始走这条路之前就已经测试过了。@itsme86好主意。当我在考虑如何创建一个SavableContactInfo类时,你触发了我的一个想法。我想任何实现IContactInfo的对象都会有自己的持久化逻辑,因此在接口上保存可能最有意义。多个表有可能实现IContactInfo,每个表都需要自己的保存实现返回到原始表,因此我无法很容易地将保存功能重构为具体实现。@MarkRucker您可以更进一步,拥有一个ISave接口。实现ISave接口的任何东西都可以持久化。另一种选择是使用Save方法的多个接口。在我的书中,这将违反干燥原则。谢谢你的回答。我们通过保存到数据库来进行持久化,尽管您是对的,我们可以将此实现抽象出来,并使用缓存和序列化等其他功能。为了简化持久性,我们使用反射将数据库列直接移动到属性,反之亦然。创建多层对象会更好,但会使我们的ORM策略复杂化,所以我们使用接口。此外,我不认为具体类型比接口更能解决我的问题?您介意详细说明一下吗,因为我没有提到。@MarkRucker,实现从同一接口继承的两个接口肯定会在将对象映射到表时产生问题,并且接口不会序列化。阿尔索