Стоит ли переносить инициализацию в отдельный метод?
От: Аноним  
Дата: 02.07.13 03:23
Оценка:
Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
Re: Стоит ли переносить инициализацию в отдельный метод?
От: Sinix  
Дата: 02.07.13 04:55
Оценка: 1 (1) -1
Здравствуйте, Аноним, Вы писали:

А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?


It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().

Если речь идёт про выносе всего кода из конструктора в отдельный метод — практически не встречал. В большинстве случаев удобней разбить логику на отдельные методы и превратить инициализацию в вызовы этих методов из конструктора.
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
От: Аноним  
Дата: 02.07.13 05:31
Оценка:
Здравствуйте, Sinix, Вы писали:

S>It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().


S>Если речь идёт про выносе всего кода из конструктора в отдельный метод — практически не встречал. В большинстве случаев удобней разбить логику на отдельные методы и превратить инициализацию в вызовы этих методов из конструктора.


Всё так. Спасибо.
Re: Стоит ли переносить инициализацию в отдельный метод?
От: Nikolay_Ch Россия  
Дата: 02.07.13 05:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?

Ну... к примеру, если активно используются интерфейсы, то единственный нормальный способ проинициализировать экземпляр — это метод.
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
От: Аноним  
Дата: 02.07.13 06:12
Оценка: +2
Здравствуйте, Nikolay_Ch, Вы писали:
N_C>Ну... к примеру, если активно используются интерфейсы, то единственный нормальный способ проинициализировать экземпляр — это метод.

А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.

ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика. Соответственно и публичные методы инициализации, которые позволяют существовать объекту в невалидном состоянии в течении времени между созданием объекта и вызовом метода инициализации, есть нехорошо. Единственное оправдание всяких Form.OnCreate Control.Initialize это низкая сложность входа, отсутствие необходимости объяснять что такое Dependency Injection и возможность скрыть сложность фабрики форм.
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
От: Nikolay_Ch Россия  
Дата: 02.07.13 06:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.

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

А>ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика.

ИМХО практика нормальная. К примеру как при работе с БД — у объекта Connection есть конструктор, а есть метод Open. Таких ситуаций множество можно описать.
Re[4]: Стоит ли переносить инициализацию в отдельный метод?
От: Аноним  
Дата: 02.07.13 07:02
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Здравствуйте, Аноним, Вы писали:


А>>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.

N_C>Если у Вас есть интерфейс, который реализуется совершенно разными объектами (не наследуемых друг от друга). Есть объекты, которые получают на вход экземпляр объекта и должны его инициализировать. Вам как-то надо придумать единый метод инициализации этих объектов, т.к. конструктор здесь не подойдет.
Как конструктор может не подойти для инициализации объекта?
Я правильно понял вашу мысль: кто-то(кто?) создал объекты и теперь просит их проинициализировать уже у вашего клиента. Возникает естественный вопрос: почему этот кто-то не создал их сразу нормальными? И кто будет инициализировать объекты, если они понадобятся в другом месте?

А>>ИМХО существование объекта в невалидном состоянии между вызовами публичных методов — плохая практика.

N_C>ИМХО практика нормальная. К примеру как при работе с БД — у объекта Connection есть конструктор, а есть метод Open. Таких ситуаций множество можно описать.
Вы тут подменяете инициализацию и открытие соединения. Объект соединение в закрытом состоянии это вполне валидный объект, с явно определенным поведением. И открытие соединения это часть интерфейса.

Похоже термин "инициализация объекта" мы наделяем разными понятиями. Я под этим термином понимаю некое наполнение внутреннего состояния объекта. И это состояние должно быть валидным с точки зрения публичного интерфейса.
Re: UninitializedException
От: igor-booch Россия  
Дата: 02.07.13 07:33
Оценка: +2
А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?

Есть недостаток, нужно во всех методах проверять проинициализирован экземпляр или нет, и если нет выкидывать эксепшен.
А при инициализации через конструктор, у Вас либо есть проинициализированный экземпляр, либо его нет.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[2]: Стоит ли переносить инициализацию в отдельный метод?
От: Tom Россия http://www.RSDN.ru
Дата: 02.07.13 09:25
Оценка:
А>>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в C#?
S>It depends. Например, если инициализация включает в себя логику, специфичную для отдельных сценариев, вместо двух конструкторов удобней использовать static-методы вида CreateForA(), CreateForB().
Это до того момента когда вам тесты понадобится писать. В целом для нормально тестируемого кода надо забыть что такое статический метод, или статическая переменная
Народная мудрось
всем все никому ничего(с).
Re[2]: UninitializedException
От: drol  
Дата: 02.07.13 09:30
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>А при инициализации через конструктор, у Вас либо есть проинициализированный экземпляр, либо его нет.


Это верно только для однопоточной ситуации. В многопоточном случае возможны такие "чудеса", как выполнение конструктора параллельно с финализатором.
Re[3]: UninitializedException
От: HowardLovekraft  
Дата: 02.07.13 10:21
Оценка:
Здравствуйте, drol, Вы писали:

D>Это верно только для однопоточной ситуации. В многопоточном случае возможны такие "чудеса", как выполнение конструктора параллельно с финализатором.

Пруф?
Финализаторы и так в отдельном потоке вызываются. Что вы подразумеваете под словом "многопоточный" в данном случае?
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
От: Аноним  
Дата: 02.07.13 10:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А можете раскрыть мысль? Совершенно не улавливается связь между инициализацией и интерфейсами.

Для инициализации используется конструктор. Конструктор не может быть определен в интерфейсе.
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
От: Sinix  
Дата: 02.07.13 10:25
Оценка: +1 :)
Здравствуйте, Tom, Вы писали:

Tom>Это до того момента когда вам тесты понадобится писать. В целом для нормально тестируемого кода надо забыть что такое статический метод, или статическая переменная


Или не нагибать код под тесты. Можно просто использовать Fakes/Mole, можно сочетать тесты с ассертами, можно вообще отказаться от юнит-тестов, обвешать код контрактами и ловить оставшуюся мелочь сразу на интеграционных/функциональных тестах. Я видел все три варианта, не сказал бы что любой из них был сильно лучше/хуже прочих.
Re: Стоит ли переносить инициализацию в отдельный метод?
От: HowardLovekraft  
Дата: 02.07.13 10:25
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Есть ли у этого подхода преимущества перед обычной инициализацией через конструктор в 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]: Стоит ли переносить инициализацию в отдельный метод?
От: Sinatr Германия  
Дата: 02.07.13 11:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Точнее, так: в чем преимущество:

А> public MyClass Initialize(...);
А>перед:
А> public MyClass(...)

Отложенная инициализация. Удобно, когда нужно инстанцинировать обьект, а инициализировать попозже (не в момент инстанцинации). Частный случай применения — если инстанцинация относительно "дорого" обходится, т.к. в этом случае есть возможность ее избежать, вызвав Deinit+Init.
---
ПроГLамеры объединяйтесь..
Re[3]: Стоит ли переносить инициализацию в отдельный метод?
От: HowardLovekraft  
Дата: 02.07.13 11:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Первое.

Обнаружил опечатку в своем посте. Должно быть так:
class MyClass
{
    private MyClass()
    {
    }    

    public static MyClass Create() {}
}

Т.е., фабричный метод.

А>Точнее, так: в чем преимущество:

А>перед:
Объект создан, но не инициализирован. Т.е. пользоваться им нельзя. Вопросы: 1) зачем его создавать? 2) тут есть преимущество?
Соседний пост про отложенную инициализацию не катит. Отложенная инициализация должна быть скрыта от внешнего кода.
Re[4]: Стоит ли переносить инициализацию в отдельный метод?
От: artelk  
Дата: 02.07.13 12:38
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

Однажды такое понадобилось, чтобы запретить клиентам наследовать от моего абстрактного класса 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]: Стоит ли переносить инициализацию в отдельный метод?
От: HowardLovekraft  
Дата: 02.07.13 13:14
Оценка:
Здравствуйте, artelk, Вы писали:

A>skipped

Не, у вас как раз пример с фабричными методами.
А у ТС Initialize вполне себе экземплярный и public:
var myObj = new MyClass();
myObj.Initialize();
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.