当前位置:  开发笔记 > 编程语言 > 正文

继承的Builder设计模式:有更好的方法吗?

如何解决《继承的Builder设计模式:有更好的方法吗?》经验,为你挑选了1个好方法。

我正在创建一系列构建器来清理语法,为我的模拟创建域类,作为改进整体单元测试的一部分.我的构建器基本上填充了一个域类(例如a Schedule),其中一些值通过调用相应的值WithXXX并将它们链接在一起来确定.

我在构建器中遇到了一些共性,我想将它抽象到基类中以增加代码重用.不幸的是,我最终看起来像:

public abstract class BaseBuilder where BLDR : BaseBuilder 
                                          where T : new()
{
    public abstract T Build();

    protected int Id { get; private set; }
    protected abstract BLDR This { get; }

    public BLDR WithId(int id)
    {
        Id = id;
        return This;
    }
}

特别注意protected abstract BLDR This { get; }.

域类构建器的示例实现是:

public class ScheduleIntervalBuilder :
    BaseBuilder
{
    private int _scheduleId;
    // ...

    // UG! here's the problem:
    protected override ScheduleIntervalBuilder This
    {
        get { return this; }
    }

    public override ScheduleInterval Build()
    {
        return new ScheduleInterval
        {
            Id = base.Id,
            ScheduleId = _scheduleId
                    // ...
        };
    }

    public ScheduleIntervalBuilder WithScheduleId(int scheduleId)
    {
        _scheduleId = scheduleId;
        return this;
    }

    // ...
}

因为BLDR不是BaseBuilder类型,所以我不能return thisWithId(int)方法中使用BaseBuilder.

在这里公开带有属性的子类型是abstract BLDR This { get; }我唯一的选择,还是我错过了一些语法技巧?

更新(因为我可以更清楚地说明为什么我这样做了):

最终结果是让构建器构建配置文件的域类,人们希望以[程序员]可读格式从数据库中检索这些类.......没有错

mock.Expect(m => m.Select(It.IsAny())).Returns(
    new Schedule
    {
        ScheduleId = 1
        // ...
    }
);

因为那已经很可读了.替代构建器语法是:

mock.Expect(m => m.Select(It.IsAny())).Returns(
    new ScheduleBuilder()
        .WithId(1)
        // ...
        .Build()
);

我正在寻找使用构建器(以及实现所有这些WithXXX方法)的优势是抽象出复杂的属性创建(自动扩展我们的数据库查找值,而Lookup.KnownValues不是明显地访问数据库)并让构建器提供通常可重用的测试配置文件对于域类...

mock.Expect(m => m.Select(It.IsAny())).Returns(
    new ScheduleBuilder()
        .AsOneDay()
        .Build()
);

Jon Skeet.. 11

我可以说的是,如果这样做的一种方式,我想知道它太-我用的正是我的这种模式Protocol Buffers的端口.事实上,我很高兴看到其他人已经采取了它 - 这意味着我们至少有可能是正确的!



1> Jon Skeet..:

我可以说的是,如果这样做的一种方式,我想知道它太-我用的正是我的这种模式Protocol Buffers的端口.事实上,我很高兴看到其他人已经采取了它 - 这意味着我们至少有可能是正确的!


@Pellared:但是你没有得到你想要处理"任何建设者"或"任何信息"的情况的好处 - 是的,那些确实发生了.每种方法都有利弊.
推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有