我对这一切都很陌生,所以这可能是OOP 101,但我无法理解它,假设以下C#代码存在于程序集中:
internal interface IDataStore
{
void Store(string name, object data);
object Retrieve(string name);
}
internal class DBStore : IDataStore
{
public DBStore(string connection) { }
public void Store(string name, object data) { }
public object Retrieve(string name) { }
}
public class GizmoManager
{
public GizmoManager(IDataStore dataStore) { }
// Other stuff
}
public class WidgetManager
{
public WidgetManager(IDataStore dataStore) { }
// Other stuff
}
如果第二个程序集试图创建一个GizmoManager和一个WidgetManager,它就不能,因为它无法获取DBStore(因为它是内部的而不是公共的)。
以下不适用AFAICS:
这可能非常明显,但我看不到它。如何克服这一矛盾?
TIA。
答案 0 :(得分:3)
只需将界面IDataStore
公开。这样,客户端可以使用他们自己创建的模拟对象来实例化您的WidgetManager
和GizmoManager
类。
实现 Factory 类设计模式,以允许通过客户端代码创建GiszmoManager
和WidgetManager
对象。这样,客户端代码永远不会创建DBStore
对象,因此他们永远不会绕过您的经理。
顺便说一句为什么要烦恼封装?如果您在专有框架业务中,这可能有意义,但除此之外,YAGNI。
答案 1 :(得分:1)
将IDataStore和DBStore公开,但将DBStore构造函数设为内部。然后可以说,1完全控制DBStores何时被实例化,但程序集2能够访问并传入DBStore。
我想你会在程序集1中想要一个工厂,它限制了创建的DBStore实例的数量或配置。
答案 2 :(得分:0)
您可以创建接口和类public
,但可以使方法直接访问数据库internal
。这样,您可以实例化DBStore
的实例,而不允许对不允许其他程序集的方法进行任何访问。
internal
方法仅对同一程序集中的类可见。
我宁愿检查是否无法组装对象而无需每次都实例化DBStore
。也许工厂模式或依赖注入?然后,您可以将您的界面公开,并让第一个程序集中的工厂实例化它们。这不会影响可测试性,但会减少您创建的对象实例。较少new XYZ()
次陈述更好......
答案 3 :(得分:0)
让DBStore公开,但是要让你不想公开私人或内部的所有成员。然后... 选项1:从IDataStore中删除您不希望在程序集外部访问的所有成员,并将IDataStore公开。 选项2:将IDataStore重命名为IDataStoreInternal,并使其继承自没有成员的新公共IDataStore接口(或者只是要在外部公开的成员)。
答案 4 :(得分:0)
我喜欢这两个:
- 不要将IDataStore传递给GizmoManager和WidgetManager 构造函数。不好因为它减少了 可测试性(你不能轻易传入 一个MockDataStore)。
- 与工厂做一些神奇的事情。似乎没有解决任何问题,因为 你需要传递相同的IDataStore 同时使用GizmoManager和WidgetManager 因此客户端组件仍然 需要将IDataStore分配给 变量(它不能因为 IDataStore是内部的。
为了解决可测试性但隐藏实现,公共接口应该只提供商店是否应该是实时的,可测试的,预生产等的选项。因此,您可以将正确的IDataStore构造的责任委托给程序集内的另一方。例如。工厂概念,只允许您设置“测试”,“部署”,“调试”等。在给定“模式”设置的情况下,使用默认构造函数(或单例或其他)在工厂内部引用正确的存储。 / p>