Re[2]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.09.23 12:38
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Я читал, что это анти-паттерн. Но как сделать по другому?

Сделайте Adapter параметром метода Init.

Z>Второй вопрос. Кто (какой объект) должен отвечать за проверку типа базы и создание конкретного Адаптера?

Очевидно, AdapterFactory.

Приведённый вами случай отличается от заявленного в начале топика.
Тут у вас инициализация ридера требует фиксированного набора параметров, поэтому ничто не мешает внести их в метод Init (раз уж вы твёрдо решили обойтись без параметров в конструкторе).
По крайней мере у вас чётко будет 2 состояния у объекта: до инициализации и после инициализации; и гарантированно не будет "недоинициализированного" объекта (как могло бы быть, если бы установка отдельных свойств делалась отдельными вызовами со сложным ветвлением).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: zelenprog  
Дата: 14.09.23 07:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Приведённый вами случай отличается от заявленного в начале топика.


Отличается только как частное к общему: последний пример — это частный случай той проблемы, которая была описана в первом топике.

S>Тут у вас инициализация ридера требует фиксированного набора параметров, поэтому ничто не мешает внести их в метод Init (раз уж вы твёрдо решили обойтись без параметров в конструкторе).

S>По крайней мере у вас чётко будет 2 состояния у объекта: до инициализации и после инициализации; и гарантированно не будет "недоинициализированного" объекта (как могло бы быть, если бы установка отдельных свойств делалась отдельными вызовами со сложным ветвлением).

Во-о-от. То есть от метода Init в данной ситуации нельзя избавиться. Причем этот метод придется использовать в большинстве классов.
Получается, использование метода Init надо "подчинить" каким-то правилам, чтобы везде его использование в коде было однозначным.
То есть мы приходим к необходимости "оформления" нового "шаблона" создания и инициализации объектов.
Об этом я и спрашивал в первом топике: "есть ли какие-либо устоявшиеся шаблоны\методики\практики более "гибкого" выделения ресурсов в дополнение к конструктору класса"?

Ведь для уничтожения объектов разработали общепринятый IDisposable.
Значит, еще нужен и IInitialaizable.
Re[4]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.09.23 11:16
Оценка: +1
Здравствуйте, zelenprog, Вы писали:

Z>Ведь для уничтожения объектов разработали общепринятый IDisposable.

Z>Значит, еще нужен и IInitialaizable.

Положа руку на сердце, это выглядит как решение искусственно созданной проблемы.
Вот в дотнете конструктор уже является "методом Init", просто языки вроде C# более-менее следят за тем, чтобы не дать программисту воспользоваться объектом в недоинициализированом состоянии.
С точки зрения CLR, к моменту вызова конструктора объект уже полностью сконструирован — у него корректная VMT, и в полях нет никакого булшита (который мог бы помешать работе GC — например, случайные ссылки).
То есть авторы шарпа постарались максимально скрыть от пользователя этот зазор между "конструктором" и "Init". А вы зачем-то выпячиваете его наружу.
Фактически, тщательно переносите в рантайм проверку, которую прекрасно мог взять на себя компилятор.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: zelenprog  
Дата: 15.09.23 10:52
Оценка:
S>Положа руку на сердце, это выглядит как решение искусственно созданной проблемы.

Это не искусственная проблема.
Это особенность "моей" платформы.

S>Вот в дотнете конструктор уже является "методом Init", просто языки вроде C# более-менее следят за тем, чтобы не дать программисту воспользоваться объектом в недоинициализированом состоянии.

S>С точки зрения CLR, к моменту вызова конструктора объект уже полностью сконструирован — у него корректная VMT, и в полях нет никакого булшита (который мог бы помешать работе GC — например, случайные ссылки).
S>То есть авторы шарпа постарались максимально скрыть от пользователя этот зазор между "конструктором" и "Init". А вы зачем-то выпячиваете его наружу.
S>Фактически, тщательно переносите в рантайм проверку, которую прекрасно мог взять на себя компилятор.

>> авторы шарпа постарались максимально скрыть от пользователя этот зазор между "конструктором" и "Init". А вы зачем-то выпячиваете его наружу.

>> Фактически, тщательно переносите в рантайм проверку, которую прекрасно мог взять на себя компилятор.

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

Приходится "вручную" добавлять эти недостающие возможности ООП.
Re[2]: "Гибкий" конструктор для инициализации объекта класса
От: Sm0ke Россия ksi
Дата: 15.09.23 11:38
Оценка:
Здравствуйте, zelenprog

Можно сделать вспомогательные функции приложения таким образом, чтобы ...
// global function
I_DBAdapter MakeDBAdapter(string pFileName) // 1
{
  I_DBAdapter lDBAdapter = null;
  T_DatabaseInfo lDatabaseInfo = new T_DatabaseInfo(pFileName);
  
  if lDatabaseInfo.DBType = Database.DBType1 then
    lDBAdapter = new T_DBAdapter1(pFileName);
  elseif lDatabaseInfo.DBType = Database.DBType2
    lDBAdapter = new T_DBAdapter2(pFileName);
  else
    // исключение "неизвестный тип БД
  endif
  
  return lDBAdapter;
}

// global function
T_DBGoodsReader MakeDBGoodsReader(string pFileName) // 2
{
  T_DBGoodsReader lDBGoodsReader = new T_DBGoodsReader;
  I_DBAdapter lDBAdapter = MakeDBAdapter(pFileName); // 1
  
  lDBGoodsReader.SetAdapter(lAdapter);
  lDBGoodsReader.Init();
  
  return lDBGoodsReader;
}

... Чтобы их было легче использовать
Class MainForm
{
  string mFileName;
  
  void OnButton_ReadDatabase()
  {
    T_DBGoodsReader lDBGoodsReader = MakeDBGoodsReader(mFileName); // 2
    
    lDBGoodsReader.Read();
    
    // показать на форме список товаров
  }
}


--
Я просто переорганизовал ваш код

Z>
Z>Class MainForm
Z>{
Z>    string mFileName;
    
Z>    void OnButton_ReadDatabase()
Z>    {
Z>        T_DatabaseInfo lDatabaseInfo = new T_DatabaseInfo(mFileName);
Z>        T_DBGoodsReader lDBGoodsReader = new T_DBGoodsReader;
Z>        I_DBAdapter lDBAdapter = null;
        
Z>        if lDatabaseInfo.DBType = Database.DBType1 then
Z>            lDBAdapter = new T_DBAdapter1(mFileName);
Z>        elseif lDatabaseInfo.DBType = Database.DBType2
Z>            lDBAdapter = new T_DBAdapter2(mFileName);
Z>        else
Z>            // исключение "неизвестный тип БД
Z>        endif
        
Z>        lDBGoodsReader.SetAdapter(lAdapter);
Z>        lDBGoodsReader.Init();
Z>        lDBGoodsReader.Read();
        
Z>        // показать на форме список товаров
Z>    }
Z>}
Z>
Отредактировано 15.09.2023 11:40 Sm0ke . Предыдущая версия .
Re: maker generated
От: Sm0ke Россия ksi
Дата: 25.09.23 22:30
Оценка:
Здравствуйте, zelenprog:

У вас есть возможность доработать ваш компилятор?

Скажем чтобы он мог сгенерировать для класса SomeClass
... глобальную функцию SomeClass_make()
... в которой параметры те-же, что и в методе Init() того же класса
а тело функции make примерно такое:
SomeClass_make(int param1, string param2)
{
  SomeClass ret = new SomeClass;
  ret.Init(param1, param2);
  return ret;
}

Чтобы просто форвардить параметры в init

т.е Компилятор знает параметры в init и может их обработать, так?

Но если в классе нет init, то и SomeClass_make() видимо не нужен.
Отредактировано 25.09.2023 22:30 Sm0ke . Предыдущая версия .
Re[6]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: Разраб  
Дата: 26.09.23 02:13
Оценка:
Здравствуйте, zelenprog, Вы писали:

S>>Положа руку на сердце, это выглядит как решение искусственно созданной проблемы.


Z>Это не искусственная проблема.

Z>Это особенность "моей" платформы.
1С?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[7]: "Гибкий" конструктор для инициализации объекта класса (аналог Dispose)
От: zelenprog  
Дата: 26.09.23 05:41
Оценка: +1
Здравствуйте, Разраб, Вы писали:

Z>>Это не искусственная проблема.

Z>>Это особенность "моей" платформы.
Р>1С?

Да. Не хотелось этого афишировать.
Боюсь, что упоминание про 1С уведет обсуждение в сторону.
А мне хотелось бы и на 1С написать программу с "правильным" подходом и "правильной" архитектурой. Нужно только придумать как грамотно преодолеть некоторые ограничения платформы.
Re[2]: maker generated
От: zelenprog  
Дата: 26.09.23 05:43
Оценка:
S>У вас есть возможность доработать ваш компилятор?

Нет такой возможности.

S>Скажем чтобы он мог сгенерировать для класса SomeClass

S>... глобальную функцию SomeClass_make()
S>... в которой параметры те-же, что и в методе Init() того же класса
S>а тело функции make примерно такое:
S>
S>SomeClass_make(int param1, string param2)
S>{
S>  SomeClass ret = new SomeClass;
S>  ret.Init(param1, param2);
S>  return ret;
S>}
S>

S>Чтобы просто форвардить параметры в init

Так это просто Фабрика?
Re[3]: maker generated
От: Sm0ke Россия ksi
Дата: 26.09.23 12:10
Оценка:
Здравствуйте, zelenprog, Вы писали:

S>>Скажем чтобы он мог сгенерировать для класса SomeClass

S>>... глобальную функцию SomeClass_make()
S>>... в которой параметры те-же, что и в методе Init() того же класса
S>>а тело функции make примерно такое:
S>>
S>>SomeClass_make(int param1, string param2)
S>>{
S>>  SomeClass ret = new SomeClass;
S>>  ret.Init(param1, param2);
S>>  return ret;
S>>}
S>>

S>>Чтобы просто форвардить параметры в init

Z>Так это просто Фабрика?


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