繁体   English   中英

基于泛型类型的转换链

[英]Chain of transformations based on generic types

我正在考虑一个链,它将允许我执行一组转换,数据类型从转换到转换。 到目前为止,我有这样的事情:

public abstract class TransformationStep<T, TY>
{
    public abstract TY Execute(T input);
}

public class Times2<TY> : TransformationStep<int, TY>
{
    public Times2(TransformationStep<int, TY> next)
    {
        Next = next;
    }

    public TransformationStep<int, TY> Next { get; set; }

    public override TY Execute(int input)
    {
        var res = input * 2;
        return Next.Execute(res);
    }
}

public class ToString<TY> : TransformationStep<int, TY>
{
    public ToString(TransformationStep<string, TY> next)
    {
        Next = next;
    }

    public TransformationStep<string, TY> Next { get; }

    public override TY Execute(int input)
    {
        var res = input + "!!!";
        return Next.Execute(res);
    }
}

我看到的唯一问题是末端链类型,我无法将 T 转换为 TY。

public class End<T, TY> : TransformationStep<T, TY>
{
    public override TY Execute(T input)
    {
        return input;
    }
}

你有什么解决办法吗? 另外你对这个设计有什么看法,你知道这样的东西有什么好的材料吗?

看起来你想要转换:

public abstract class TransformationStep<TIn, TOutput>
{
    public abstract TOutput Execute(TIn input);
}

如果你只想返回输入类型,那么可以创建另一个返回类型的方法:

public abstract class TransformationStep<TIn, TOutput>
{
    public abstract TOutput Execute(TIn input);

    public abstract TIn ExecuteWithoutTransformation(TIn input);
}

数据流

如果要将数据链连接到管道或图形中,则可以使用TransformBlock

什么是责任链模式

正如wiki所说 的“责任链模式”:

在面向对象设计中,责任链模式是一种行为设计模式,由一个命令对象源和一系列处理对象组成。 2每个处理对象都包含定义它可以处理的命令对象类型的逻辑; 其余的被传递给链中的下一个处理对象。 还存在一种将新处理对象添加到该链末端的机制。

您的代码看起来很相似,但是链式责任模式的代码和目标略有不同。 它不进行转换,它将对象提供给链中的下一个处理对象

因此,责任模式链代码的一种变体可以如下所示:

责任模式链的期望行为的抽象:

public abstract class MyHandler<T>
{
    private MyHandler<T> Next { get; set; }

    public virtual void Handle(T request)
    {
        Next?.Handle(request);
    }

    public MyHandler<T> SetNext(MyHandler<T> next)
    {
        Next = next;
        return Next;
    }
}

让我们想象一下,我们是一家出版社,我们希望文章的每个属性都应该得到验证。 因此,处理文章的具体实现可能如下所示:

public class OnlyNewArticleValidationHandler : MyHandler<Document>
{
    public override void Handle(Document document)
    {
        if (document.DateCreated.Year < DateTime.Now.Year)
        {
            throw new Exception("Only new articles should be published.");
        }

        base.Handle(document);
    }
}


public class AuthorValidationHandler : MyHandler<Document>
{
    public override void Handle(Document document)
    {
        if (string.IsNullOrWhiteSpace(document.Author))
        {
            throw new Exception("Author is required.");
        }

        base.Handle(document);
    }
}


public class NameRequiredValidationHandler : MyHandler<Document>
{
    public override void Handle(Document document)
    {
        if (string.IsNullOrWhiteSpace(document.Name))
        {
            throw new Exception("Name is required.");
        }

        base.Handle(document);
    }
}

ArticleProcessor看起来像这样:

public class MyChainAticleProcessor
{
    public void Validate(Document document)
    {
        var handler = new NameRequiredValidationHandler();
        handler.SetNext(new AuthorValidationHandler())
            .SetNext(new OnlyNewArticleValidationHandler());

        handler.Handle(document);
    }
}

它可以像这样运行:

new MyChainAticleProcessor().Validate(
    new Document { Author = "Author 1", Name="Name 1" }
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM