通用策略模式
Generic Strategy pattern
我正在尝试使用泛型类型实现策略模式。我尝试创建对象并最终调用它,但我不知道它的签名应该是什么样子。我的问题出在 ObjectProcessor class(Do 方法).
//my code
abstract class Credential {}
class SNMP : Credential { }
class HTTP : Credential { }
//dll
abstract class CredentialDLL { }
class SNMPDLL : CredentialDLL { }
class HTTPDLL : CredentialDLL { }
interface IMapper<T, Y>
{
T Map(Y input);
Y Map(T input);
}
class SNMPMapper : IMapper<SNMP, SNMPDLL>
{
public SNMPDLL Map(SNMP input) { throw new NotImplementedException(); }
public SNMP Map(SNMPDLL input) { throw new NotImplementedException(); }
}
class HTPPMapper : IMapper<HTTP, HTTPDLL>
{
public HTTPDLL Map(HTTP input) { throw new NotImplementedException(); }
public HTTP Map(HTTPDLL input) { throw new NotImplementedException(); }
}
class ObjectProcessor
{
CredentialDLL Do(Credential input)
{
IMapper <?,?> mapper; // ??
if (input is SNMP)
{
mapper = new SNMPMapper();
}
else
{
mapper = new HTPPMapper();
}
return mapper.Map(input);
}
}
简单的答案是,您不能在 if 语句之外声明映射器,因为这两种类型中的每一种 returns 都是不同的映射器(一个是 IMapper<SNMP, SNMPDLL>
,另一个是 IMapper<HTTP, HTTPDLL>
).有多种方法可以解决这个问题,但如果不知道您的其余代码,就很难说什么是最佳选择。我能想到的最简单的更改是像这样编辑 Do
方法:
CredentialDLL Do(Credential input)
{
if (input is SNMP)
{
return new SNMPMapper().Map(input);
}
else
{
return new HTPPMapper().Map(input);
}
}
第二种可能性是向抽象 class 添加一个 Map
方法,然后在每个派生 class 中实现它。然后您可以进一步简化 Do
方法并消除检查类型的需要(这似乎违背了拥有泛型或基础 class 的目的)。
abstract class Credential
{
public abstract CredentialDLL Map();
}
class SNMP : Credential
{
public override CredentialDLL Map()
{
return new SNMPMapper().Map(this);
}
}
class HTTP : Credential
{
public override CredentialDLL Map()
{
return new HTTPMapper().Map(this);
}
}
// Simplified do method, it is now a one liner
CredentialDLL Do(Credential input)
{
return input.Map();
}
我正在尝试使用泛型类型实现策略模式。我尝试创建对象并最终调用它,但我不知道它的签名应该是什么样子。我的问题出在 ObjectProcessor class(Do 方法).
//my code
abstract class Credential {}
class SNMP : Credential { }
class HTTP : Credential { }
//dll
abstract class CredentialDLL { }
class SNMPDLL : CredentialDLL { }
class HTTPDLL : CredentialDLL { }
interface IMapper<T, Y>
{
T Map(Y input);
Y Map(T input);
}
class SNMPMapper : IMapper<SNMP, SNMPDLL>
{
public SNMPDLL Map(SNMP input) { throw new NotImplementedException(); }
public SNMP Map(SNMPDLL input) { throw new NotImplementedException(); }
}
class HTPPMapper : IMapper<HTTP, HTTPDLL>
{
public HTTPDLL Map(HTTP input) { throw new NotImplementedException(); }
public HTTP Map(HTTPDLL input) { throw new NotImplementedException(); }
}
class ObjectProcessor
{
CredentialDLL Do(Credential input)
{
IMapper <?,?> mapper; // ??
if (input is SNMP)
{
mapper = new SNMPMapper();
}
else
{
mapper = new HTPPMapper();
}
return mapper.Map(input);
}
}
简单的答案是,您不能在 if 语句之外声明映射器,因为这两种类型中的每一种 returns 都是不同的映射器(一个是 IMapper<SNMP, SNMPDLL>
,另一个是 IMapper<HTTP, HTTPDLL>
).有多种方法可以解决这个问题,但如果不知道您的其余代码,就很难说什么是最佳选择。我能想到的最简单的更改是像这样编辑 Do
方法:
CredentialDLL Do(Credential input)
{
if (input is SNMP)
{
return new SNMPMapper().Map(input);
}
else
{
return new HTPPMapper().Map(input);
}
}
第二种可能性是向抽象 class 添加一个 Map
方法,然后在每个派生 class 中实现它。然后您可以进一步简化 Do
方法并消除检查类型的需要(这似乎违背了拥有泛型或基础 class 的目的)。
abstract class Credential
{
public abstract CredentialDLL Map();
}
class SNMP : Credential
{
public override CredentialDLL Map()
{
return new SNMPMapper().Map(this);
}
}
class HTTP : Credential
{
public override CredentialDLL Map()
{
return new HTTPMapper().Map(this);
}
}
// Simplified do method, it is now a one liner
CredentialDLL Do(Credential input)
{
return input.Map();
}