Как разработать неизменный объект со сложной инициализацией

13
задан Community 23 May 2017 в 12:10
поделиться

5 ответов

Используйте разработчика:

public class Entity
{
   public class Builder
   {
     private int _field1;
     private int _field2;
     private int _field3;

     public Builder WithField1(int value) { _field1 = value; return this; }
     public Builder WithField2(int value) { _field2 = value; return this; }
     public Builder WithField3(int value) { _field3 = value; return this; }

     public Entity Build() { return new Entity(_field1, _field2, _field3); }
   }

   private int _field1;
   private int _field2;
   private int _field3;

   private Entity(int field1, int field2, int field3) 
   {
     // Set the fields.
   }

   public int Field1 { get { return _field1; } }
   public int Field2 { get { return _field2; } }
   public int Field3 { get { return _field3; } }

   public static Builder Build() { return new Builder(); }
}

Затем создают его как:

Entity myEntity = Entity.Build()
                   .WithField1(123)
                   .WithField2(456)
                   .WithField3(789)
                  .Build()

, Если некоторые параметры являются дополнительными, Вы не должны будете называть метод WithXXX, и у них могут быть значения по умолчанию.

22
ответ дан 1 December 2019 в 19:15
поделиться

Хотя это - вероятно, часть домена того, что Вы делаете, и таким образом мое предложение может быть недопустимым, что относительно того, чтобы пытаться сломать эти 8 параметров в логические группы?

Каждый раз, когда я вижу "кучу" параметров, я чувствую, что object/method/contructor должен быть более простым.

1
ответ дан 1 December 2019 в 19:15
поделиться

В данный момент необходимо было бы использовать конструктора с большим количеством args или разработчика. В C# 4.0 (VS2010) можно использовать именованные / дополнительные аргументы для достижения чего-то подобного объектным инициализаторам C# 3.0 - см. здесь . Пример на блоге:

  Person p = new Person ( forename: "Fred", surname: "Flintstone" );

, Но можно легко видеть, как что-то подобное может запросить любого конструктора (или другой сложный метод). Сравните с синтаксисом C# 3.0 объектного инициализатора (с изменяемым типом):

 Person p = new Person { Forename = "Fred", Surname = "Flintstone" };

Не очень, чтобы сказать им независимо, действительно.

Jon Skeet отправил некоторые мысли об этом предмете также, здесь .

9
ответ дан 1 December 2019 в 19:15
поделиться

Первое, что пришло на ум два различных ответа приходят на ум...

... первое, и вероятно самый простой, должен использовать объектную фабрику (или разработчик) как помощник, который удостоверяется, чтобы Вы разобрались в вещах.

Объектная инициализация была бы похожа на это:

var factory = new ObjectFactory();
factory.Fimble = 32;
factory.Flummix = "Nearly";
var mine = factory.CreateInstance();

... второе должно создать Ваш объект как стандартное, изменяемое, объект с Блокировкой () или Замораживание () функция. Все Ваши мутаторы должны проверить, чтобы видеть, был ли объект заблокирован и выдает исключение, если он имеет.

Объектная инициализация была бы похожа на это:

var mine = new myImmutableObject();
mine.Fimble = 32;
mine.Flummix = "Nearly";
mine.Lock(); // Now it's immutable.

, Какой метод взять во многом зависит от Вашего контекста - фабрика имеет преимущество того, чтобы быть удобным, если у Вас есть серия подобных объектов для построения, но это действительно представляет другой класс записи и поддерживает. Блокируемый объект означает, что существует только один класс, но другие пользователи могли бы получить непредвиденные ошибки выполнения, и тестирование более трудно.

3
ответ дан 1 December 2019 в 19:15
поделиться

Меня озадачил тот же вопрос, поскольку сложные конструкторы - тоже плохой дизайн для меня. Я также не являюсь большим поклонником концепции построителя, поскольку кажется, что слишком много лишнего кода нужно поддерживать. Что нам нужно, так это неизменность popsicle, что означает, что объект начинается как изменяемый, где вам разрешено использовать установщики свойств. Когда все свойства установлены, должен быть способ зафиксировать объект в неизменяемом состоянии. К сожалению, эта стратегия изначально не поддерживается в языке C #. В итоге я разработал свой собственный шаблон для создания неизменяемых объектов, как описано в следующем вопросе:

Шаблон неизменяемого объекта в C # - как вы думаете?

Андерс Хейлсберг говорит о поддержке этого типа неизменяемости с 36:30 в следующем интервью:

От эксперта к эксперту: Андерс Хейлсберг - Будущее C #

1
ответ дан 1 December 2019 в 19:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: