通用战略模式

时间:2017-08-30 19:51:39

标签: c# generics design-patterns strategy-pattern

我试图用泛型类型实现策略模式。我尝试创建对象,结束调用它,但我不知道应该如何看起来像它的签名。我的问题出在ObjectProcessor类(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);
    }
}

1 个答案:

答案 0 :(得分:2)

The simple answer is, you can't declare the mapper outside of the if statement because each of those two types returns a different mapper (one is <script src="/lib/js/vendor.min.js"></script> and the other is <script src="/com/app.js" defer></script> ). There are several options to solving this, but without knowing the rest of your code it is hard to say what would be the best option. The simplest change that I can think of would be to edit your //Make program fullscreen, etc axShockwaveFlash1.Dock = DockStyle.Fill; InitFlashMovie(axShockwaveFlash1,Properties.Resources.SWF); method like this:

IMapper<SNMP, SNMPDLL>

A second possiblity would be to add a IMapper<HTTP, HTTPDLL> method to your abstract class and then implement it in each derived class. Then you could simplify the Do method further and remove the need to check for a type (which seems to defeat the purpose of having a generic or a base class anyway).

CredentialDLL Do(Credential input)
{
    if (input is SNMP)
    {
        return new SNMPMapper().Map(input);
    }
    else
    {
        return new HTPPMapper().Map(input);
    }
}