我有一个Factory类,我根据字符串匹配实例化类。
示例代码段:
class Factory
{
Dictionary test = new Dictionary(string, ICreate);
public FactoryMethod()
{
test.Add("classA",new a());
test.Add("classB",new b());
test.Add("classC",new c());
}
public ICreate Create(string toMatch)
{
return test[toMatch];
}
}
但现在我想匹配少量模式(文件路径),然后根据匹配的模式实例化类。
所以我的问题是我在哪里可以存储我想要匹配的这些模式?它们应该在我的数据库中的“表”中吗?或者我可以在这里有一个哈希表(当任何一个模式匹配时,它映射到要实例化的类)?
首先,你的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'.
在这个例子中,我们使用Contains()
进行模式匹配,但由于它是Func,你可以使用任何字符串函数,正则表达式来编写任何你想要的表达式。你也可以混搭;例如,您可以使用正则表达式来标识需要ClassA的模式,但您可以使用常规==
比较来识别ClassB的模式。此外,如果要确保提交的任何字符串与一个且仅一个模式匹配,我们可以将LINQ函数从First
更改为Single
。