![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
#1
|
|||
|
|||
|
Buenas gente,
a ver si me podeis echar una manita con el rediseño de un programa. Tengo un form principal, una serie de frames y una máquina de estados para controlar la visualización de los frames, entre otras cosas. Hasta ahora el diseño era un poco chapuza, el form principal contiene las referencias a todos los frames y la creación de los estados de la máquina. A parte, cada frame contiene referencias a otros frames "hermanos" que necesita y referencias al frame principal, con lo cual tengo un lío tremendo de referencias circulares. Algunas partes del código Form principal Código:
TfrMain = class(TForm)
frToolbar: TfrToolbar;
procedure mmExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
frNavBarLeft :TfrNavBarLeft;
frNavBarRight :TfrNavBarRight;
frEditPatient :TfrEditPatient;
frViewPatient :TfrViewPatient;
frBlank :TfrBlank;
frViewImage :TfrViewImage;
frViewStudy :TfrVIewStudy;
frViewImageTwin :TfrViewImageTwin;
frCamera :TfrCamera;
frEditStudy :TfrEditStudy;
frPrint :TfrPrint;
frProcesses :TfrProcesses;
end;
var
frMain: TfrMain;
implementation
{$R *.dfm}
procedure TfrMain.mmExitClick(Sender: TObject);
begin
frMain.Close;
end;
procedure TfrMain.FormCreate(Sender: TObject);
begin
frBlank :=TfrBlank.Create(Self);
frNavBarLeft :=TfrNavBarLeft.Create(Self);
frViewPatient :=TfrViewPatient.Create(self);
frEditPatient :=TfrEditPatient.Create(Self);
frViewImage :=TfrViewImage.Create(Self);
frViewStudy :=TfrViewStudy.Create(Self);
frViewImageTwin :=TfrViewImageTwin.Create(Self);
frCamera :=TfrCamera.Create(Self);
frEditStudy :=TfrEditStudy.Create(Self);
frPrint :=TfrPrint.Create(Self);
frProcesses :=TfrProcesses.Create(Self);
frBlank.Parent :=Self;
frNavBarLeft.Parent :=Self;
frViewPatient.Parent :=Self;
frEditPatient.Parent :=Self;
frViewImage.Parent :=Self;
frViewStudy.Parent :=Self;
frViewImageTwin.Parent :=Self;
frCamera.Parent :=Self;
frEditStudy.Parent :=Self;
frPrint.Parent :=Self;
frProcesses.Parent :=Self;
sessiondate:=now;
states:=TStateMachine.Create;
frNavBarLeft.ReLoadTreeView;
frMain.TabStop:=false;
states.Add (
stBlank,
frBlank.frEnter,
frBlank.frExit,
frBlank,
true,
frToolBar.menu
);
states.Add (
stViewPatient,
frViewPatient.frEnter,
frViewPatient.frExit,
frViewPatient,
true,
frToolBar.menu
);
// y bla bla bla... demás estados ....
states.Enter(stBlank);
end;
Código:
TProc = procedure of object;
{
TState:
state type for the State Machine
}
TState = record
id:integer; //id state (for ex. stBlank, stViewPatient)
inProc:TProc; //initial process
outProc:TProc; //fianl process
frame:TFrame; //frame corresponding for this state
navBarL:Boolean; //bars must be shown
menu:TMainMenu; //main menu for this frame (use to be main menu of the
//toolbar frame
end;
{
TStateMachine:
Controls the state of the program and manage the interface active frame
}
TStateMachine = class
private
states:array of TState; //posible states
procedure stExit(id:integer);
public
current:integer; // current state
last:integer; //last state (for goback function)
OnRecordChange:TNotifyEvent;
stack:TStack;
procedure Add(id:integer;ip,op:TProc;frame:TFrame;nbl:boolean;menu:TMainMenu); procedure SetInProc(proc:TProc;state:integer);
procedure Enter(id:integer);
constructor Create;
destructor Destroy; override;
var
states :TStateMachine;
sessionDate :TDateTime;
implementation
procedure TStateMachine.Add(id:integer;ip,op:TProc;frame:TFrame;
nbl:boolean;menu:TMainMenu);
var
l :integer;
begin
l := Length(states);
SetLength(states,l+1);
states[l].id := id;
states[l].inProc := ip;
states[l].outProc := op;
states[l].frame := frame;
states[l].menu := menu;
states[l].navBarL := nbl;
end;
procedure TStateMachine.Enter(id: integer);
var
i,j:integer;
begin
for i := 0 to length(states)-1 do
if id = states[i].id then
begin
stExit(current);
current := id;
frMain.frNavBarLeft.Visible := states[i].navBarL;
frMain.Menu := states[i].menu;
with states[i].frame do
begin
Align := alClient;
Visible := True;
end;
states[i].inProc;
end;
end;
procedure TStateMachine.stExit(id:integer);
var
i :integer;
begin
for i := 0 to length(states)-1 do
if id=states[i].id then
begin
last := current;
current := -1;
states[i].outProc;
states[i].frame.Align := alNone;
states[i].frame.Visible := False;
end;
end;
![]() Y un pequeño resumen, de cómo considero que son/deberían ser las cosas, pero que no consigo ver claro cómo hacer:
¿Qué patrones de diseño veis aquí? ¿Singleton para la máquina de estados? ¿Alguna manera de evitar el rollo de las referencias circulares... sin hacer el chapuceo de los uses en la implementación? (Perdón por el rollo :P ) |
|
|
Temas Similares
|
||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| Patron GoF: Factoría ¿Como y cuando se usa? | Delphius | OOP | 2 | 26-12-2007 06:37:32 |
| En access hay botón buscador-en form permite buscar patron-existe uno en Delphi igual | Ale Alvarez | OOP | 9 | 26-09-2007 07:13:44 |
| Patrón observador, attach, notify,update ... | adpa | OOP | 5 | 22-01-2006 01:07:40 |
| Patrón de los Informáticos. | obiwuan | Varios | 20 | 10-09-2003 14:44:54 |
|