Конструктор с параметрами vs метод Init -- стоит ли использо
От: Shmj Ниоткуда  
Дата: 31.03.16 11:46
Оценка: -2 :))
Собственно, вся прелесть конструктора -- вы можете быть уверенным, что если создан инстанс то определенное поле 100% имеет установленное значение (если установлено в конструкторе).

Зато конструктор имеет много минусов. К примеру, Generics не поддерживают создание инстанса если конструктор с параметрами. Так же для XML-сериализации требуется наличие конструктора без параметров, а значит у вас уже не будет той гарантии, ради которой конструкторы вообще задумывались.

Еще минус, вы не можете добавить новый конструктор в класс с помощью Extensions-методов. Зато можно добавить новый метод Init.

И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).

Прихожу к пониманию что конструктор с параметрами не гибок и имеет больше минусов, чем плюсов. И лучшее решение всегда создавать конструктор без параметров + метод Init, если нужны параметры для инициализации класса. Если повторная инициализация запрещена -- это легко решается с помощью булевого поля _isInitialized.

Согласны?
Отредактировано 31.03.2016 13:28 Shmj . Предыдущая версия . Еще …
Отредактировано 31.03.2016 13:22 Shmj . Предыдущая версия .
Re: Конструктор с параметрами vs метод Init -- стоит ли использовать конструктор
От: _NN_ www.nemerleweb.com
Дата: 31.03.16 12:10
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>Согласны?


Нет конечно
Обычно метод Init не нужен, потому как возникают сразу множество проблем контролирования состояния.
Что если два раза кто-нибудь вызовет ? Из двух потоков ? И т.п.

С обобщениями действительно проблема и есть предложение, однако не так часто нужно и всегда есть обходные пути.
Насчёт сериализации, то для объектов-данных (data object) вообще не нужен конструктор и логика.

Есть предложение о добавления конструктора и расширения класса методами, но это не повод создавать всегда двухуровневую иницализацию.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Конструктор с параметрами vs метод Init -- стоит ли использовать конструк
От: Sharov Россия  
Дата: 31.03.16 12:20
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN> Из двух потоков ? И т.п.


Вот это для конструктора как раз не проблема. Там унутрях блокировка ставиться.
Кодом людям нужно помогать!
Re[2]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 31.03.16 13:25
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Нет конечно

_NN>Обычно метод Init не нужен, потому как возникают сразу множество проблем контролирования состояния.

А как насчет контрактов (interface). Как там описать конструктор?

_NN>Что если два раза кто-нибудь вызовет ? Из двух потоков ? И т.п.


По поводу двух раз -- уже написал, достаточно 1 поля для проверки.

По поводу потоков. Инстанс класса считается не потокобезопасным, если не указано иное. Если хотите сделать потокобезопасным -- то вам нужно озаботиться не только этим методом, но и всеми другими.

_NN>С обобщениями действительно проблема и есть предложение, однако не так часто нужно и всегда есть обходные пути.

_NN>Насчёт сериализации, то для объектов-данных (data object) вообще не нужен конструктор и логика.

А проверка того что все обязательные поля установлены?

_NN>Есть предложение о добавления конструктора и расширения класса методами, но это не повод создавать всегда двухуровневую иницализацию.


При использовании контрактов двухуровневой не избежать.
Отредактировано 31.03.2016 13:25 Shmj . Предыдущая версия .
Re[3]: Конструктор с параметрами vs метод Init -- стоит ли и
От: _NN_ www.nemerleweb.com
Дата: 31.03.16 13:35
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, _NN_, Вы писали:


_NN>>Нет конечно

_NN>>Обычно метод Init не нужен, потому как возникают сразу множество проблем контролирования состояния.

S>А как насчет контрактов (interface). Как там описать конструктор?

Тут конечно проблема. Пока нет такой возможности. Надеемся на светлое будущее.

_NN>>Что если два раза кто-нибудь вызовет ? Из двух потоков ? И т.п.


S>По поводу двух раз -- уже написал, достаточно 1 поля для проверки.

И проверять его в каждом методе, в каждом свойстве.

S>По поводу потоков. Инстанс класса считается не потокобезопасным, если не указано иное. Если хотите сделать потокобезопасным -- то вам нужно озаботиться не только этим методом, но и всеми другими.

У вас путаница.
Создание объекта через обычный конструктор это полностью потокобезопасно.
Вы не можете вызвать конструктор два раза и тем более из двух потоков, а вот метод Init запросто.

Кстати мы ещё не упомянули наследование, что если забудем вызвать базовый Init ? С конструкторами то ничего не забудем.

_NN>>С обобщениями действительно проблема и есть предложение, однако не так часто нужно и всегда есть обходные пути.

_NN>>Насчёт сериализации, то для объектов-данных (data object) вообще не нужен конструктор и логика.

S>А проверка того что все обязательные поля установлены?

Это разные вещи.
Данные это данные, а логика это логика.
Интерфейс ISerializable позволяет полностью всё проконтролировать если очень нужно.

_NN>>Есть предложение о добавления конструктора и расширения класса методами, но это не повод создавать всегда двухуровневую иницализацию.


S>При использовании контрактов двухуровневой не избежать.

Можно пример ?


Как вариант можете просто написать свой анализатор кода и всё контролировать извне.
Есть ещё вариант в виде библиотеки: https://github.com/default0/Introspect
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Конструктор с параметрами vs метод Init -- стоит ли использо
От: Sinix  
Дата: 31.03.16 13:42
Оценка: 3 (1) +2
Здравствуйте, Shmj, Вы писали:

S>Согласны?

Нет. Это классический "я не хочу учиться готовить кошек, поэтому кошки не нужны". Проблема не в кошках, проблема в том, что 99% их не готовят.
Серьёзно, у вас половина вопросов — это готовая иллюстрация XY problem, переучивайтесь


S>К примеру, Generics не поддерживают создание инстанса если конструктор с параметрами.

factory method, можно автоматом кэшировать делегат на конструктор. Буквально минута гуглинга на обсуждение с workaround-ом.


S>Еще минус, вы не можете добавить новый конструктор в класс с помощью Extensions-методов

factory method. Ну и про "добавить новый метод" говорить в принципе некорректно. Изучите, как оно работает.

S>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).

factory method / static interfaces proposal.
Re[4]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 31.03.16 14:59
Оценка:
Здравствуйте, _NN_, Вы писали:

S>>При использовании контрактов двухуровневой не избежать.

_NN>Можно пример ?

Упрощенный пример:

  Скрытый текст
using System;

namespace ConsoleApplication30
{
    class Program
    {
        class Settings
        {
            public string LocalFolder { get; set; }
        }

        interface IFileService
        {
            // Нужно иметь гарантию что установлены настройки
            void Init(Settings settings);

            void DownloadFile(string fileName);
        }

        class TestFileService : IFileService
        {
            private Settings _settings;

            public void Init(Settings settings)
            {
                _settings = settings;
            }

            public void DownloadFile(string fileName)
            {
                Console.WriteLine("Скачиваем файл " + fileName + " и сохраняем в папку " + _settings.LocalFolder);
            }
        }

        static void Main(string[] args)
        {
            // Получаем необходимую реализацию через unityContainer
            //IFileService fileService = unityContainer.Resolve<IFileService>()
            // Для упрощения заменим:
            IFileService fileService = new TestFileService();

            // Вместо Init можно было бы задействовать InjectionConstructor, но это никак бы не отразилось на контракте.
            // По этому в контракте нужно либо сделать свойство Settings, либо метод Init. Поскольку при инициализации не просто устанавливаем значение, а и производим действия -- то метод.
            fileService.Init(new Settings {LocalFolder = "C:\\temp"});

            fileService.DownloadFile("fileName.txt");
        }
    }
}


_NN>Как вариант можете просто написать свой анализатор кода и всё контролировать извне.

_NN>Есть ещё вариант в виде библиотеки: https://github.com/default0/Introspect

Я бы предпочел максимально простой вариант, без доп. библиотек, когда можно без них.
Отредактировано 31.03.2016 15:01 Shmj . Предыдущая версия .
Re[2]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 31.03.16 15:00
Оценка:
Здравствуйте, Sinix, Вы писали:

S>>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).

S>factory method / static interfaces proposal.

Вот вам пример упрощенный с описанием проблемы:

  Скрытый текст
using System;

namespace ConsoleApplication30
{
    class Program
    {
        class Settings
        {
            public string LocalFolder { get; set; }
        }

        interface IFileService
        {
            // Нужно иметь гарантию что установлены настройки
            void Init(Settings settings);

            void DownloadFile(string fileName);
        }

        class TestFileService : IFileService
        {
            private Settings _settings;

            public void Init(Settings settings)
            {
                _settings = settings;
            }

            public void DownloadFile(string fileName)
            {
                Console.WriteLine("Скачиваем файл " + fileName + " и сохраняем в папку " + _settings.LocalFolder);
            }
        }

        static void Main(string[] args)
        {
            // Получаем необходимую реализацию через unityContainer
            //IFileService fileService = unityContainer.Resolve<IFileService>()
            // Для упрощения заменим:
            IFileService fileService = new TestFileService();

            // Вместо Init можно было бы задействовать InjectionConstructor, но это никак бы не отразилось на контракте.
            // По этому в контракте нужно либо сделать свойство Settings, либо метод Init. Поскольку при инициализации не просто устанавливаем значение, а и производим действия -- то метод.
            fileService.Init(new Settings {LocalFolder = "C:\\temp"});

            fileService.DownloadFile("fileName.txt");
        }
    }
}


Напишите как правильно.
Отредактировано 31.03.2016 15:01 Shmj . Предыдущая версия .
Re[5]: Конструктор с параметрами vs метод Init -- стоит ли и
От: _NN_ www.nemerleweb.com
Дата: 31.03.16 15:12
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, _NN_, Вы писали:


S>>>При использовании контрактов двухуровневой не избежать.

_NN>>Можно пример ?

S>Упрощенный пример:


S>
  Скрытый текст
S>
S>using System;

S>namespace ConsoleApplication30
S>{
S>    class Program
S>    {
S>        class Settings
S>        {
S>            public string LocalFolder { get; set; }
S>        }

S>        interface IFileService
S>        {
S>            // Нужно иметь гарантию что установлены настройки
S>            void Init(Settings settings);

S>            void DownloadFile(string fileName);
S>        }

S>        class TestFileService : IFileService
S>        {
S>            private Settings _settings;

S>            public void Init(Settings settings)
S>            {
S>                _settings = settings;
S>            }

S>            public void DownloadFile(string fileName)
S>            {
S>                Console.WriteLine("Скачиваем файл " + fileName + " и сохраняем в папку " + _settings.LocalFolder);
S>            }
S>        }

S>        static void Main(string[] args)
S>        {
S>            // Получаем необходимую реализацию через unityContainer
S>            //IFileService fileService = unityContainer.Resolve<IFileService>()
S>            // Для упрощения заменим:
S>            IFileService fileService = new TestFileService();

S>            // Вместо Init можно было бы задействовать InjectionConstructor, но это никак бы не отразилось на контракте.
S>            // По этому в контракте нужно либо сделать свойство Settings, либо метод Init. Поскольку при инициализации не просто устанавливаем значение, а и производим действия -- то метод.
S>            fileService.Init(new Settings {LocalFolder = "C:\\temp"});

S>            fileService.DownloadFile("fileName.txt");
S>        }
S>    }
S>}

S>



Пример похоже слишком простой.
Неясно почему тот же TestFileServices не может в конструкторе принимать Settings.
И вообще какое дело интерфейсу до этого.

Интерфейс описывает желаемое поведение, а как оно задается это дело конкретного класса.
interface IFileService
{
  void DownloadFile(string fileName);
}

class TestFileService : IFileService
{
 public TestFilerService(Settings settings) { .. }
 public void DownloadFile(string fileName) { ... }
}


class AdvancedTestFileService : IFileService
{
 public AdvancedTestFileService(AdvancedSettings settings) { .. } // Тут требуем другие настройки
 public void DownloadFile(string fileName) { ... }
}


class DefaultFileService : IFileService
{
 public DefaultFileService() { .. } // Тут например не требуется ничего.
 public void DownloadFile(string fileName) { ... }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 31.03.16 17:24
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Интерфейс описывает желаемое поведение, а как оно задается это дело конкретного класса.


А что возможность задавать свойства по ошибке в интерфейсы добавили? К примеру см. интерфейс IRelatedEnd. Там и свойства и методы, т.е. не только поведение.

Если я хочу чтобы для всех реализаций были изначально заданы настройки и произведены действия по инициализации с этими настройками. Код, который работает с контрактами ничего не знает о конкретных реализациях. И тем не менее конкретные реализации должны быть проинициализированы с настройками.
Отредактировано 31.03.2016 17:27 Shmj . Предыдущая версия .
Re: Конструктор с параметрами vs метод Init -- стоит ли использо
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.03.16 21:14
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Зато конструктор имеет много минусов. К примеру, Generics не поддерживают создание инстанса если конструктор с параметрами. Так же для XML-сериализации требуется наличие конструктора без параметров, а значит у вас уже не будет той гарантии, ради которой конструкторы вообще задумывались.


А два конструктора, один с параметрами другой без — религия не позволяет иметь?

S>Еще минус, вы не можете добавить новый конструктор в класс с помощью Extensions-методов. Зато можно добавить новый метод Init.


Тоже нельзя. Extensions ничего в классы не добавляют, это просто инфиксная форма записи обычного статического метода.

S>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).


Это не проблема, это фича. Если тебе нужен констракт на создание экземпляра — есть такой паттерн, фабрика.

S>Согласны?


Нет.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Конструктор с параметрами vs метод Init -- стоит ли использо
От: Shmj Ниоткуда  
Дата: 31.03.16 21:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>А два конструктора, один с параметрами другой без — религия не позволяет иметь?


Тогда теряется преимущество -- гарантия того что все обязательные поля проинициализированы. Ведь могут вызвать не тот конструктор.

S>>Еще минус, вы не можете добавить новый конструктор в класс с помощью Extensions-методов. Зато можно добавить новый метод Init.


AVK>Тоже нельзя. Extensions ничего в классы не добавляют, это просто инфиксная форма записи обычного статического метода.


Да мне без разницы как оно внутри устроено. Я что компиляторы или решарперы пишу? Для бизнес-приложения выглядит так, как будто появился новый инстанциональный метод. И это красиво. Можно добавить Init с нужными параметрами а вот чтобы создать класс как бы новым конструктором -- нельзя.

S>>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).

AVK>Это не проблема, это фича. Если тебе нужен констракт на создание экземпляра — есть такой паттерн, фабрика.

Вот пример:

  Скрытый текст
using System;

namespace ConsoleApplication30
{
    class Program
    {
        class Settings
        {
            public string LocalFolder { get; set; }
        }

        interface IFileService
        {
            // Нужно иметь гарантию что установлены настройки
            void Init(Settings settings);

            void DownloadFile(string fileName);
        }

        class TestFileService : IFileService
        {
            private Settings _settings;

            public void Init(Settings settings)
            {
                _settings = settings;
            }

            public void DownloadFile(string fileName)
            {
                Console.WriteLine("Скачиваем файл " + fileName + " и сохраняем в папку " + _settings.LocalFolder);
            }
        }

        static void Main(string[] args)
        {
            // Получаем необходимую реализацию через unityContainer
            //IFileService fileService = unityContainer.Resolve<IFileService>()
            // Для упрощения заменим:
            IFileService fileService = new TestFileService();

            // Вместо Init можно было бы задействовать InjectionConstructor, но это никак бы не отразилось на контракте.
            // По этому в контракте нужно либо сделать свойство Settings, либо метод Init. Поскольку при инициализации не просто устанавливаем значение, а и производим действия -- то метод.
            fileService.Init(new Settings {LocalFolder = "C:\\temp"});

            fileService.DownloadFile("fileName.txt");
        }
    }
}


Покажите на этом примере как правильно.
Re[3]: Конструктор с параметрами vs метод Init -- стоит ли использо
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.03.16 21:40
Оценка:
Здравствуйте, Shmj, Вы писали:

AVK>>А два конструктора, один с параметрами другой без — религия не позволяет иметь?

S>Тогда теряется преимущество -- гарантия того что все обязательные поля проинициализированы. Ведь могут вызвать не тот конструктор.

Только тут проблема не в конструкторах, а в твоих требованиях

AVK>>Тоже нельзя. Extensions ничего в классы не добавляют, это просто инфиксная форма записи обычного статического метода.

S>Да мне без разницы как оно внутри устроено.

Оно устроено так снаружи.

S> Я что компиляторы или решарперы пишу? Для бизнес-приложения выглядит так, как будто появился новый инстанциональный метод.


Нет, не выглядит.

S> Можно добавить Init с нужными параметрами


Нельзя. Потому что Init имеет смысл только если он полиморфный. А статический метод полиморфным быть не может.

S>Покажите на этом примере как правильно.


Ничего не знаю про Unity, поэтому не покажу.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 31.03.16 22:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

S>>Покажите на этом примере как правильно.

AVK>Ничего не знаю про Unity, поэтому не покажу.

В данном примере в Unity делаете регистрацию:

container.RegisterType<IFileService, TestFileService>();


А потом, когда требуется инстанс, пишите:

container.Resolve<IFileService>();


и получаете тот, который ранее зарегистрировали.

У меня парадигма такая:

1. Сначала пишутся контракты (interface) сервисов и бизнес-сущности (можно было бы тоже interface, но для простоты просто классы, т.к. там только поля).
2. Потом параллельно делается внедрение этих контрактов в рабочую библиотеку с тестовыми реализациями и одновременно их реализация (может разными людьми).
3. Замена тестовых заглушек на реальные происходит через Unity, т.е. в рабочем коде ничего изменять не нужно (только переконфигурировать все в 1 месте (там где RegisterType)).

Т.е. разработка начинается с контракта.

Нужно для распараллеливания процесса разработки, структуризации проекта и для упрощения тестирования.

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

Варианты такие:

1. Оставить метод Init(Settings settings). Тогда он берет на себя роль конструктора. Как бы ничего, но доп. проверки и нужно не забывать его вызывать.

2. Оставить в библиотеке контрактов класс Settings, но никак не отображать инициализацию в контрактах (т.е. убрать метод Init(Settings settings)). Тогда можно задействовать конструктор и фичу Unity InjectionConstructor. Можно создавать экземпляр класса через Unity Resolve<IFileService> и передавать нужное значение в конструктор. Тут проблема -- нужно не забывать передавать этот InjectionConstructor а так же требуется чтобы во всех реализациях интерфейса был конструктор с нужным параметром (просто помнить -- никакой подсказки от компилятора не будет).

3. Фабричный метод который тут предлагали. Если я правильно понял, предлагается создать некий IFileServiceFactory с методом CreateFileService(Settings settings) а потом еще и реализацию для него. Реализацию так же получать через Unity, к примеру. Однако же в таком случае нужно помнить что TestFileService/FileService нельзя создавать вручную -- только через реализацию IFileServiceFactory. И не ясно чем это так уж лучше Init.
Отредактировано 31.03.2016 22:42 Shmj . Предыдущая версия .
Re[5]: Конструктор с параметрами vs метод Init -- стоит ли и
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.03.16 23:35
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>и получаете тот, который ранее зарегистрировали.


Ну и дальше надо смотреть как в Unity позвать конструктор с параметром. Еслли никак — выкинуть его в мусорку, IoC контейнеров как грязи (и все уродские, но это отдельный разговор).
Беглый гуглинг подсказал что есть, во-первых, метод RegisterInstance, а во-вторых перегрузки с LifetimeManager в параметрах.

S>Т.е. разработка начинается с контракта.


А если у тестового сервиса какой нибудь специфичный параметр понадобится? К примеру, путь к наборам тестовых данных. Тогда что?

S>И вот у меня дилемма с настройками в примере выше. Включать ли в контракты сведения о настройках.


Какой вопрос — такой ответ: зависит от настроек и дизайна.

S>3. Фабричный метод который тут предлагали. Если я правильно понял, предлагается создать некий IFileServiceFactory с методом CreateFileService(Settings settings)


Часто достаточно просто Func<IFileService>.

S> а потом еще и реализацию для него. Реализацию так же получать через Unity, к примеру.


Зачем?

P.S. А вообще предлагаю начать с того зачем вообще тебе понадобился Unity.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Конструктор с параметрами vs метод Init -- стоит ли использо
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.04.16 02:28
Оценка: 4 (1)
Здравствуйте, Shmj, Вы писали:

S>Зато конструктор имеет много минусов. К примеру, Generics не поддерживают создание инстанса если конструктор с параметрами.


Описал коряво, но суть ясна. Это проблема не конструктора, а языка. В Немерле ее нет. В Шарпе тоже можно устранить.

S>Так же для XML-сериализации требуется наличие конструктора без параметров,


А это проблема XML-сериализатора.

S>Еще минус, вы не можете добавить новый конструктор в класс с помощью Extensions-методов.


Никакой метод нельзя добавить с их помощью. Сделать же внешнюю перегрузку оператора new таки можно. Именно это и сделано в С++. Там это имеет смысл так как можно менять механизм выделения памяти. В дотнете механизм предопределен, так что и механизм смысла не имеет.

Какие на фиг методы-расширения, если их не к чему применять?

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

S>Зато можно добавить новый метод Init.


Куда?

S>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).


Это уже проблема интерфейсов. Если сделать статические интерфейсы, то в принципе можно сделать будет. Но интерфейс принципиально реализуется в объекта, а при создании объекта самого объекта еще нет.

Короче, еще один притянутый за уши "аргумент".

S>Прихожу к пониманию что конструктор с параметрами не гибок и имеет больше минусов, чем плюсов. И лучшее решение всегда создавать конструктор без параметров + метод Init, если нужны параметры для инициализации класса. Если повторная инициализация запрещена -- это легко решается с помощью булевого поля _isInitialized.


S>Согласны?


Согласен с оговоркой. Реализация конструкторов в Шарпе не гибка. Пути увеличения гибкости:
1. Вывод типов позволяющий обойтись без указания параметров типов (есть в Немерле).
2. Возможность использовать конструктор как функцию — передавать туда где требуется делегат (опять же реализовано в Немерле).
3. Можно позволить описывать виртуальные статические функции, т.е. виртуальные методы класса (а не экзмпляра). Это позволит гибче подменять конструктры (есть в Дельфи). По сути это инкапсуляция фабричного метода.
4. Вопрос малость спорный, но все же, еще можно позволить не указывать ключевое слово new. При описании иерархий объектов это дает более чистый код. Но это приводит к неоднозначностям которые должен решать типизатор (что замедляет вывод типов). Опять же есть в Немерле, но на счет этой фичи я не уверен. Проголосовал бы за нее, если был бы уверен, что есть четкие правила разрешение неоднозначностей.

К однозначным плюсам конструкторов относится то, что только в них можно назначать неизменяемые поля. Лично я часто использую неизменяемые объекты, а для них альтернативы конструкторам в донете нет (джит не даст).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Shmj Ниоткуда  
Дата: 01.04.16 10:12
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Часто достаточно просто Func<IFileService>.

AVK>P.S. А вообще предлагаю начать с того зачем вообще тебе понадобился Unity.

А вы что для реализации IoC никакого фреймворка не используете? Только свою Func<IFileService>?
Re: Конструктор с параметрами vs метод Init -- стоит ли использо
От: v6  
Дата: 01.04.16 10:28
Оценка:
Здравствуйте, Shmj, Вы писали:

S>И наверное самая большая проблема -- конструктор нельзя описать с помощью контрактов (interface).


Не уверен, что это проблема. Интерфейс определяет поведение объекта. А на момент вызова конструктора объекта еще нет. С точки зрения поведения объекта это некоторая точка сингулярности.
Чтобы это было непротиворечиво можно вводить какие-то статические интерфейсы, но ценность этого мне не очевидна.

S>Прихожу к пониманию что конструктор с параметрами не гибок и имеет больше минусов, чем плюсов. И лучшее решение всегда создавать конструктор без параметров + метод Init, если нужны параметры для инициализации класса. Если повторная инициализация запрещена -- это легко решается с помощью булевого поля _isInitialized.


S>Согласны?


Нет.
Re[7]: Конструктор с параметрами vs метод Init -- стоит ли и
От: Sinix  
Дата: 01.04.16 10:30
Оценка:
Здравствуйте, Shmj, Вы писали:

S>А вы что для реализации IoC никакого фреймворка не используете? Только свою Func<IFileService>?


Ну вот я знал же, что это очередной XY problem. Прям как по учебнику

Правило большого пальца: если что-то не получается, то надо не обвинять язык/фреймворк, а сесть и изучить матчасть.
Скорее всего за вас на все грабли уже понаступали и решение выложили, осталось только найти и усвоить.

Теперь собственно ответ:
Инициализация сервиса — это ответственность IOC-фреймворка, а не конечного потребителя.
Для Unity это емнип LifetimeManager + resolve with parameters.
также см
http://mikaelkoskinen.net/post/unity-passing-constructor-parameters-to-resolve
Re[2]: Конструктор с параметрами vs метод Init -- стоит ли использо
От: Shmj Ниоткуда  
Дата: 01.04.16 10:39
Оценка:
Здравствуйте, v6, Вы писали:

v6>Не уверен, что это проблема. Интерфейс определяет поведение объекта. А на момент вызова конструктора объекта еще нет. С точки зрения поведения объекта это некоторая точка сингулярности.


Ваша теория расходится с практикой. См. IRelatedEnd. Там и свойства и методы в одном интерфейсе.

v6>Чтобы это было непротиворечиво можно вводить какие-то статические интерфейсы, но ценность этого мне не очевидна.


Почему инициализация определенными параметрами не может быть частью контракта
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.