Множественные синглтоны на C#: Nemerle может помочь?
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 00:25
Оценка:
Звиняйте, если чушь напишу, может не сообразил. Есть не важная задача, речь просто о некрасивости при повторении кода, которую мне не удалось устранить в C#. В макросах Nemerle не силён, но, насколько мне помниться, если что-то может решить проблему, то они. Ну, или я туплю что-то.
Пишу проект на C#, есть примерно такой код:

базовый класс
// Просто базовый класс. Он практически ничего не делает. Объявляет поле статуса операции и то, что операция выполняется через пул потоков
public abstract class getApiData
        {
            protected abstract void calc(Object threadContext);

            protected int      status = 0;
            public    int      Status
            {
                get {return status;}
            }

            public readonly ManualResetEvent endedEvent =  new ManualResetEvent(false);

            public readonly MySqlQuery query;
            public getApiData(MySqlQuery query)
            {
                this.query = query;
            }

            public bool pExec()
            {
                endedEvent.Reset();
                return ThreadPool.QueueUserWorkItem(calc);
            }
    }


один из типичных потомков
public class getEquipmentChilds: getApiData
        {
        // ничего важного: здесь происходит регистрация обработчика события изменения данных
        private getEquipmentChilds(MySqlQuery query): base(query)
            {
                AEUpdateEvent = ComponentDataUpdaterManager.singleManager.insertIntoStartUpdateTarget(ComponentDataUpdaterManager.updateTargets.allEquipment,   updateWordHandler, this, 0);
                updateWordHandler();
            }
            ComponentDataUpdaterManager.handlerUpdateEvent AEUpdateEvent;

            public void updateWordHandler()
            {
                pExec();
            }

                        // Вот этот метод дублируется в каждом классе, его назначение - вызвать статический конструктор, как только сам метод вызван и ничего не делать, если конструктор уже есть
                        // Его нельзя перенести в предок, т.к. тогда инициализироваться при вызове будет именно предок, даже если вызывать явно по имени класса-потомка
                        // Понятно, что его можно заменить макросом, который вставит соотв. код. Но его нужно будет вставлять в каждый класс, а не в потомок.
                        // Возможно ли решение, где каждый класс-потомок сразу будет получать этот код без явного указания макроса или чего бы то ещё, кроме самого факта наследования?
            public static void init()
            {
            }

                        // Вот это поле есть в каждом потомке и называется оно одинаково, но в каждом потомке оно разного типа (собственно, объявляемого типа, это и есть синглтон)
                        // Можно ли его заменить макросом и что для этого потребуется? Можно ли определить такой макрос только в базовом классе (т.е. чтобы потомок не содежал даже упоминания такого макроса)
                        // Можно ли сообщить компилятору, что в каждом классе, наследованном от getApiData,
                        // есть и обязано быть такое поле, что оно является наследником getApiData и его тип совпадает с определяемым типом (в данном случае с типом getEquipmentChilds )?
            public readonly static getEquipmentChilds ewObject  = new getEquipmentChilds(MySqlQuery.query);

                        // Это свойство есть в каждом методе и просто упрощает работу с событием ожидания endedEvent (убирает лишнюю точку)
                        // Его нельзя перенести в предок, т.к. ewObject тоже тогда нужно перенести в предок,
                        // но при этом он потеряет информацию о конкретном типе объекта (станет getApiData),
                        // кроме этого, это свойство представляет статическое поле, которое должно быть одно и только одно на каждый класс.
            public static ManualResetEvent ended
            {
                get
                {
                    return ewObject.endedEvent;
                }
            }

                        // далее ничего интересного и непереносимого даже в C# в потомок нет, кроме блока finally в конце
            public class Child
            {
                public readonly int      id, parent, child;

                public Child(MySqlDataReader reader)
                {
                    id        = reader.GetInt32("ID");
                    parent    = reader.GetInt32("parentCatID");
                    child    = reader.GetInt32("childCatID");
                }
            }

            public SortedList<int, Child> words = null;

            public string errMsg = "";
            public int errCode   = 0;
            protected override void calc(Object threadContext)
            {
                MySqlDataReader reader = null;
                try
                {
                    status = 0;
                    reader = query.executeReader("select ID, parentCatID, childCatID from equipmentChildsView");

                    words = new SortedList<int, Child>(count);
                    while (reader.Read())
                    {
                        words.Add(reader.GetInt32("ID"), new Child(reader));
                    }
                }
                catch (MySqlException e)
                {
                    status  = -1;
                    errMsg  = e.Message;
                    errCode = e.Number;
                }
                catch (Exception e)
                {
                    status = -1;
                    errMsg = e.Message;
                }
                finally
                {
                    try
                    {
                        if (reader != null)
                            reader.Close();
                    }
                    finally
                    {       endedEvent - это свойство, которое, как описано выше, не может быть само по себе перенесено в базвый класс
                        endedEvent.Set();
                    }
                }
            }
        }
Re: Множественные синглтоны на C#: Nemerle может помочь?
От: Ziaw Россия  
Дата: 20.05.10 06:50
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>

FDS> // Вот это поле есть в каждом потомке и называется оно одинаково, но в каждом потомке оно разного типа (собственно, объявляемого типа, это и есть синглтон)
FDS> // Можно ли его заменить макросом и что для этого потребуется? Можно ли определить такой макрос только в базовом классе (т.е. чтобы потомок не содежал даже упоминания такого макроса)
FDS> // Можно ли сообщить компилятору, что в каждом классе, наследованном от getApiData,
FDS> // есть и обязано быть такое поле, что оно является наследником getApiData и его тип совпадает с определяемым типом (в данном случае с типом getEquipmentChilds )?
FDS> public readonly static getEquipmentChilds ewObject = new getEquipmentChilds(MySqlQuery.query);
FDS>


Я ничего не понял в логике, но в любом случае можно написать макрос уровня сборки который будет инжектить все что нужно во все нужные классы.
Re: Множественные синглтоны на C#: Nemerle может помочь?
От: hardcase Пират http://nemerle.org
Дата: 20.05.10 07:04
Оценка: +1 -1
Здравствуйте, FDSC, Вы писали:


Нэйминг ужасен — совершенно неинформативен и не соответствует соглашениям, принятым в .NET (как и в ООПр — ну что за имя класса, начинающееся с глагола get).

Бегло посмотрев описания могу преждложить только один макрос (метаатрибут), который реализует шаблонный код init, ended и поле ewObject (возможно что-то еще), полная автоматизация таковой реализации в наследниках возможна но не приветствуется в рамках вашей задачи. Вообще судя по коду, до макросов еще далековато — то что есть причесать надо бы.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Множественные синглтоны на C#: Nemerle может помочь?
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.05.10 08:34
Оценка:
Здравствуйте, FDSC, Вы писали:

Согласен с предыдущими ораторами.

Код действительно не внятный. Беглый взгляд показывает, что во многом он мог бы быть улучшен банальным использованием обобщенных (generic) типов.

Что касается самого вопроса, то ответ однозначно "да".
Макросы — это одно из средств устранения дублирования кода. Причем самое мощьное. С их помощью можно избавиться практически от любого дублирования. Вопрос только в том нужно ли их для этого применять или есть другие, более простые (более подходящие в данном случае) решения.

Устранение дублирования кода макросами является плохой идеей главным образом потому, что задачи в которых такое дублирование возникает обычно намного лучше решаются с помощью введения DSL-я.

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

Классический пример такой модели — это грамматика языка программирования. По ней можно в автоматическом режиме сгенерировать парсер (или еще что-то, например документацию). Точно так же можно выделить описание своей проблемы и написать макрос (или их группу) который будет читать это описание и генерировать весь необходимый код.

При таком подходе код ужимается в десятки раз. А результата (сгенерированные классы) можно скомпилировать в сборку и использовать из того же C#-а (если надо).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Причёсывание на C#
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 10:04
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>Согласен с предыдущими ораторами.


VD>Код действительно не внятный. Беглый взгляд показывает, что во многом он мог бы быть улучшен банальным использованием обобщенных (generic) типов.


Признаться не понял, как именно.

VD>Устранение дублирования кода макросами является плохой идеей главным образом потому, что задачи в которых такое дублирование возникает обычно намного лучше решаются с помощью введения DSL-я.


Слишком сложно для данной задачи. Насколько я понимаю, создание DSL (я так понимаю, проблемно-зависимый язык) является более мощным и сложным подходом к устранению дублирования, чем макросы, и , главное, сделав DSL я могу прекрасно обойтись и без Nemerle, а я хочу, чтобы это решалось стандартными языковыми средствами. Или я что-то не так понял?
Re[2]: Оффтопик: get в имени класса
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 10:08
Оценка:
Здравствуйте, hardcase, Вы писали:

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



H>Нэйминг ужасен — совершенно неинформативен и не соответствует соглашениям, принятым в .NET (как и в ООПр — ну что за имя класса, начинающееся с глагола get).


Что касается get в имени класса — это хороший нэйминг. Такой нэйминг успешно применяется в крупных фирмах и, с моей точки зрения, удачен (я имею в виду get в методе класса). При создании объекта этого класса он сразу же говорит о том, что его основная задача — это получить данные, по сути, в коде это выглядит почти как вызов функции (просто для этого вызова нужен объект).
Re[2]: Множественные синглтоны на C#: Nemerle может помочь?
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 10:09
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Я ничего не понял в логике, но в любом случае можно написать макрос уровня сборки который будет инжектить все что нужно во все нужные классы.

А можно код например. Хотя бы конкретную ссылку на документацию, как это может выглядеть?
Re[3]: Причёсывание на C#
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.05.10 10:29
Оценка:
Здравствуйте, FDSC, Вы писали:

VD>>Код действительно не внятный. Беглый взгляд показывает, что во многом он мог бы быть улучшен банальным использованием обобщенных (generic) типов.


FDS>Признаться не понял, как именно.


Опиши задачу на словах, при этом стараясь вообще не давать каких либо намеков на твое видение реализации. Тогда можно будет что-то предложить.

VD>>Устранение дублирования кода макросами является плохой идеей главным образом потому, что задачи в которых такое дублирование возникает обычно намного лучше решаются с помощью введения DSL-я.


FDS>Слишком сложно для данной задачи. Насколько я понимаю, создание DSL (я так понимаю, проблемно-зависимый язык) является более мощным и сложным подходом к устранению дублирования, чем макросы, и , главное, сделав DSL я могу прекрасно обойтись и без Nemerle, а я хочу, чтобы это решалось стандартными языковыми средствами. Или я что-то не так понял?


Да, что-то не понял. Дело в том, что макросы — это отличное средство для создания микро-DSL-ей встроенных в основной язык (Nemerle в нашем случае).

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

В отличии от разработки полноценного внешнего DSL-я, создание микро-DSL-ей на Немерле задача во много раз более простая. По сложности она сопоставима с созданием хорошо структурированной обобщенной библиотеки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Причёсывание на C#
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 10:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>>>Код действительно не внятный. Беглый взгляд показывает, что во многом он мог бы быть улучшен банальным использованием обобщенных (generic) типов.


FDS>>Признаться не понял, как именно.


VD>Опиши задачу на словах, при этом стараясь вообще не давать каких либо намеков на твое видение реализации. Тогда можно будет что-то предложить.


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

VD>Да, что-то не понял. Дело в том, что макросы — это отличное средство для создания микро-DSL-ей встроенных в основной язык (Nemerle в нашем случае).

VD>Так вот, твоя задача может быть сведена к описанию входных данных в некотором синтаксисе и к созданию макроса который по этому описанию сгенерирует весь код.

VD>В отличии от разработки полноценного внешнего DSL-я, создание микро-DSL-ей на Немерле задача во много раз более простая. По сложности она сопоставима с созданием хорошо структурированной обобщенной библиотеки.


Это вообще где-то в статьях/документации есть? Как такое чудо создавать и какие подходы при этом использовать. Мне, в общем, не важно, как именно макросы будут работать, я как раз хочу понять подход, как это возможно сделать на Nemerle и насколько затруднительно (особенно если учесть, что макросов я никогда в нём нормально не понимал ).
Re[5]: [оффтопик] А что сейчас с интеграцией?
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 11:37
Оценка:
Влад, а что сейчас с интеграцией Nemerle в VS. Я как-то посмотрел и ничего не понял: для какой студии она есть последняя и где её взять в скомпилированном виде (чтобы SDK не нужен был). Здесь http://nemerle.org/Editors написано VS 2008, а файл называется "NemerleVs2005Integration.exe". В общем, я не понял, что с ней сейчас, раньше как-то понятнее было.
Re[3]: Оффтопик: get в имени класса
От: hardcase Пират http://nemerle.org
Дата: 20.05.10 13:47
Оценка:
Здравствуйте, FDSC, Вы писали:

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


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



H>>Нэйминг ужасен — совершенно неинформативен и не соответствует соглашениям, принятым в .NET (как и в ООПр — ну что за имя класса, начинающееся с глагола get).


FDS>Что касается get в имени класса — это хороший нэйминг. Такой нэйминг успешно применяется в крупных фирмах и, с моей точки зрения, удачен (я имею в виду get в методе класса). При создании объекта этого класса он сразу же говорит о том, что его основная задача — это получить данные, по сути, в коде это выглядит почти как вызов функции (просто для этого вызова нужен объект).


В порядке оффтопа.
Класс — это сущность (имя существительное), методы класса — действия над экземплярами (глаголы), таким образом имя getEquipmentChilds — отличное имя для метода и совершенно дезориентирующее имя для класса.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: [оффтопик] А что сейчас с интеграцией?
От: hardcase Пират http://nemerle.org
Дата: 20.05.10 13:48
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Влад, а что сейчас с интеграцией Nemerle в VS. Я как-то посмотрел и ничего не понял: для какой студии она есть последняя и где её взять в скомпилированном виде (чтобы SDK не нужен был). Здесь http://nemerle.org/Editors написано VS 2008, а файл называется "NemerleVs2005Integration.exe". В общем, я не понял, что с ней сейчас, раньше как-то понятнее было.


Самый свежий билд Немерла можно взять отсюда: http://code.google.com/p/nemerle/downloads/list
/* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: [оффтопик] А что сейчас с интеграцией?
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 13:49
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Самый свежий билд Немерла можно взять отсюда: http://code.google.com/p/nemerle/downloads/list


Немерле — да, а интеграция со студией?
Re[8]: [оффтопик] А что сейчас с интеграцией?
От: hardcase Пират http://nemerle.org
Дата: 20.05.10 13:50
Оценка: 2 (1)
Здравствуйте, FDSC, Вы писали:

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


H>>Самый свежий билд Немерла можно взять отсюда: http://code.google.com/p/nemerle/downloads/list


FDS>Немерле — да, а интеграция со студией?


Там же, они одним пакетом идут.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Оффтопик: get в имени класса
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 13:53
Оценка:
Здравствуйте, hardcase, Вы писали:

H>В порядке оффтопа.

H>Класс — это сущность (имя существительное), методы класса — действия над экземплярами (глаголы), таким образом имя getEquipmentChilds — отличное имя для метода и совершенно дезориентирующее имя для класса.

В данном случае сущность и есть глагол. Те, кто с такими вещами регулярно работает, спокойно к этому относятся, вы просто не привыкли, что объектом может выступать операция. А вот если пытаться для глагольной сущности придумать существительное — получается, как минимум, длиннее и, в лучшем случае, не более понятно. Обычно смысл затуманивается, да, конечно, я могу назвать класс getEquipmentChildsOperation, но будет ли от этого он лучше?
Re[5]: Оффтопик: get в имени класса
От: catbert  
Дата: 20.05.10 15:23
Оценка: -1
Здравствуйте, FDSC, Вы писали:

FDS> Обычно смысл затуманивается, да, конечно, я могу назвать класс getEquipmentChildsOperation, но будет ли от этого он лучше?


Назовите его GetEquipmentChildrenOperation, и он уже станет чуточку лучше А назовёте EquipmentChildrenData, станет ещё лучше. Но главное, как по мне, использовать соглашения фреймворка, на котором работаете. В .NET всегда названия методов и классов начинаются с большой буквы.

В Nemerle, допустим, для создания объекта не используется ключевое слово new. От такого кода (представьте, что ваш клас не синглетон) у нормального человека начинает болеть голова:

def childs = getEquipmentChilds();
childs.init();
...
def children = childs.words;


Кстати, публичные изменяемые поля считаются моветоном.
Re[6]: Оффтопик: get в имени класса с точки зрения немерлист
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 16:13
Оценка:
Здравствуйте, catbert, Вы писали:

C>Назовите его GetEquipmentChildrenOperation, и он уже станет чуточку лучше А назовёте EquipmentChildrenData, станет ещё лучше.


Не думаю

C> Но главное, как по мне, использовать соглашения фреймворка, на котором работаете. В .NET всегда названия методов и классов начинаются с большой буквы.


В .NET всегда было двоякое наименование методов: допускалось и с большой буквы наименовать, и с маленькой, насколько я помню. Классы — да, с большой.

C>В Nemerle, допустим, для создания объекта не используется ключевое слово new. От такого кода (представьте, что ваш клас не синглетон) у нормального человека начинает болеть голова:


C>
C>def childs = getEquipmentChilds();
C>childs.init();
C>...
C>def children = childs.words;
C>


Нет, не так, а вот так (если синглтон)
getEquipmentChilds.init();
getEquipmentChilds.ended.waitOne(); // можно просто getEquipmentChilds.wait() или getEquipmentChilds.waitOfEnd(), если периписать свойство на метод
def childrens = getEquipmentChilds.ewObject.words; // а уж это немерлист спокойно поймёт, т.к. семантика getEquipmentChilds().words, просто скобки убрали


А если назвать так, как вы хотите, то будет
EquipmentChildrenData.init(); // что такое, не понятно, кстати, т.к. явно не данные инициализируются
EquipmentChildrenData.ended.waitOne(); // кого ждём? Данных?
def childrens = EquipmentChildrenData.words; // Да, здесь понятно


Если не синглтон
def operation = getEquipmentChilds();
operation.endedEvent.waitOne();

if (operation.status == 1)
  operation.words;  // без проблем - возвращаем из функции результат операции operation
else
  null;


А если назвать так, как вы хотите, то будет
def data= EquipmentChildrenData();
data.endedEvent.waitOne(); // опять же, кого ждём, данные не могут закончится. Заканчивается операция

if (data.status == 1)  // кого проверяем? Данные не могут иметь статуса - они просто есть, а вот операция имеет статус
  data.words;          // здесь понятно
else
  null;



C>Кстати, публичные изменяемые поля считаются моветоном.


Согласен, можно добавить лишнее свойство для ErrCode и ErrMsg, но это не суть важно. В данном случае это совершенно ничему не мешает, а писать лишний код только для того, чтобы он соответствовал всем канонам программирования — увольте: я пишу так, как мне удобно, там, где это может повредить, все публичные поля помечены как readonly (да и возится с защитой списка через предоставление интерфейса — я считаю, что это "моветон" практически всегда, это я вместо дела только и буду сам от себя защищать очевидные вещи и мешать, тем самым, себе программировать, т.к. инумератор обладает ограниченными возможностями и всё равно придётся в итоге открывать этот список).
Re[7]: небольшая обшибка
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 16:37
Оценка:
Здравствуйте, FDSC, Вы писали:

ошбшибся, см. выделенное жирным

FDS>Если не синглтон

def operation = getEquipmentChilds();
operation.pExec();                     // запускаем метод получения данных
operation.endedEvent.waitOne();

if (operation.status == 1)
  operation.words;  // без проблем - возвращаем из функции результат операции operation
else
  null;


FDS>А если назвать так, как вы хотите, то будет

def data= EquipmentChildrenData();
data.pExec();                         // запускаем что? Данные?
data.endedEvent.waitOne(); // опять же, кого ждём, данные не могут закончится. Заканчивается операция

if (data.status == 1)  // кого проверяем? Данные не могут иметь статуса - они просто есть, а вот операция имеет статус
  data.words;          // здесь понятно
else
  null;
Re[8]: небольшая обшибка
От: Ziaw Россия  
Дата: 20.05.10 16:56
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>>А если назвать так, как вы хотите, то будет

FDS>
FDS>def data= EquipmentChildrenData();
FDS>data.pExec();                         // запускаем что? Данные?
FDS>data.endedEvent.waitOne(); // опять же, кого ждём, данные не могут закончится. Заканчивается операция

FDS>if (data.status == 1)  // кого проверяем? Данные не могут иметь статуса - они просто есть, а вот операция имеет статус
FDS>  data.words;          // здесь понятно
FDS>else
FDS>  null;
FDS>


В чем проблема? процесс назовем EquipmentChildrenReader, дадим ему 2 публичных метода, Read и ReadAsync.

Не очень понятно что этот класс абстрагирует, если процесс асинхронного чтения — зачем ему ORM функции? Кто гарантирует, что запрос выбирает то, что захардкоженно в классе? Мой совет — взять блтулкит и не изобретать ORM.

Я не юзал MySql, но в других базах шарить один конекшн на несколько тредов противопоказано, в вашей архитектуре очень неопределенно время жизни конекшена и транзакции.

Не увидел никакого смысла в статиках, кроме головной боли.
Re[9]: [оффтопик]: глагол get в имени класса
От: FDSC Россия consp11.github.io блог
Дата: 20.05.10 17:12
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>В чем проблема? процесс назовем EquipmentChildrenReader, дадим ему 2 публичных метода, Read и ReadAsync.


Не против. Только get короче писать, чем Reader, кроме этого, если нужно что-то получить, потом вводишь .get, а VS сама тебе предлагает разные варианты, с Reader так не получится — неудобно.

Z>Не очень понятно что этот класс абстрагирует, если процесс асинхронного чтения — зачем ему ORM функции? Мой совет — взять блтулкит и не изобретать ORM.


1. Производительность. Я в своё время пользовался hibernate, в связи с тем, что работало это полчаса вместо 1-ой минуты своего sql: больше никогда не использую такие вещи.
2. Мне легче написать класс, чем настроить какой-либо инструмент автоматического извлечения
3. Я не знаю, что он будет делать, если часть данных поменяется (может, он всю базу заново выкачает?)
4. Всё равно останутся классы изменения таблиц
5. Что будет, если у пользователя нет прав на получение таблицы?
6. Я не люблю, когда всё не очень удобно и при этом не под контролем, а ORM — это не удобно (по крайней мере, прежде чем станет удобно, пройдёт много времени) и существенно уменьшает уровень контроль над чтениями БД.


getApiData абстрагирует процесс асинхронного чтения
Его потомки: конкретную операцию по получению таблиц и, в случае необходимости, их обработки

Z> Кто гарантирует, что запрос выбирает то, что захардкоженно в классе?

Не понял вопроса.

Z>Я не юзал MySql, но в других базах шарить один конекшн на несколько тредов противопоказано, в вашей архитектуре очень неопределенно время жизни конекшена и транзакции.


А кто шарит коннекшн на несколько тредов?
Время транзакции определено и коннекшена определено (если не считать ConnectionPooling, т.е. того, что брошенный мною коннект может быть не закрыт, а отдан для дальнейшего использования)
Даже не понял, с чего вы взяли, что это не так

Z>Не увидел никакого смысла в статиках, кроме головной боли.


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