Factory Pattern用于实例化Factory类中的类

时间:2018-03-01 04:17:18

标签: c# pattern-matching factory factory-pattern

我有一个Factory类,我根据字符串匹配实例化类。

示例代码段:

[dbo].[BookOrder](
[OrderId] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[OrderNo] [numeric](18, 0) NOT NULL,
[OrderDate] [datetime] NULL,
[OrderRetailerId] [int] NULL,
[OrderDistributorId] [int] NULL,
[OrderAgentId] [int] NULL,
[OrderTotalItems] [float] NULL,
[OrderTotalBaseAmt] [float] NULL,
[OrderTaxTotal] [float] NULL,
[OrderTotal] [float] NULL,
[OrderRemark] [varchar](150) NULL,
[OrderSMSStat] [bit] NULL,
[OrderCreatedById] [int] NULL,
[OrderCreatedOrigin] [varchar](50) NULL,
[OrderDeactivate] [bit] NULL,
[CmpId] [int] NULL,

但现在我想匹配少量模式(文件路径),然后根据匹配的模式实例化类。

所以我的问题是我在哪里可以存储我想要匹配的这些模式? 它们应该在我的数据库中的“表”中吗?或者我可以在这里有一个哈希表(当任何一个模式匹配时,它映射到要实例化的类)?

1 个答案:

答案 0 :(得分:3)

首先,您的Create方法实际上并没有创建任何内容。它返回已创建的实例。每次调用Create都会返回相同的实例。

如果那是你想要的,那很好,但是如果你每次想要一个新实例,我可以提出建议吗?而不是存储对象,存储一个返回新对象的函数:

class Factory
{
     Dictionary<string,Func<ICreate>> test = new Dictionary<string,Func<ICreate>>();

     public Factory()
     {
        test.Add( "classA", () => new a() );
        test.Add( "classB", () => new b() );
        test.Add( "classC", () => new c() );
     }

     public ICreate Create(string toMatch)
     {
        var creationFunction = test[toMatch];
        return creationFunction();
     }
}

看看它是如何工作的? lambda表达式() => new a()可以像函数一样调用,并且每次调用都会实例化一个新的a

对于模式匹配,你可以做类似的事情。我们为函数设置了一个函数;现在让我们把钥匙放进去。我们将存储一个接受字符串并返回布尔值的函数,而不是存储字符串。然后我们要做的就是搜索第一个字典条目,执行该键返回true。

class Factory
{
     Dictionary<Func<string,bool>,Func<ICreate>> _map = new Dictionary<Func<string,bool>, Func<ICreate>>();

     public Factory()
     {
        _map.Add
        (
            a => a.Contains("classA"), 
            () => new a()
        );
        _map.Add
        (
            a => a.Contains("classB"), 
            () => new b()
        );
        _map.Add
        (
            a => a.Contains("classC"), 
            () => new c()
        );
     }

     public ICreate Create(string toMatch)
     {
         var func = _map.Where( e => e.Key(toMatch) ).First().Value;
         return func(); 
     }
}


public class Program
{
    static public void Main()
    {
        var f = new Factory();
        var o = f.Create("c:\folder\subfolder\classA");
        Console.WriteLine("You just created an instance of '{0}'.", o.GetType().Name);
    }
}

输出:

You just created an instance of 'a'.

Code on DotNetFiddle

在这个例子中,我们与Contains()进行了模式匹配,但由于它是Func,你可以使用任何字符串函数,正则表达式来编写你想要的任何表达式。你也可以混搭;例如,您可以使用正则表达式来标识需要ClassA的模式,但您可以使用常规==比较来标识ClassB的模式。此外,如果要确保提交的任何字符串都匹配一个且只有一个模式,我们可以将LINQ函数从First更改为Single