首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >抽象工厂模式

抽象工厂模式
EN

Stack Overflow用户
提问于 2012-05-09 09:14:14
回答 1查看 65.7K关注 0票数 47
  1. 抽象工厂模式在C#?
  2. 中的好例子抽象工厂模式在C#中的优势是什么?
  3. 如何与抽象工厂模式一起使用C#泛型?
  4. 如何用抽象工厂模式进行单元测试?

<代码>G29

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-09 09:47:15

首先,我建议您阅读抽象工厂模式,例如here。现在,我将尝试解释为什么您会使用这种模式。

通常,如果您使用Factory模式,您将在Factory中创建对象。当给定类(或多个类)有多个实现时,就会出现问题。现在,对这些多个实现进行分组。当您有一个工厂时,您将使用Abstract Factory pattern,但是您希望对每个组创建的对象进行分组。

好的,上面的解释可能不是很清楚,所以我会给你们举一个例子。

假设您有一个带有数据代理的类库。数据代理提供了访问和存储不同数据的方法。当然,有多种存储数据的方法。例如:在数据库中,在XML文件中,在服务上。对于每一种可能的方法,您都希望有数据代理。现在的问题是,您不希望有人将DataAgentA用于XML文件,而将DataAgentB用于数据库(假设我们有实体A和B)。用户只应使用一个存储引擎。

让我向您介绍抽象工厂模式。

您将确保用户不能直接实例化您的数据代理,但他们必须将这些数据代理从工厂中取出。(另一个优势是,当您使用数据库(EF)时,您可以进行内部连接,以确保数据代理使用相同的上下文,等等)我们如何做到这一点?我们将数据代理的构造函数设置为“内部”。除此之外,我们为每个存储引擎创建了不同的工厂。现在,由于这些工厂都做同样的事情,我们也有这些接口(就像我们的数据代理一样,因为它们都必须做同样的事情,对吧!?)

下面我们有我们的接口。基本上这是工厂模式,但只是现在,我们谈论的不是类,而是接口。

代码语言:javascript
运行
复制
public interface IAgentA 
{
    // Add some methods here!
}

public interface IAgentB
{
    // Add some methods here!
}

public interface IAgentFactory
{
    IAgentA CreateAgentA();
    IAgentB CreateAgentB();
}

对于这两个代理,我们有两个可能的实现,一个用于XML,另一个用于数据库存储(同样:这是一个示例,您可以使用任意多个实现类型)。这些实现将如下所示(见下文)。请注意,我做了构造函数internal!这是在这个代码块之后的部分所需要的。

代码语言:javascript
运行
复制
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
}

因为构造函数是内部的。这导致您无法在程序集之外实例化这些类,这通常是对此类情况所做的操作。现在我们必须建立我们的工厂。

代码语言:javascript
运行
复制
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实现(在本例中,他想使用不同的存储引擎),而不必更改他编写的任何其他代码(针对代理),只要他针对接口进行编程(很明显)。

以上解释希望能回答你的问题(1)和(2)。

  1. 抽象工厂模式在C#?
  2. 中的好例子以及抽象工厂模式在c#?

中的优势是什么?

回答你的问题(3)。

  1. 如何使用抽象工厂模式的C#泛型?

您仍然可以使用泛型,当您使用抽象工厂模式时,这一点也不会改变。当然,您必须创建通用工厂方法( create方法),但这应该不会有任何问题。

回答你的问题(4)。

  1. 如何用抽象工厂模式进行单元测试?

就像单元测试任何其他类一样。只有一件事是不同的。

由于您可能还想测试类的构造函数(以及其他内部方法),所以需要使内部构造函数(方法)对单元测试项目可见(并且不希望将internal更改为public)。通过将以下行添加到项目的AssemblyInfo.cs文件(工厂和类所在的项目中),很容易做到这一点:

代码语言:javascript
运行
复制
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")]

您可以在InternalsVisibleTo上找到关于属性的更多信息(和备注)。

我希望这样回答你的问题。

票数 142
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10513086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档