首页 > 解决方案 > 如何创建工厂以创建接受更多派生类型的参数的派生对象

问题描述

我在为一系列基于公共的类的工厂设计适当的解决方案时遇到问题。我有一个名为 Verifier 的类,该类将只有方法 Verify 接受 Specification 的实例作为参数

public abstract class Verifier 
{
    public virtual bool Verify(Specification spec) 
    {
        //does the common job
        return true; //or false
    }
}

然后我有一组具体的验证器

public abstract class FirstVerifier : Verifier
{
    public override bool Verify(Specification spec) 
    {
       //does the job, maybe even calls for base or maybe not
       return true; 
    }
}

public abstract class SecondVerifier : Verifier
{
    public override bool Verify(Specification spec) 
    {
       //does the job, maybe even calls for base or maybe not
       return true; 
    }
}

然后我有一个不错的工厂,它返回给我一个合适的实例:

public class VerifierFactory 
{
    public static Verifier Create(string type) //not actually a string, but does not matter
    {
        switch (type) 
        {
            case "First": return new FirstVerifier();
            case "Second": return new SecondVerifier();
            default: throw new Exception();
        } 
    }
}

现在我有一个要求,验证者可以验证的不是规范的实例,而是规范的派生类型,例如:

public abstract class FirstVerifier : Verifier
{
    public override bool Verify(SpecificationOne spec)  //SpecificationOne derives from Specification
    {
       //does the job, maybe even calls for base or maybe not
       return true; 
    }
}

public abstract class SecondVerifier : Verifier
{
    public override bool Verify(SpecificationTwo spec) //SpecificationOne derives from Specification
    {
       //does the job, maybe even calls for base or maybe not
       return true; 
    }
}

这显然不会编译,我不想做这样的技巧:

public abstract class FirstVerifier : Verifier
{
    public override bool Verify(Specification spec)
    {
       var realSpecification = spec as SpecificationOne;
       if(realSpecification == null)
          throw new Exception();
       // do job
    }
}

我正在考虑一种解决方案(可能是通用的解决方案),其中我的工厂返回正确的类型,而后者又在验证方法中接受正确的类型,这样我就可以使用我的工厂创建验证器并调用验证,如下所示:

specifications.Select(s => VerifierFactory.Create(typeof(s)).Verify(s))

标签: c#genericsdesign-patternsfactory

解决方案


我认为您可以使用通用方法。例如:

public abstract class Verifier 
{
    public virtual bool Verify<T>(T  spec) where T: Specification
    {
        //does the common job
        return true; //or false
    }
}

或者您可以使用泛型类,例如:

创建基Specification

public class Specification
{
    //some properties, fields and etc
}

并从基Specification类继承您的其他规范

public class SpecificationOne : Specification
{
    //some properties, fields and etc
}


public class SpecificationTwo : Specification
{
    //some properties
}

创建基Verifier类后,它是泛型类。

public abstract class Verifier<T> where T : Specification
{
    public virtual bool Verify(T spec)
    {
        //does the common job
        return true; //or false
    }
}

并从基类继承您的其他验证器类Verifier<T>这些类必须不是抽象的,因为我们将在VerifierFactory. 例如:

public class FirstVerifier : Verifier<SpecificationOne>
{
    public override bool Verify(SpecificationOne spec)
    {
        var baseResult = base.Verify(spec);

        //some logic

        return baseResult;
    }
}

public class SecondVerifier : Verifier<SpecificationTwo>
{
    public override bool Verify(SpecificationTwo spec)
    {
        var baseResult = base.Verify(spec);

        //some logic

        return baseResult;
    }
}

你可以VerifierFactory像下面这样创建:

public class VerifierFactory
{
    public static Verifier<T> Create<T>(T spec) where T : Specification
    {
        if (spec.GetType() == typeof(SpecificationOne))
            return new FirstVerifier() as Verifier<T>;

        if (spec.GetType() == typeof(SpecificationTwo))
            return new SecondVerifier() as Verifier<T>;

        //and etc...
        // I think you project must have one default Verifier class for else case
    }
}

最后,您可以使用如下所示的 linq 查询:

specifications.Select(s => VerifierFactory.Create(s).Verify(s))

推荐阅读