design-patterns - 抽象工厂模式

标签 design-patterns c#-4.0 architecture abstract-factory

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question



  • C# 中抽象工厂模式的好例子?
  • C#中抽象工厂模式的优点是什么?
  • 如何在抽象工厂模式中使用 C# 泛型?
  • 如何使用抽象工厂模式进行单元测试?
  • 最佳答案

    首先,我建议您阅读抽象工厂模式,例如 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)。

    1. Good example for Abstract factory pattern in C#?
    2. and what are advantages of Abstract factory pattern in c#?


    回答你的问题(3)。

    1. How use C# generics with Abstract factory pattern?


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

    回答你的问题(4)。

    1. 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/

    相关文章:

    php - 我应该如何处理预期的错误?例如。 "username already exists"

    java - Java API 设计中的面向对象事件日志记录

    c# - .NET 2.0等效于C#扩展方法

    c# - 如何使用 Nunit 断言每个集合项

    entity-framework - Entity Framework 最重要的限制

    ios - 应用程序设计 : UITabBarController inside UINavigationController

    java - 需要将Java编写的加密镜像到C#中

    .net - IT HIT WEBDAV Word 文档以只读方式打开

    php - Mysql VIEWS 与 PHP 查询

    django - Javascript MVC 框架和服务器端框架