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
Design patterns 抽象工厂模式 C#中抽象工厂模式的好例子 C#中抽象工厂模式的优点是什么 如何将C#泛型与抽象工厂模式结合使用 如何使用抽象工厂模式进行单元测试_Design Patterns_C# 4.0_Architecture_Abstract Factory - Fatal编程技术网

Design patterns 抽象工厂模式 C#中抽象工厂模式的好例子 C#中抽象工厂模式的优点是什么 如何将C#泛型与抽象工厂模式结合使用 如何使用抽象工厂模式进行单元测试

Design patterns 抽象工厂模式 C#中抽象工厂模式的好例子 C#中抽象工厂模式的优点是什么 如何将C#泛型与抽象工厂模式结合使用 如何使用抽象工厂模式进行单元测试,design-patterns,c#-4.0,architecture,abstract-factory,Design Patterns,C# 4.0,Architecture,Abstract Factory,首先,我建议您阅读抽象工厂模式,例如。现在我将尝试解释为什么要使用这种模式 通常,如果使用Factory模式,将在Factory中创建对象。当给定类有多个实现时,就会出现问题。现在,这些多个实现被分组。当您有工厂时,您将使用抽象工厂模式,但您希望将对象的创建按组分组 好的,上面的解释可能不完全清楚,所以我给你们举个例子 假设您有一个带有数据代理的类库。数据代理为您提供访问和存储不同数据的方法。当然,有多种存储数据的方法。例如:在数据库中,在XML文件中,通过服务。对于这些可能的方法中的每一种,您

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

通常,如果使用Factory模式,将在Factory中创建对象。当给定类有多个实现时,就会出现问题。现在,这些多个实现被分组。当您有工厂时,您将使用
抽象工厂模式
,但您希望将对象的创建按组分组

好的,上面的解释可能不完全清楚,所以我给你们举个例子

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

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

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

下面是我们的界面。基本上这是工厂模式,但直到现在我们才开始讨论接口,而不是类

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

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
实现(如果他在本例中希望使用不同的存储引擎),而无需更改他编写的任何其他代码(针对代理),只要他针对接口编程(显然)

以上解释有望回答您的问题(1)和(2)

  • C#中抽象工厂模式的好例子
  • c#中抽象工厂模式的优势是什么
  • 回答你的问题(3)

  • 如何将C#泛型与抽象工厂模式结合使用
  • 您仍然可以使用泛型,当您使用抽象工厂模式时,这不会有任何变化。当然,您必须创建泛型工厂方法(create方法),但这应该不会有任何问题

    回答你的问题(4)

  • 如何使用抽象工厂模式进行单元测试
  • 与单元测试任何其他类一样。只有一件事是不同的

    由于您可能还希望测试类的构造函数(可能还有其他内部方法),因此需要使内部构造函数(方法)对单元测试项目可见(并且您不希望将
    内部
    更改为
    公共
    )。通过在项目(工厂和类所在的项目)的
    AssemblyInfo.cs
    文件中添加以下行,可以轻松完成此操作:

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


    我希望这类问题能回答您的问题。

    问题应该更具体。看起来,你不想找到关于你的主题的信息,只想有人向你解释这个主题。你也可以研究其他模式,而不是抽象工厂模式。这个答案的可能重复是人们经常谈论的隐藏的宝石之一。解释得很好。非常感谢。
    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();
        }
    }
    
    [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")]