有条件的构建方法链接流畅的界面 [英] Conditional Builder Method Chaining Fluent Interface

查看:126
本文介绍了有条件的构建方法链接流畅的界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道什么是执行在流畅接口的。当情况的最好办法方式链接生成器对象?

I was wondering what would be the best way to implement a .When condition in a fluent interface using method chaining in a Builder object?

比如我将如何贯彻落实 .WithSkill ()。当()在下面的示例中的方法:

For instance how would I implement the .WithSkill() and .When() methods in the following example:

var level = 5;

var ninja = NinjaBuilder
    .CreateNinja()
    .Named("Ninja Boy")
    .AtLevel(level)
    .WithShurikens(10)
    .WithSkill(Skill.HideInShadows)
        .When(level > 3)
    .Build()

更新 - 样品溶液可以发现的这里

Update - A sample solution can be found here.

推荐答案

我会做的是有 NinjaBuilder 保持业务为代表的列表,而不是将它们,只适用于他们时,被称为 .Build 。这将允许您以使其有条件的:

What I'd do is have NinjaBuilder keep the operations as a list of delegates, rather than applying them, and only apply them when .Build is called. This would allow you to make them conditional:

public class NinjaBuilder { 
    List<Action<Ninja>> builderActions = new List<Action<Ninja>>();

    public Ninja Build() {
        var ninja = new Ninja();
        builderActions.ForEach(ba => ba(ninja));
        return ninja;
    }

    public NinjaBuilder WithShurikens(int numShirukens) {
        builderActions.Add(n=>n.Shirukens = numShirukens);
        return this;
    }

    public NinjaBuilder When(Boolean condition) {
        if (!condition) // If the condition is not met, remove the last action
            builderActions.Remove(builderActions.Length - 1);
        return this;
    }
}



当然,这个假设条件是恒定在建设者创造的时候。如果你想让它不恒定,你可以做这样的事情,而不是:

Of course, this assumes that the condition is constant at the time of builder creation. If you want to make it non-constant, you could do something like this instead:

    public NinjaBuilder When(Func<Boolean> condition) {
        var oldAction = builderActions[builderActions.Length - 1];
        builderActions[builderActions.Length - 1] = n => condition() ? oldAction(n) : n;
        return this;
    }

如果你想将较为编译器检查,可以使受保护的builderActions,做这样的事情:

If you want When be somewhat more compiler checked, you can make builderActions protected and do something like this:

public class ConditionalNinjaBuilder : NinjaBuilder {
    public ConditionalNinjaBuilder(NinjaBuilder wrappedBuilder) {            
        // Since someone might call .WithShirukens on the wrapping
        // builder directly, we should make sure that our actions 
        // list is the same instance as the one in our wrapped builder
        builderActions = wrappedBuilder.builderActions;
    }

    public ConditionalNinjaBuilder When(Func<Boolean> condition) {
        var oldAction = builderActions[builderActions.Length - 1];
        builderActions[builderActions.Length - 1] = n => condition() ? oldAction(n) : n;
        return this;
    }
}

和具有原始操作返回一个ConditionalNinjaBuilder:

and have the original operations return a ConditionalNinjaBuilder:

    public ConditionalNinjaBuilder WithShurikens(int numShirukens) {
        builderActions.Add(n=>n.Shirukens = numShirukens);
        return new ConditionalNinjaBuilder(this);
    }



这样,你只能叫。当。这有可能允许嵌套/复合条件语句额外的优势/并发症,太。让人惊讶。

That way you can only call .When after first calling another method. This has the additional advantage/complication of potentially allowing for nested/compounded conditionals, too. Yikes.

这篇关于有条件的构建方法链接流畅的界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆