Форум: "Компоненты";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];
ВнизИнкапсуляция и взаимодействие Найти похожие ветки
← →
dvp_Dima (2005-11-24 21:44) [0]Здравствуйте мастера.
При практическом решении задачи возник теоретический вопрос:
Имеются 2 класса:
TLittleClass = class
property FirstProperty: TSomeType;
property SecondProperty: TAnotherType;
end;
TBigClass = class
private
FChanged: Boolean;
FLittleItems: array of TLittleClass;
public
property Changed: Boolean read FChanged;
procedure DoChangeSomething;
...
end;
Т.е. класс TBigClass инкапсулирует класс TLittleClass.
У объекта типа TBigClass имеется свойство Changed (и соответствующее ему поле FChanged), которое предназначено для хранения факта внесения изменений в этот объект.
На практике это означает, что при вызове DoChangeSomething флаг FChanged устанавливается в True;
Вопрос: Как организовать взаимодействие описанной системы, чтобы при внесении изменений в любой из инкапсулированных объектов FLittleItems: array of TLittleClass флаг FChanged устанавливался в True;
Сам я пока нашёл только два решения, но оба они мне не нравятся:
1. В классе TLittleClass сделать аналогичное поле FChanged и поддерживать его значение средствами самого класса. А при вызове TBigClass.Changed возвращять TBigClass.FChanged or TBigClass.FLittleItems[0..Count].FChanged
2. Создать в лкассе TLittleClass свойство OnChange. При создании объекта TBigClass назначить TLittleClass.OnChange действие, устанавливающее флаг TBigClass.FChanged в True.
Подскажите, как правильно организовать это?
← →
dvp_Dima (2005-11-24 22:04) [1]Да, забыл сказать - второй вариант не корректен, потому что TLittleClass.OnChange будет Public и следовательно будет доступен в обход TBigClass
← →
oleg_ (2005-11-24 23:21) [2]Я в подобных случая для класса littleclass прописываю ссылку на объект класса bigclass
← →
dvp_Dima (2005-11-25 00:49) [3]Т.е. по аналогии с Parent в визуальных компонентах?
Но в этом случае придётся FChanged делать открытым на запись, что конечно не критично, но всё-таки как-то не правильно
← →
ЮЮ © (2005-11-25 03:43) [4]>Но в этом случае придётся FChanged делать открытым на запись
Зачем? Может лучше
property Changed: Boolean read FChanged write SetChanged
Кстати, будет ли TBigClass.Changed, если в списке нескольких эземпляров TLittleClass был только один, который Changed, и он был удален из списка? Тогда может лучше так(если список не очень большой):
property Changed: Boolean read GetChanged;
function GetChanged: boolean;
var
i: integer;
begin
Result := false;;
for i := 0 to High(FLittleItems) do
if FLittleItems[i].Changed then begin
Result := true;
exit;
end
end;
← →
Юрий Зотов © (2005-11-25 05:31) [5]> dvp_Dima (24.11.05 21:44)
Наследуйте TLittleClass от TCollectionItem, а TBigClass - от TCollection, там все уже реализовано (см. методы Changed). Или сделайте по аналогии с коллекциями.
← →
Igorek © (2005-11-25 08:57) [6]> 2. Создать в лкассе TLittleClass свойство OnChange. При
> создании объекта TBigClass назначить TLittleClass.OnChange
> действие, устанавливающее флаг TBigClass.FChanged в True.
Вот так хорошо. Но действие - это метод TBigClass, который динамически назначен обработчиком TLittleClass.OnChange (пусть это будет LittleItemChanged(Sender)). Но есть потенциальный недостаток. Вообще говоря поле свойства, должно меняться только в методе записи св-ва. Можно конечно в LittleItemChanged написать Changed := True (предварительно добавив метод записи). Но проблема возникает, когда происходит много изменений, и TBigClass после каждого должен выполнить какую-то затратную операцию (перерисовку например). Вмешаться в работу метода записи напрямую Вы не можете. Тогда надо реализовать механизм BeginUpdate, EndUpdate, IsUpdating - если TBigClass в процессе изменения, то при вызове SetChange, эта затратная операция не выполняется. А в EndUpdate надо инициировать эту затратную операцию.
← →
Юрий Зотов © (2005-11-25 15:24) [7]> Igorek © (25.11.05 08:57) [6]
> Тогда надо реализовать механизм BeginUpdate, EndUpdate...
То есть, повторить все то, что уже сделано в классе TCollection. Значит, надо просто от него и отнаследоваться, это будет и проще, и надежнее.
← →
dvp_Dima (2005-11-26 21:53) [8]Юрий Зотов © (25.11.05 05:31) [5]
Спасибо, думаю это будет действительно правильный подход.
Страницы: 1 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.037 c