|
[ komplikator @ 30.12.2011. 08:02 ] @
| Pozdrav svima!
Nešto mi vuče na generice (no nisam se u njih nikad upštao u Delphiju)...
Ovako, napravio sam nekoliko naslijeđenih objekata (formi) sa raznoraznim svojstvima, metodama i sl. Sve potječu iz jedne korjenske klase, ali se na kraju razlikuju u detaljima.
Želim stvoriti neograničen broj objekata/formi iz tih raznih klasa pozivom funkcije kojoj bi samo proslijedio tip klase tj. ime, a ona bi stvorila svoju (lokalnu) varijablu sa novim objektom i pravljala bi njime.
Ne želim pisati funkciju za svaku od 500 raznih formi izvedenih iz nekoliko korjenskih, nego jefnu funkciju koja će ovisno o parametru znati koji tip napraviti.
Znači imam:
TDok = class(TForm) ... neka moja forma
TPoste = class (TDok)...
TPorezi = class (TDok)...
želim napraviti ovo:
function GetDokument (TPorezi): boolean;
.
.
A funkcija stvara novi objekt tipa Tporezi, ne želim funkciju tipa Function GetPorezi():boolean;
probao sam ideju koja naravno ne prolazi:
function GetDokument(aTip: TClass): Boolean;
var myFrm : TIPDok;
begin
myFrm := (aTip as TfrmIPDok).Create(nil); // ne pali ni ništa drugo vezano uz castanje tipova.
try
myFrm.PrimjeniOvlastinaAkcije;
myFrm.PrikaziModalno;
finally
myfrm.Free;
end;
end;
Ima li tko kakvu ideju, mozak mi stoji, negdje fulam osnovnu oop koncepciju i to ne vidim, a nema smisla pisati neke pozivne funkcije za svaku od velikog broja izvedenih formi/klasa. |
[ Rapaic Rajko @ 30.12.2011. 09:59 ] @
Potrazi u help-u metaklase, ima lepo sve objasnjeno.
U tvom slucaju, kod bi bio nesto kao:
Code:
TDok = class(TForm) ... neka moja forma
TPoste = class (TDok)...
TPorezi = class (TDok)...
TDokClass = class of TDok; // metaklasa
function GetDokument (aTip: TDokClass): boolean;
function GetDokument(aTip: TDokClass): Boolean;
var
myFrm : TfrmIPDok;
myDoc: TDok;
begin
myDok := aTip.Create(nil);
if myDok is TfrmIPDok then
begin
myFrm := myDoc as TfrmIPDok;
try
myFrm.PrimjeniOvlastinaAkcije;
myFrm.PrikaziModalno;
finally
myfrm.Free;
end;
end
else
begin
// neki drugi tipovi...
end;
end;
Ali, napomena. Stvarno dobar kod (dobra koncepcija klasa) ne zahteva kastovanje objekata u letu. Ako lepo osmislis metode (virtual; abstract) u baznoj klasi TDok, koje zatim override-ujes u izvedenim klasama, onaj kod gore (if myDok is TfrmIPDok) postaje suvisan. Istina je da to nije uvek moguce, prema tome, radimo kako mozemo.
Javi sta si uradio. :)
Pozz
[ komplikator @ 30.12.2011. 10:18 ] @
Da, istina je to što kažeš castanju u letu, no promjenio sam firmu, promjenio posao i zatekao uradak "šampionskog programera" koji je nemoguće održavati i sad radim nove programe iznova. naravno, što drugo nego svima omraženi poslovni software.
Napravio sam vfi mehanizam sa raznoraznim stvari koje trebaju za razne tipove dokumenata, GUI je TDI tipa i praktički svaki dokument možeš otvoriti neograničeni broj puta, a on raznim lookupovima može otvarati dalje poddokumente i sl. i praktički svaki novi tip dokumenta je zasebna klasa nastala iz nekoliko tipova izvornih klasa, i u jednom trenutku opet zvaršiš da neka metoda/funkcija treba stvarati novi podobjekt nečega, pa da malo uopćim i bolje kontroliram postupke generiranja vezanih podobjekata mislio sam raditi metode tj. funkcije ovog tipa što tražim. Ne znam shvaćaš li na što mislim, što želim izvesti. Generic-e. nisam koristio, interfejsi bi se u sve uklopili ali i znatno komplicirali, a vrijeme (i pamet) mi polako cure...
Hvala na savjetu, idem vijdeti što mogu učiniti.
[ Rapaic Rajko @ 30.12.2011. 11:41 ] @
Eh, druze, ko da si moj zivotopis prepricao :) , pa reprizirano n puta...
Nisam ni ja koristio generics u Delphi-ju, a ne verujem ni da cu. Preporucujem ti da ih zaobidjes, jer sam imao primer u jednoj beogradskoj firmi (C++, gradjevinski CAD), koriscenja template-a (isto to) preko svake mere. Pa su cak radili typedef (proglasavanje tipova) za template od ovog, onog, svaceg... od drugih template-a (template na kvadrat :) ); katastrofa.
Posledica je da je u pojam ubijeno par tekovina OOP-a, a to su nasledjivanje i polimorfizam. Ne kazem da generics/templates nisu upotrebljivi, ali mnogo veci napredak je (po meni) nacinjen uvodjenjem interface-a; e to je stvarno mocan koncept.
Pozz
[ komplikator @ 30.12.2011. 12:37 ] @
Riješio sam problem metaklasama, skroz sam previdio kakav parametar šaljem funkciji i što dobijem.
Trenutno radim prototip funkcije koja mi na ovaj sistem radi.
dakle:
type TDokClass = class of TDok;
function OtvoriDok(aDokument: TDokClass ): Boolean;
var novidok : TIPDok;
begin
novidok := aDokument.Create(Self);
with novidok do
begin
if PrimjeniOvlastiNaAkcije then // radim nešto sa formom/objektom...
PrikaziNaKartici( frmMain.advpage)
else
if Assigned(novidok) then novidok.Free;
end;
end;
TfrmRobaUsluge = class (TDok) .... neka forma
Poziv funkcijom sa nekog izbornika: OtvoriDok(TfrmRobaUsluge);
(nije baš najlijepše no radi, i koliko vidim debugerom prolazi kroz klase i naslijeđuje i nadvladava virtualne metode i sl. kako spada).
Update:
Napravio sam ovu zavrzlamu:
aKlasa je String parametar u pozivu funkcije.
var noviDokument :TDok;
novaKlasa : TDokClass;
begin
novaKlasa := TDokClass(classes.FindClass(aKlasaDokumenta));
noviDokument := novaKlasa.Create(Self);
U konstruktoru datamodula nekog modula registriram klase koje se iz njega pozivaju RegisterClass(TfrmRobaUsluge);
Ovime sam postigao da se funkcija može pozvati od svuda u programu (jer klasu šaljem kao string) bez da je unit ove forme TfrmRobaUsluge naveden u uses i da time kompliciram život glavnoj formi, delphiju, delphijevom sporom codeinsightu i sl.
nadam se da sam na dobrom putu
[Ovu poruku je menjao komplikator dana 30.12.2011. u 14:27 GMT+1]
[ Rapaic Rajko @ 30.12.2011. 13:38 ] @
Blago tebi, sad je taj tvoj kod milina odrzavati  .
Nego, tvoj nick me podsetio, gde god sam pisao klase, nabedjivali su me da 'volim da komplikujem' stvari  , pa su terali po svome. A kasnije se ispostavi da je 'preko prece, naokolo blize'  .
Pozz i svako dobro
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|