关闭。这个问题需要更多 focused .它目前不接受答案。
想改进这个问题?更新问题,使其仅关注一个问题 editing this post .
5年前关闭。
Improve this question
最佳答案
首先,我建议您阅读抽象工厂模式,例如 here .现在我将尝试解释为什么你会使用这种模式。
通常,如果您使用工厂模式,您将在工厂中创建对象。当您有多个给定类(或多个类)的实现时,就会出现问题。现在,这些多个实现被分组。您将使用 Abstract Factory pattern
当您有工厂时,但您想将创建对象分组到每个组。
好的,上面的解释可能不是很清楚,所以我举个例子。
假设您有一个带有数据代理的类库。数据代理为您提供访问和存储不同数据的方法。当然,有多种存储数据的方法。例如:在数据库中、在 XML 文件中、通过服务、.对于这些可能的方式中的每一种,您都希望拥有数据代理。现在的问题是,您不希望有人将 DataAgentA 用于 XML 文件和 DataAgentB 用于数据库(假设我们有实体 A 和 B)。用户应该只使用一个存储引擎。
让我向您介绍抽象工厂模式。
您将确保用户不能直接实例化您的数据代理,但他们必须将这些数据代理从工厂中取出。 (一个额外的优势是,当您使用例如数据库 (EF) 时,您可以进行内部连接以确保您的数据代理使用相同的上下文等)我们如何实现这一点?我们将数据代理的构造函数设置为“内部”。除此之外,我们为每个存储引擎创建不同的工厂。现在,由于这些工厂都做同样的事情,我们也有这些接口(interface)(就像我们的数据代理一样,因为它们都必须做同样的事情,对吧!?)。
下面我们有我们的接口(interface)。基本上这是工厂模式,但只是现在我们谈论的是接口(interface)而不是类。
public interface IAgentA
{
// Add some methods here!
}
public interface IAgentB
{
// Add some methods here!
}
public interface IAgentFactory
{
IAgentA CreateAgentA();
IAgentB CreateAgentB();
}
现在对于这两个代理,我们有两种可能的实现,一种用于 XML,另一种用于数据库存储(再次说明:这是一个示例,您可以拥有任意数量的实现类型)。这些实现看起来像这样(见下文)。请注意,我创建了构造函数
internal
!这是该代码块之后的部分所必需的。public class AgentA_Xml : IAgentA
{
internal AgentA_Xml()
{ /* Construction here */}
// IAgentA method implementations
}
public class AgentB_Xml : IAgentB
{
internal AgentB_Xml()
{ /* Construction here */}
// IAgentB method implementations
}
public class AgentA_Database : IAgentA
{
internal AgentA_Database()
{ /* Construction here */}
// IAgentA method implementations
}
public class AgentB_Database : IAgentB
{
internal AgentB_Database()
{ /* Construction here */}
// IAgentB method implementations
}
现在因为构造函数是内部的。这导致您无法在程序集之外实例化这些类,这通常是您对这些情况所做的事情。现在我们必须创建我们的工厂。
public class XMLAgentFactory : IAgentFactory
{
public IAgentA CreateAgentA()
{
return new AgentA_Xml();
}
public IAgentB CreateAgentB()
{
return new AgentB_Xml();
}
}
public class DatabaseAgentFactory : IAgentFactory
{
public IAgentA CreateAgentA()
{
return new AgentA_Database();
}
public IAgentB CreateAgentB()
{
return new AgentB_Database();
}
}
由于两家工厂都实现了
IAgentFactory
界面,用户可以轻松更改AgentFactory
实现(在这种情况下,如果他想要使用不同的存储引擎),而不必更改他编写的任何其他代码(针对代理),只要他针对接口(interface)进行编程(显然)。以上解释希望能回答您的问题(1)和(2)。
- Good example for Abstract factory pattern in C#?
- and what are advantages of Abstract factory pattern in c#?
回答你的问题(3)。
- How use C# generics with Abstract factory pattern?
您仍然可以使用泛型,当您使用抽象工厂模式时,这不会有任何改变。当然,您必须创建通用工厂方法(create 方法),但这不应该有任何问题。
回答你的问题(4)。
- How does unit test with Abstract factory pattern?
就像您对任何其他类进行单元测试一样。只有一件事会有所不同。
由于您可能还想测试您的类的构造函数(可能还有其他内部方法),因此您需要使内部构造函数(方法)对您的单元测试项目可见(并且您不想将
internal
更改为public
)。这很容易通过将以下行添加到您的 AssemblyInfo.cs
中来完成。您的项目文件(您的工厂和类所在的项目):[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")]
您可以在 MSDN 上找到有关 InternalsVisibleTo 属性的更多信息(和备注)。 .
我希望这种回答你的问题。
关于design-patterns - 抽象工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10513086/