Здравствуйте, Аноним, Вы писали:
А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().
Если речь идёт про выносе всего кода из конструктора в отдельный метод — практически не встречал. В большинстве случаев удобней разбить логику на отдельные методы и превратить инициализацию в вызовы этих методов из конструктора.
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
От:
Аноним
Дата:
02.07.13 05:31
Оценка:
Здравствуйте, Sinix, Вы писали:
S>It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().
S>Если речь идёт про выносе всего кода из конструктора в отдельный метод — практически не встречал. В большинстве случаев удобней разбить логику на отдельные методы и превратить инициализацию в вызовы этих методов из конструктора.
Всё так. Спасибо.
Re: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Аноним, Вы писали:
А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
Ну... к примеру, если активно используются интерфейсы, то единственный нормальный способ проинициализировать экземпляр — это метод.
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Nikolay_Ch, Вы писали: N_C>Ну... к примеру, если активно используются интерфейсы, то единственный нормальный способ проинициализировать экземпляр — это метод.
А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.
ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика. Соответственно и публичные методы инициализации, которые позволяют существовать объекту в невалидном состоянии в течении времени между созданием объекта и вызовом метода инициализации, есть нехорошо. Единственное оправдание всяких Form.OnCreate Control.Initialize это низкая сложность входа, отсутствие необходимости объяснять что такое Dependency Injection и возможность скрыть сложность фабрики форм.
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Аноним, Вы писали:
А>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.
Если у Вас есть интерфейс, который реализуется совершенно разными объектами (не наследуемых друг от друга). Есть объекты, которые получают на вход экземпляр объекта и должны его инициализировать. Вам как-то надо придумать единый метод инициализации этих объектов, т.к. конструктор здесь не подойдет.
А>ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика.
ИМХО практика нормальная. К примеру как при работе с БД — у объекта Connection есть конструктор, а есть метод Open. Таких ситуаций множество можно описать.
Re[4]: Стоит ли переносить инициализацию в отдельный метод?
От:
Аноним
Дата:
02.07.13 07:02
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:
N_C>Здравствуйте, Аноним, Вы писали:
А>>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами. N_C>Если у Вас есть интерфейс, который реализуется совершенно разными объектами (не наследуемых друг от друга). Есть объекты, которые получают на вход экземпляр объекта и должны его инициализировать. Вам как-то надо придумать единый метод инициализации этих объектов, т.к. конструктор здесь не подойдет.
Как конструктор может не подойти для инициализации объекта?
Я правильно понял вашу мысль: кто-то(кто?) создал объекты и теперь просит их проинициализировать уже у вашего клиента. Возникает естественный вопрос: почему этот кто-то не создал их сразу нормальными? И кто будет инициализировать объекты, если они понадобятся в другом месте?
А>>ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика. N_C>ИМХО практика нормальная. К примеру как при работе с БД — у объекта Connection есть конструктор, а есть метод Open. Таких ситуаций множество можно описать.
Вы тут подменяете инициализацию и открытие соединения. Объект соединение в закрытом состоянии это вполне валидный объект, с явно определенным поведением. И открытие соединения это часть интерфейса.
Похоже термин "инициализация объекта" мы наделяем разными понятиями. Я под этим термином понимаю некое наполнение внутреннего состояния объекта. И это состояние должно быть валидным с точки зрения публичного интерфейса.
А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
Есть недостаток, нужно во всех методах проверять проинициализирован экземпляр или нет, и если нет выкидывать эксепшен.
А при инициализации через конструктор, у Вас либо есть проинициализированный экземпляр, либо его нет.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания http://rsdn.ru/Info/rules.xml
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
А>>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#? S>It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().
Это до того момента когда вам тесты понадобится писать. В целом для нормально тестируемого кода надо забыть что такое статический метод, или статическая переменная
Здравствуйте, drol, Вы писали:
D>Это верно только для однопоточной ситуации. В многопоточном случае возможны такие "чудеса", как выполнение конструктора параллельно с финализатором.
Пруф?
Финализаторы и так в отдельном потоке вызываются. Что вы подразумеваете под словом "многопоточный" в данном случае?
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
От:
Аноним
Дата:
02.07.13 10:22
Оценка:
Здравствуйте, Аноним, Вы писали:
А>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.
Для инициализации используется конструктор. Конструктор не может быть определен в интерфейсе.
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Tom, Вы писали:
Tom>Это до того момента когда вам тесты понадобится писать. В целом для нормально тестируемого кода надо забыть что такое статический метод, или статическая переменная
Или не нагибать код под тесты. Можно просто использовать Fakes/Mole, можно сочетать тесты с ассертами, можно вообще отказаться от юнит-тестов, обвешать код контрактами и ловить оставшуюся мелочь сразу на интеграционных/функциональных тестах. Я видел все три варианта, не сказал бы что любой из них был сильно лучше/хуже прочих.
Re: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Аноним, Вы писали:
А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
Что имеется ввиду? Это:
class MyClass
{
private MyClass()
{
}
public MyClass Create();
}
это:
class MyClass()
{
private void Initialize()
{
}
public MyClass()
{
Initialize();
}
}
или еще какой-то вариант?
Re[5]: Стоит ли переносить инициализацию в отдельный метод?
От:
Аноним
Дата:
02.07.13 10:28
Оценка:
Здравствуйте, Аноним, Вы писали:
N_C>>ИМХО практика нормальная. К примеру как при работе с БД — у объекта Connection есть конструктор, а есть метод Open. Таких ситуаций множество можно описать. А>Вы тут подменяете инициализацию и открытие соединения. Объект соединение в закрытом состоянии это вполне валидный объект, с явно определенным поведением. И открытие соединения это часть интерфейса.
Почему?
Допустим, имеется объект view сразу после вызова new View(). И имеется объект view после вызова view.Initialize(some data), заполненный некоторыми данными.
Что невалидного в состоянии объекта view без данных?
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
От:
Аноним
Дата:
02.07.13 10:35
Оценка:
Первое.
Точнее, так: в чем преимущество:
public class MyClass
{
public MyClass()
{
}
public MyClass Initialize(...);
}
перед:
public class MyClass
{
public MyClass(...)
{
}
}
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
Здравствуйте, Аноним, Вы писали:
А>Точнее, так: в чем преимущество: А> public MyClass Initialize(...); А>перед: А> public MyClass(...)
Отложенная инициализация. Удобно, когда нужно инстанцинировать обьект, а инициализировать попозже (не в момент инстанцинации). Частный случай применения — если инстанцинация относительно "дорого" обходится, т.к. в этом случае есть возможность ее избежать, вызвав Deinit+Init.
---
ПроГLамеры объединяйтесь..
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
Т.е., фабричный метод.
А>Точнее, так: в чем преимущество: А>перед:
Объект создан, но не инициализирован. Т.е. пользоваться им нельзя. Вопросы: 1) зачем его создавать? 2) тут есть преимущество?
Соседний пост про отложенную инициализацию не катит. Отложенная инициализация должна быть скрыта от внешнего кода.
Re[4]: Стоит ли переносить инициализацию в отдельный метод?
Однажды такое понадобилось, чтобы запретить клиентам наследовать от моего абстрактного класса Either — т.е. сделать закрытую иерархию (эмуляция алгебраических типов):
Скрытый текст
public abstract class Either<T1, T2>
{
private Either()
{ }
public static Either<T1, T2> New(T1 value)
{
return Value1(value);
}
public static Either<T1, T2> New(T2 value)
{
return Value2(value);
}
public static Either<T1, T2> Value1(T1 value)
{
return new Either1(value);
}
public static Either<T1, T2> Value2(T2 value)
{
return new Either2(value);
}
public abstract T Exec<T>(Func<T1, T> f1, Func<T2, T> f2);
public abstract void Exec(Action<T1> f1, Action<T2> f2);
private sealed class Either1 : Either<T1, T2>
{
private readonly T1 _value;
public Either1(T1 value)
{
_value = value;
}
public override T Exec<T>(Func<T1, T> f1, Func<T2, T> f2)
{
return f1(_value);
}
public override void Exec(Action<T1> f1, Action<T2> f2)
{
f1(_value);
}
}
private sealed class Either2 : Either<T1, T2>
{
private readonly T2 _value;
public Either2(T2 value)
{
_value = value;
}
public override T Exec<T>(Func<T1, T> f1, Func<T2, T> f2)
{
return f2(_value);
}
public override void Exec(Action<T1> f1, Action<T2> f2)
{
f2(_value);
}
}
}
Re[5]: Стоит ли переносить инициализацию в отдельный метод?