среда, марта 22, 2006

Bold. Копирование объектов.


В настоящий момент я внедряю проект, реализованный (почти) на Bold. Параллельно добавляются некоторые вкусности и полезности, и, естественно, устраняются багги. Одной из таких полезностей является копирование объектов. Что я имею в виду? Предположим, имеется накладная, содержащая неоторые товары. Количество и стоимость товара являются атрибутами класса-ассоциации. Я именую такой класс - расшифровка накладной. Процесс формирования накладной занимает определенное время (подбор товара, указание цены и количества и т.д.). Достаточно часто возникает необходимость создания типовых накладных. С точки зрения пользователя, в этом случае, значительно удобнее сделать копию имеющейся накладной, чем создавать новую «с нуля». Что должно произойти с технической точки зрения?

Создается новый объект – экземпляр класса «накладная»;
Устанавливаются связь нового объекта с теми товарами, которые ассоциированы с копируемой накладной;
Ищутся соответсвующие экземпляры класса –ассоциации и копируются их атрибуты.
Здесь очень важно правильно найти соответсвующие расшифровки накладных. Если в исходной накладной проводится два процессора и один винчестер, то в копии должно быть именно два процессора и винчестер, а не наоборот.

Почему задача должна решаться именно так? Мы не можем создать класс ассоциацию обычным методом. Он создается автоматически после связывания двух объектов. Возможно, было бы удобнее, создавать экземпляр класса –ассоциации, так как создаются экземпляры обычных классов, и это бы приводило к автоматическому связыванию ассоциацией соответсвующих объектов, но так не происходит. Функции TBoldCopyAndClone.BoldCopy и TBoldCopyAndClone.BoldClone также не справляются с задачей.

В принципе, вышеописанная задача достаточно типична. И я решил написать две подпрограммы, которые можно использовать в подобной ситуации без модификаций.

Вот их текст:



function TfClientCard.LocateAssObject(AssClName:string;
frstObj, secObj: TBoldObject): TBoldElement;
var

Expr: string;
brL: TBoldReferenceHandle;
BOV: TBoldOCLVariables;
CI: TBoldVariableTuple;
begin
try
brl:=TBoldReferenceHandle.Create(self);
brl.StaticSystemHandle:= DM.bsh;
brl.StaticValueTypeName:=secObj.BoldClassTypeInfo.ExpressionName;
brl.Value:= secObj
as TBoldElement;
BOV:=TBoldOCLVariables.Create(self);
CI:=TBoldVariableTuple(BOV.Variables.Add);
CI.VariableName:=
'vNewObj';
CI.BoldHandle:=brl;
Expr:=
'self.'+LowerCase(AssClName)+
'->select('+LowerCase(secObj.BoldClassTypeInfo.ExpressionName)+'=vNewObj)->first';
result:=frstObj.EvaluateExpressionAsDirectElement(Expr,BOV.VariableList);

finally
bov.Free;
brl.Free;
end;
end;


procedure TfClientCard.CopyAssociations(SourceObj, DistObj: TBoldObject;
AssClassName, RoleName:
string);
// SourceObj - объект-источник
// DistObj - объект -приемник
// AssClassName - имя класса ассоциации
// AssName - имя роли
var
i: integer;
AssObjRel: TBoldObject;
AssObjectDist, AssObjectSource: TBoldObject;
begin
// здесь весьма нетрадиционный, но действенный способ проверки
//множественности ассоциации (а точнее роли)
// если аккуратно передавать параметры, то это и не нужно
if Pos('List',SourceObj.BoldMemberByExpressionName[RoleName].ClassName)<>0 then
begin
if
DistObj.ClassName=SourceObj.ClassName then
begin
for
i := 0 to (SourceObj.BoldMemberByExpressionName[RoleName]

as TBoldObjectList).Count-1 do
begin
// если источник и приемник - экземпляры одного класса
if Assigned((SourceObj.BoldMemberByExpressionName[RoleName]
as TBoldObjectList)[i] as TBoldObject) then
begin

AssObjRel:=(SourceObj.BoldMemberByExpressionName[RoleName]
as TBoldObjectList)[i] as TBoldObject;
(DistObj.BoldMemberByExpressionName[RoleName]
as TBoldObjectList).Add(AssObjRel);

AssObjectDist:=LocateAssObject(AssClassName,DistObj, AssObjRel)
as TBoldObject;
AssObjectSource:=LocateAssObject(AssClassName,SourceObj, AssObjRel)
as TBoldObject;

TBoldCopyAndClone.BoldCopy(AssObjectDist,AssObjectSource,bcmAttributes,true);
end;

end;
end;
end
// я затрудняюсь это правильно сказать :(
else ShowMessage('Ассоциация не множественная');

end;
end.


Alexander Bozhko Bold&ECO blog

Alexander Bozhko Bold&ECO blog

четверг, марта 16, 2006

Статья

Недавно на сайте издания Xakep была опубликована очередная моя статья.
Borland IDE: что дальше?
Правда уже задним числом я нашел пару ляпов. Но в принципе... судите сами.

Новый блог

Прочувствовав все преимущества Google, я решил перевести свой старый блог сюда. Возможно, это простимулирует меня почаще писать.
---
В качестве теста я перенесу пару постов из старого блога, дабы освоиться.
---
Ну, и не забывайте посетить сайт Russian ECO&Bold Community, участником которого я являюсь.