如何实现和扩展约书亚的建造者模式在.net中? [英] How to implement and extend Joshua's builder pattern in .net?

查看:150
本文介绍了如何实现和扩展约书亚的建造者模式在.net中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是code我都试过了,有没有更好的方式来做到这一点?

Below is the code I have tried, is there a better way to do this?

    public class NutritionFacts
    {
        public static NutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
        {
            return new NutritionFacts.Builder(name, servingSize, servingsPerContainer);
        }

        public sealed class Builder
        {
            public Builder(String name, int servingSize,
            int servingsPerContainer)
            {
            }
            public Builder totalFat(int val) { }
            public Builder saturatedFat(int val) { }
            public Builder transFat(int val) { }
            public Builder cholesterol(int val) { }
            //... 15 more setters
            public NutritionFacts build()
            {
                return new NutritionFacts(this);
            }
        }
        private NutritionFacts(Builder builder) { }
        protected NutritionFacts() { }
    }

  • 如何扩展这个类呢?做 我们需要编写单独的建设者 类的每个派生 班?

    • How do we extend such a class? Do we need to write separate builder classes for each of the derived classes?

      public class MoreNutritionFacts : NutritionFacts
      {
          public new static MoreNutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
          {
              return new MoreNutritionFacts.Builder(name, servingSize, servingsPerContainer);
          }
          public new sealed class Builder
          {
              public Builder(String name, int servingSize,
              int servingsPerContainer) {}
              public Builder totalFat(int val) { }
              public Builder saturatedFat(int val) { }
              public Builder transFat(int val) { }
              public Builder cholesterol(int val) { }
              //... 15 more setters
              public Builder newProperty(int val) { }
              public MoreNutritionFacts build()
              {
                  return new MoreNutritionFacts(this);
              }
          }
          private MoreNutritionFacts(MoreNutritionFacts.Builder builder) { }
      }
      

    • 推荐答案

      在Protocol Buffers的,我们实行这样的生成器模式(大大简化):

      In Protocol Buffers, we implement the builder pattern like this (vastly simplified):

      public sealed class SomeMessage
      {
        public string Name { get; private set; }
        public int Age { get; private set; }
      
        // Can only be called in this class and nested types
        private SomeMessage() {}
      
        public sealed class Builder
        {
          private SomeMessage message = new SomeMessage();
      
          public string Name
          {
            get { return message.Name; }
            set { message.Name = value; }
          }
      
          public int Age
          {
            get { return message.Age; }
            set { message.Age = value; }
          }
      
          public SomeMessage Build()
          {
            // Check for optional fields etc here
            SomeMessage ret = message;
            message = null; // Builder is invalid after this
            return ret;
          }
        }
      }
      

      这是不太一样EJ2格局,但:

      This isn't quite the same as the pattern in EJ2, but:

      • 在没有任何数据复制需要在编译的时候。换句话说,当你设置的属性,你这样做的真正对象 - 你就不能看到它。这是类似于的StringBuilder 一样。
      • 的建设者成为呼叫生成后无效的()来保证不变性。这不幸装置的方式,它不能用作为一种原型的该EJ2版本即可。
      • 我们使用属性,而不是getter和setter方法​​,在大多数情况下 - 这正好配合C#3的对象初始化
      • 我们确实还提供制定者返回为求preC#3的用户。
      • No data copying is required at build time. In other words, while you're setting the properties, you're doing so on the real object - you just can't see it yet. This is similar to what StringBuilder does.
      • The builder becomes invalid after calling Build() to guarantee immutability. This unfortunately means it can't be used as a sort of "prototype" in the way that the EJ2 version can.
      • We use properties instead of getters and setters, for the most part - which fits in well with C# 3's object initializers.
      • We do also provide setters returning this for the sake of pre-C#3 users.

      我还没有真正研究过的继承与生成器模式 - 它不支持协议缓冲区反正。我怀疑这是相当棘手。

      I haven't really looked into inheritance with the builder pattern - it's not supported in Protocol Buffers anyway. I suspect it's quite tricky.

      这篇关于如何实现和扩展约书亚的建造者模式在.net中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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