Форум: "Основная";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
Внизкопирование объектов... Найти похожие ветки
← →
Makhanev Alexander (2006-10-27 09:32) [0]Есть объект класса, наследника от tpersistent.
делаю assign с другим объектом того же класса - говорит "не могу assign Класс1 к Класс1".
Как решить такое в delphi?
Писать свой assign?
PS: привык к vs 2005 - легко там с этим было...
← →
MBo © (2006-10-27 09:35) [1]Да, нужно Assign(To) реализовать
← →
Юрий Зотов © (2006-10-27 09:42) [2]Причин может быть две:
1. Не перекрыт метод Assign и/или AssignTo. В итоге вызывается унаследованный Assign, тот вызывает унаследованный AssignTo, а тот выдает ошибку.
2. Параметром передается объект из другого модуля (например, DLL), а он имеет свою VMT и поэтому рассматривается, как экземпляр другого класса. В итоге is выдает false и возникает ошибка.
← →
Makhanev Alexander (2006-10-27 09:54) [3]Мой вариант - первый (Не перекрыт метод Assign).
Значит, мне надо руками его делать?
Реализовывать логику копирования всех свойств.... (среди которых куча объектов, иерархий массивов объектов и т.п.) ?
← →
Сергей М. © (2006-10-27 09:57) [4]
> мне надо руками его делать?
> Реализовывать логику копирования всех свойств
Совершенно верно.
Кому как не самому объекту знать, какие его св-ва и в какой последовательности следует назначить конкретному "целевому" объекту конкретного целевого класса ?
← →
StriderMan © (2006-10-27 09:58) [5]как вариант, можно унаследоваться от TComponent и через поток все скопировать
← →
Сергей М. © (2006-10-27 09:59) [6]
> копирования всех свойств
Не обязательно всех.
Реализуя AssignTo() ты сам определяешь, какие св-ва следует копировать, а какие не следует.
← →
Makhanev Alexander (2006-10-27 10:13) [7]
> StriderMan © (27.10.06 09:58) [5]
> как вариант, можно унаследоваться от TComponent и через
> поток все скопировать
Засада....
Опишу задачу поконкретнее, немного упростив:
Вопрос собственно в том, что есть форма-редактор объекта. В ней, грубо говоря, может быть нажато как OK так и Cancel.
В случае с Cancel мы не сохраняем изменения.
Так вот, нужен "буферный" объект-копия исходного, чтоб временно хранить изменения в нем и в зависимости от OK или Cancel сохраняться в исходный объект или не сохраняться.
Если нельзя копировать объекты, то придется хранить временные изменения в самих компонентах формы, либо в других левых сущностях - что есть плохо (сменили компонент - косяк, да и работа двойная получается).
Или есть иные варианты реализации отката изменений по Cancel?
← →
StriderMan © (2006-10-27 10:19) [8]
> Makhanev Alexander (27.10.06 10:13) [7]
А исходный вариант где хранится? в файли или в БД? у меня аналогичный редактор, так вот там форма с кмопнентами хранится в блобе БД. когда юзер жмет "редактировать", форма полнимается из Блоба, запускается редактор. Если после редактирования юзер нажал отмена - ничего обратно в БД не сохранится.
Еще брался как-то делать откат изменений (Undo). Для этого создавал массив в который делались копии всей формы при каждом изменении, но эту фичу пока не доделал. так вот, копии делались как раз через поток.
← →
Юрий Зотов © (2006-10-27 10:22) [9]> придется хранить временные изменения в самих компонентах формы
А они и так в них хранятся. Это те самые визуальные контролы, с помощью которых и производится редактирование.
Но идеологически правильнее все же перекрыть AssignTo.
← →
ЮЮ © (2006-10-27 10:23) [10]
> придется хранить временные изменения в самих компонентах формы
> формы,
А исходные разве не "хранятся" в "самих компонентах формы"? Они ведь настраиваются исходя из св-в объкта?! Соответственно по Ok - lделать обратное - устанавливать св-ва объекта исходя из элементов формы.
← →
Makhanev Alexander (2006-10-27 10:41) [11]
> Юрий Зотов © (27.10.06 10:22) [9]
> > придется хранить временные изменения в самих компонентах
> формы
>
> А они и так в них хранятся. Это те самые визуальные контролы,
> с помощью которых и производится редактирование.
>
Не, хранить в контролах - имхо неверно. Контролы только для отображения, а если они сами чего-то хранят - ради бога, пусть хранят, но "для себя".
А в более сложном случае UI - когда один контрол отображает 2 объекта по очереди и потом всё можно откатить - и контролы не спасут. Придется либо делать промежуточный сейв, либо - копию объектной модели через assign
> Но идеологически правильнее все же перекрыть AssignTo.
Я ж про то же.
Я жил без этого, пока в VS не окунулся...
Теперь в delphi отвыкать от тотального ООП сложно. По крайней мере в той его части, о которой мы сейчас говорим - копирование объектов.
> ЮЮ © (27.10.06 10:23) [10]
>
> А исходные разве не "хранятся" в "самих компонентах формы"?
> Они ведь настраиваются исходя из св-в объкта?! Соответственно
> по Ok - lделать обратное - устанавливать св-ва объекта исходя
> из элементов формы.
Не... всё хранит объектная модель. Контролы, формы - вторичны. Они лишь редакторы, а не хранилки.
Т.е. получается такая вот картина:
БД - Объектная модель - Контролы.
Это уже кстати суперски сделано в SQL2005 (БД - Объектная модель), да и сериализация в VS тоже клевая вещь... а в Delphi.... молчу, дабы не вызвать holywar))
А может есть какая-нить левая делфевая примочка, которой пофиг какого класса объект и она сделает copyto кому угодно и в любое время?
← →
Makhanev Alexander (2006-10-27 10:43) [12]Сейчас вспомним про запись компонентов в поток...но че-то мне кажется, что это через одно место будет работать...мне tcomponent там вообще даром не нужен был))
← →
Юрий Зотов © (2006-10-27 11:02) [13]> Makhanev Alexander (27.10.06 10:43) [12]
TPersistent тоже можно писать в поток. Он для того и создан.
Но перекрыть AssignTo, пожалуй, проще будет...
:о)
← →
Makhanev Alexander (2006-10-27 11:03) [14]немного иными словами - middle-tier (или уровень "бизнес логики") в Delphi кто-нибудь делал удачно?
сейчас больше склоняюсь к такому варианту:
исходного объекта нет, есть БД.
каждый раз когда надо откатить изменение - читаем объект из БД заново.
минус - частое чтение БД
плюс - соблюдение идеологии разграничения уровней приложения, что мне дороже)
Возможно эти проблемы и не возникают так сильно, когда ui прост и незамысловат (форм может быть много, но лишь бы их возможности были невелики). В моем случае ui сложен и может меняться, в зависимости от фидбеков. Каждый раз переделывать из-за этого кучу кода - лень и непрально ("плавали, знаем"=))). Всё что надо переделать в таком случае - отрисовку объектов в контрол.
← →
Makhanev Alexander (2006-10-27 11:04) [15]
> Юрий Зотов © (27.10.06 11:02) [13]
> > Makhanev Alexander (27.10.06 10:43) [12]
>
> TPersistent тоже можно писать в поток. Он для того и создан.
>
>
> Но перекрыть AssignTo, пожалуй, проще будет...
> :о)
Руками прописать весь процесс клонирования? А если я потом меняю модель? опять обновлять assign - так?
← →
ЮЮ © (2006-10-27 11:06) [16]
> Контролы, формы - вторичны. Они лишь редакторы, а не хранилки.
Но
1) они принимают какие-то значения, в зависимости от свойств объекта
2) изменяют свойства объекта после изменения своих свойств
если 2) разделить на
2а) изменяют свои свойства
2б) изменяют св-ва объекта исходя из своих свойств
и 2б) применять лишь по кнопке "ОК".
З.Ы. Если, конечно же на форме не требуется видеть визуальные последствия изменеия свойст именно объекта, а не контролов формы.
← →
Makhanev Alexander (2006-10-27 11:20) [17]
> ЮЮ © (27.10.06 11:06) [16]
> Но
> 1) они принимают какие-то значения, в зависимости от свойств
> объекта
> 2) изменяют свойства объекта после изменения своих свойств
не, немного не так (не в смысле, что Вы не правы, а в смысле, что у меня не так..):
1)они принимают какие-то значения и сразу передают их в объект. сами по себе они не в состоянии отобразить эти значения (без связи с другими данными).
2)они лишь отображают то, что им скажет объект.
Это моя практика. У меня так реально легче получается и баги быстрее находятся и код легче понимать - т.е. строгое разделение уровней.
UI максимально не лезет в бизнес логику, а лишь отображает ее или предоставляет ей инпуты юзера.
Чем больше смешивается UI с БЛ, тем сложнее потом отладка и изменения.
Хотя, не спорю, часть вещей можно и в UI сразу делать (напр. банально проверку введенных данных, тобеж, валидацию..).
И еще косяк - когда чтолибо хранится в контроле (именно хранится, а не передается на лету в объект), то получается что данные в объект поступают с двух фронтов (снизу - БД, сверху - контрол). Таким образом растет возможное поле для багов. Минимизируя то что приходит "сверху" вызовом тех же методов загрузки данных, котрые юзаются "снизу", мы минимизируем поле для багов. Т.е. вероятность падает.
Это тоже из опыта сравнения delphi приложения и multi-tier приложения в VS. Более того, в VS делал приложение и по "старинке", результат был ужасно глючным.
Конечно, всё дело в программисте и если он не ошибается, то ему любой подход подойдет.. НО - я ошибуюсь всегда и везде, баги - сущность постоянная и, к сожалению, я лишь управляю вероятностью их возникновения, а не их наличием.
← →
Makhanev Alexander (2006-10-27 16:49) [18]В результате: частая загрузка данных из БД не понравилась, поэтому сделал поддержку assignto для всей иерархии классов и пока полет отличный.
Всем спасибо!
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.046 c