>_< Коллеги-программисты. Не нужно подменять понятия. Абстрактный класс для разбития описания взаимосвязанных классов мне нужен не для абстракции. Я НИГДЕ больше не буду его использовать, кроме как в одном месте - заткнуть дыру негибкий возможностей пространства имён. Какой смысл мне от такой абстракции? Держать ещё 100+ строк кода, которые нужно все-время поддерживать в актуальном состоянии? Оборачивать каждый вызов метода реального класса пробежкой по таблице абстрактного класса? И не нужно, возвращаясь к примеру со школой, помещать в школьный класс людей. Там учатся школьники. Повторюсь, с оценками. У базового класса "Люди" оценок быть не должно. Как-то так.
Добавлено спустя 6 минут 17 секунд: Люди. Ещё раз посмотрите на пример
Type ClassB = Class Public Property A: ClassA Read fA; End;
Type ClassA = Class Public Property B: ClassB Read fB; End;
Поднимите руку те, кто никогда так не делал? Задам 1 вопрос: Почему вы считаете, что то что эту конструкцию средствами паскаля невозможно разбить на 2 файла без обходных путей с абстрактными классами или директивами компилятору - норма?
Brainenjii писал(а):Абстрактный класс для разбития описания взаимосвязанных классов мне нужен не для абстракции. Я НИГДЕ больше не буду его использовать, кроме как в одном месте - заткнуть дыру негибкий возможностей пространства имён.
Вы возводите частный случай в практику. Абстракция вам позволяет провести правильную декомпозицю данных. При этом, она попутно решает вашу проблему.
Brainenjii писал(а):очему вы считаете, что то что эту конструкцию средствами паскаля невозможно разбить на 2 файла без обходных путей с абстрактными классами или директивами компилятору - норма?
Потому что это врождённая особенность паскаля. Вся его идеология строится на нисходящем програмировании, вплоть до синтаксиса. Вы не можете использовать то, что ещё не объявили.
Указатели - это исключение из правил.
При развитии языка конечно появились обходные методы и костыли, которые ломают эту идеологию. Но лучше всёже оставаться в рамках этих правил.
alexs писал(а):Потому что это врождённая особенность паскаля. Вся его идеология строится на нисходящем програмировании, вплоть до синтаксиса.
Проблема, скорее, в реализации модульности в OP. Каждый модуль имеет секции инициализации и финалиэации. Компилятор гарантирует, что секция инициализации будет выполнена до начала использования модуля. При наличии циклических ссылок это невозможно.
Пробежал по этой теме (дискуссия интересная), но выводы из нее получаются следующие:
1. Каждый язык программирования, в т.ч. Паскаль имеют свои удобства и свои неудобства, свои "+", и свои "-". Особенность языка нужно считать данностью. Расширять язык нужно очень аккуратно, сто раз подумав. Очень часто фичу, требуемую одним, другие используют в противоположном значении. Например, быструю компиляцию в Паскале многие используют как инструмент рефакторинга. Изменил имя (место расположения и т.п.) и смотришь на полученные ошибки (что есть ссылки на использование элемента). Введя пространство имен в его трактовке С# в угоду одним, мы можем получить кучу проблем для других.
2. На то, что указал создатель темы - это реальное ограничение языка Паскаль. Сегодня для устранения нужно либо использовать другой язык, либо использовать модули и наследование, когда в одном модуле описаны все классы с данными и перекрестными ссылками, но нет функционала (есть только абстрактные, либо очень простые методы). А далее в других модулях абстрактная структура данных (что и есть предметная область задачи) насыщается функциями.
3. Оппоненты автора темы с одной стороны говорят правильные вещи, но они не правы по сути, т.к. они говорят о другом. Многие разработчики которые часто используют БД зацикливаются на своих БД. БД - это частный случай. В общем случае данные могут вообще нигде не храниться. А алгоритм создания и удаления может быть намного сложнее, чем контроль битых ссылок.
4. Считаю, что в любой задаче самое главное - это описание задачи, предметная область и конечная технология (не программная, а пользовательская). Программирование не самоцель, а способ решения задачи. Иногда бывает, что для решения задачи вообще не нужно программировать. Так вот, если задача формулируется как хранение и обработка больших массивов структурированных данных, то в качестве средства выбирается СУБД и выполняется нормализация данных предметной области.
5. Но ведь бывают и другие задачи. Например, есть предметная область (физика, техника, социология и т.п.), данные пусть есть, как-то редактируются и хранятся, пусть хранятся в СУБД в нормализованном виде. Но редактирование и хранение уже реализовано и работает как часы. А стоит задача выполнить обработку. Часто обработка на много сложнее, чем задача редактирования и хранения. Данные бывают очень сложными, а процедуры их обработки будут занимать часы, дни, недели и даже годы. В этом случае возникают требования с одной стороны сделать данные наглядными для описания алгоритма обработки (например, математические формулы), а с другой стороны сохранить быстродействие. Работа с нормализованными данными не приемлема в принципе, т.к. очень медленная, даже с самыми навороченными алгоритмами поиска и сортировки. В такой реализации ввод данных с нуля будет занимать один день, а обработка 1000 лет (пользователь умрет раньше, чем получит результат). Нужны банальные прямые ссылки (указатели на объекты). Здесь и возникает проблема, описанная автором топика, см. п.1 и п.2. И это делается не всегда удобно, но неудобство косметическое, т.к. вынос всей предметной области в один модуль (без функционала) как раз удобнее, чем ее разнесение по 20 модулям. Кстати, с позиции нормализации данных тоже нет никаких проблем. Читаем данные из СУБД, создаем классы под нормализованные данные, и затем в отдельной функции создаем перекрестные ссылки, после изменения состава данных (добавил, удалил, изменил), нужно заново пересоздать все перекрестные ссылки.
Тоже все время сталкиваюсь с этой проблемой, приходится решать как в 6-м посте (через абстрактного предка). В чем-то это даже логично, хотя и неудобно.
alexey38 писал(а):5. Но ведь бывают и другие задачи. Например, есть предметная область (физика, техника, социология и т.п.), данные пусть есть, как-то редактируются и хранятся, пусть хранятся в СУБД в нормализованном виде. Но редактирование и хранение уже реализовано и работает как часы. А стоит задача выполнить обработку. Часто обработка на много сложнее, чем задача редактирования и хранения. Данные бывают очень сложными, а процедуры их обработки будут занимать часы, дни, недели и даже годы. В этом случае возникают требования с одной стороны сделать данные наглядными для описания алгоритма обработки (например, математические формулы), а с другой стороны сохранить быстродействие. Работа с нормализованными данными не приемлема в принципе, т.к. очень медленная, даже с самыми навороченными алгоритмами поиска и сортировки. В такой реализации ввод данных с нуля будет занимать один день, а обработка 1000 лет (пользователь умрет раньше, чем получит результат). Нужны банальные прямые ссылки (указатели на объекты). Здесь и возникает проблема, описанная автором топика, см. п.1 и п.2. И это делается не всегда удобно, но неудобство косметическое, т.к. вынос всей предметной области в один модуль (без функционала) как раз удобнее, чем ее разнесение по 20 модулям. Кстати, с позиции нормализации данных тоже нет никаких проблем. Читаем данные из СУБД, создаем классы под нормализованные данные, и затем в отдельной функции создаем перекрестные ссылки, после изменения состава данных (добавил, удалил, изменил), нужно заново пересоздать все перекрестные ссылки.
Неужели выгрести из базы данных данные таблиц в структуры паскаля и обрабатывать в объекты в памяти быстрее , чем обработать данные таблиц на SQL сервере с помощью процедуры ?
А memory таблицы на sql сервере зачем ? Зачем жонглировать объектами, если есть таблицы.
Ism писал(а):Неужели выгрести из базы данных данные таблиц в структуры паскаля и обрабатывать в объекты в памяти быстрее , чем обработать данные таблиц на SQL сервере с помощью процедуры ? А memory таблицы на sql сервере зачем ? Зачем жонглировать объектами, если есть таблицы.
Насколько я знаю, memory таблицы на sql сервере нужны для решения своего класса задач. Но не для всех задач они нужны.
Вот две задачи из моей практики: 1. В одном случае данные - это описание графа (узлы и ветви) с параметрами. Нужно выполнить задачи по эквивалентированию: поиск последовательных и парралельных ветвей, некие преобразования. Напишите на SQL для начала хотя бы банальное хождение по графу, проверку его связанности, поиск альтернативных маршрутов. Как это быстро и просто написать на паскале с использованием классов и рекурсии я знаю (около 10 строк кода). А как на SQL сервере в виде memory таблиц не знаю. Поделитесь опытом?
2. В данных заданы параметры модели. Решение задачи - это итеративный процесс численного решения дифференциальных уранвнений. Не приведете пример решения систем линейных уравнений, и численного интегрирования на SQL сервере с помошью memory таблиц? Небольшой момент - некоторые параметры это комплексные числа (формулы оперирования известны), но я не встречал библиотек для работы с комплексной алгеброй и матрицами для SQL сервера, хотя таблица и матрица это почти одно и тоже. Напишите хотя бы умножение двух матриц на SQL сервере с помошью memory таблиц. Задача как мне кажется решается несложно (хотя и громоздко). Но как быстро это будет работать?
P.S. Самое смешное, что объем данных, сохраненных в виде текстового файла будет несколько кБ. А решение задачи и без SQL сервера заниает приличное время. На кой нужен SQL сервер, для хранения таблицы из 100-500 записей?
Взаимные сссылки в секциях INTERFACE классов, определенные в разных модулях можно делать через интерфейсы (полиморфизм в данном случае). Грубо говоря : -------------------------- unit common;
inteface
type intf1 = interface .. intf2 = interface ---------------------- unit class1;
interface
uses common;
type class1 = class(intf1) class1func1(const class2ref: intf2); ..
---------------------- unit class2;
interface
uses common;
type class2 = class(intf2) class2func1(const class1ref: intf1); --------------------------