在工厂方法中使用匹配模式(开关)的最佳方法是什么
What is the best way to use matching patter (switch) in factory methods
我想使用这样的结构创建对象:
IProduct product1 = creator.CreateProduct<ConcreteProduct1>();
IProduct product2 = creator.CreateProduct<ConcreteProduct2>();
我的 CreateProduct 方法版本如下所示:
public T CreateProduct<T>()
where T: IProduct, new()
{
switch (typeof(T))
{
case(...) return new ConcreteProduct1;
case(...) return new ConcreteProduct2;
}
}
我的问题是,在这种情况下我不知道如何使用匹配模式。
我尝试了几个选项:
case (typeof(ConcreteProduct1)): return new ConcreteProduct1;
case (ConcreteProduct1 c): return new ConcreteProduct1;
但是这些都不行。
我应该在 case 语句中使用什么表达式?
或者我还有什么其他选择可以实现这个方法?
如果ConcreteProduct1
和ConcreteProduct2
类实现了IProduct
接口,你不需要任何switch表达式,只需要简单的return一个新实例(因为您已将所需类型作为泛型类型参数 T
和无参数构造函数的泛型类型约束传递)
public T CreateProduct<T>()
where T: IProduct, new()
{
return new T();
}
当我们想要在应用程序的组件之间实现松散耦合并且只操作接口而不知道当前实例化了哪个实现时,这样做很有用的场景。例如,假设我们有以下接口:
interface IProduct
{
}
interface IArticle
{
}
假设这些接口具有以下实现:
class ConcreteProduct1: IProduct
{
}
class ConcreteProduct2: IProduct
{
}
class ConcreteArticle1: IArticle
{
}
class ConcreteArticle2: IArticle
{
}
现在,在代码库的客户端部分,我们想要在不知道当前实例化了哪个实现的情况下操作 IArticle
和 IProduct
,例如:
static void Main()
{
var article = Factory.Create<IArticle>();
var product = Factory.Create<IProduct>();
}
而且,Factory
看起来像这样:
public static class Factory
{
public static T Create<T>() where T : class
{
return Activator.CreateInstance(ImplementationOf<T>()) as T;
}
public static Type ImplementationOf<T>()
{
// Concrete types registration
var map = new Dictionary<Type, Type>()
{
[typeof(IArticle)] = typeof(ConcreteArticle1),
[typeof(IProduct)] = typeof(ConcreteProduct2)
}
return map[typeof(T)];
}
}
此处,Factory.ImplementationOf
方法包含接口与运行时使用的具体类型之间的映射。并且,以后如果我们想换一个接口的其他实现,比如ConcreteArticle2
换成IArticle
,只需要修改这个方法,不用触及客户端代码。
我想使用这样的结构创建对象:
IProduct product1 = creator.CreateProduct<ConcreteProduct1>();
IProduct product2 = creator.CreateProduct<ConcreteProduct2>();
我的 CreateProduct 方法版本如下所示:
public T CreateProduct<T>()
where T: IProduct, new()
{
switch (typeof(T))
{
case(...) return new ConcreteProduct1;
case(...) return new ConcreteProduct2;
}
}
我的问题是,在这种情况下我不知道如何使用匹配模式。 我尝试了几个选项:
case (typeof(ConcreteProduct1)): return new ConcreteProduct1;
case (ConcreteProduct1 c): return new ConcreteProduct1;
但是这些都不行。
我应该在 case 语句中使用什么表达式? 或者我还有什么其他选择可以实现这个方法?
如果ConcreteProduct1
和ConcreteProduct2
类实现了IProduct
接口,你不需要任何switch表达式,只需要简单的return一个新实例(因为您已将所需类型作为泛型类型参数 T
和无参数构造函数的泛型类型约束传递)
public T CreateProduct<T>()
where T: IProduct, new()
{
return new T();
}
当我们想要在应用程序的组件之间实现松散耦合并且只操作接口而不知道当前实例化了哪个实现时,这样做很有用的场景。例如,假设我们有以下接口:
interface IProduct
{
}
interface IArticle
{
}
假设这些接口具有以下实现:
class ConcreteProduct1: IProduct
{
}
class ConcreteProduct2: IProduct
{
}
class ConcreteArticle1: IArticle
{
}
class ConcreteArticle2: IArticle
{
}
现在,在代码库的客户端部分,我们想要在不知道当前实例化了哪个实现的情况下操作 IArticle
和 IProduct
,例如:
static void Main()
{
var article = Factory.Create<IArticle>();
var product = Factory.Create<IProduct>();
}
而且,Factory
看起来像这样:
public static class Factory
{
public static T Create<T>() where T : class
{
return Activator.CreateInstance(ImplementationOf<T>()) as T;
}
public static Type ImplementationOf<T>()
{
// Concrete types registration
var map = new Dictionary<Type, Type>()
{
[typeof(IArticle)] = typeof(ConcreteArticle1),
[typeof(IProduct)] = typeof(ConcreteProduct2)
}
return map[typeof(T)];
}
}
此处,Factory.ImplementationOf
方法包含接口与运行时使用的具体类型之间的映射。并且,以后如果我们想换一个接口的其他实现,比如ConcreteArticle2
换成IArticle
,只需要修改这个方法,不用触及客户端代码。