Ir al contenido


Foto

Ahorro de Código


  • Por favor identifícate para responder
26 respuestas en este tema

#1 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 05:37

Bueno quiero compartir algo con ustedes y es que he aprendido a ahorrarme mucho trabajo con ciertas cositas tales como:

Procedures y With do

me parece que me han hecho un 100% la vida mas facil antes cada ves que necesitaba un codigo lo desarrollaba, ahora solo lo invoco con los procedures y me ahorro mucho codigo tambien con el With Do ..... si alguien sabe como ahorrar mas código alimenten este Hilo :D creo que será de muchisima utilidad
  • 0

#2 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 05:38

y bueno uno no sabe...... si alguien no sabe usar lo que he dichoi anteriormente solo digalo!! :p
  • 0

#3 Guest_Jose Fco_*

Guest_Jose Fco_*
  • Visitante

Escrito 21 diciembre 2008 - 05:42

Hola amigo lkinGl, porque no pones un ejemplo pequeño para poderte entender.Suena interesante eso, ¿es como los includers? Bueno mas o menos algo asi. ;)

Un Saludo.

#4 Caral

Caral

    Advanced Member

  • Administrador
  • 4.262 mensajes
  • LocationCosta Rica

Escrito 21 diciembre 2008 - 05:42

Hola
Bueno una vez que ves la presentación de Egostar para CodeGear con relacion a Action Manayer te das cuenta de que se puede ahorrar no solo codigo si no muchísimo trabajo.
Ademas de que la explicación es muy buena, la idea de programar de esta forma es esplendida.
Saludos


  • 0

#5 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 05:54

ok lo haré

Ejemplo si tengo
1: 20 Form
2: tabla llamada zEjemplo con 5 campos en el Form1 código anterior




delphi
  1. Form1.zEjemplo.insert;
  2. Form1.zEjemplo.FieldbyName('campo1').asstring:=edit1.text;
  3. Form1.zEjemplo.FieldbyName('campo2').asstring:=edit2.text;
  4. Form1.zEjemplo.FieldbyName('campo3').asstring:=edit3.text;
  5. Form1.zEjemplo.FieldbyName('campo4').asstring:=edit4.text;
  6. Form1.zEjemplo.FieldbyName('campo5').asstring:=edit5.text;
  7. Form1.zEjemplo.Post;



con el With Do quedaría asi...



delphi
  1. With Form1.zEjemplo do
  2. begin
  3. Insert;
  4. FieldbyName('campo1').AsString:edit1.text;
  5. FieldbyName('campo2').AsString:edit2.text;
  6. FieldbyName('campo3').AsString:edit3.text;
  7. FieldbyName('campo4').AsString:edit4.text;
  8. FieldbyName('campo5').AsString:edit5.text;
  9. Post;
  10. end;



y con respecto a los procedure....

tengo:
1 form
5 edits
1 boton nuevo
1 boton guardar
1 boton limpiar
1 boton cancelar

Anteriormente cada ves que necesitaba un código lo desarrollaba ejemplo

Código Nuevo:



delphi
  1. edit1.enabled:=true;
  2. edit2.enabled:=true;
  3. edit3.enabled:=true;
  4. edit4.enabled:=true;
  5. edit5.enabled:=true;
  6. edit1.clear;
  7. edit2.clear;
  8. edit3.clear;
  9. edit4.clear;
  10. edit5.clear;
  11. edit1.setfocus;



como bien sabemos cada nada necesitamos habilitar y deshabilitar los edits de este formulario y tambien limpiarlo....pero no es muy bueno desarrollar el codigo cada ves que se necesite, yo he cambiado este hábito por declarar en la parte de public procedures

procedure limpiar;
procedure habilitar;
procedure deshabilitar;

despues de {$R *.dfm}

desarrollo cada procedure

y simplemente

cada ves que lo necesite pongo:

habilitar;
limpiar;
edit1.setfocus

en ves de:



delphi
  1. edit1.enabled:=true;
  2. edit2.enabled:=true;
  3. edit3.enabled:=true;
  4. edit4.enabled:=true;
  5. edit5.enabled:=true;
  6. edit1.clear;
  7. edit2.clear;
  8. edit3.clear;
  9. edit4.clear;
  10. edit5.clear;
  11. edit1.setfocus;




creo que es muchisimo mas facil
  • 0

#6 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 06:18

¿alguien sabe alguna otra forma de facilitar el ahorro de código?
  • 0

#7 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 21 diciembre 2008 - 06:18

Hola, para reducir código yo sigo más o menos estas reglas:

1. Emplear procedimientos y funciones cuando se los considere oportuno. Si tras un buen análisis se observan tareas repetitivas, lo mejor es tenerlas en un procedimiento y/o función según sea el caso.
2. Si se debe trabajar muchísimo con un objeto: With ... do. En pocas líneas mejor me lo evito.
3. Si por alguna razón existe alguna variación entre rutinas que comparten alguna similitudes y que se repiten, analizo objetivamente si se puede emplear algun parámetro de tipo bandera, o control que determine que acción realizar. Por ejemplo:



delphi
  1. procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);



La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.

4. Nombres de variables simples, y cortas aplicadas al contexto en que se la usan (si el contexto es de una acción, el nombre debe reflejarlo). Yo me he acostumbrado al inglés, se reduce muchos caracteres y armoniza con el lenguaje.

5. Identación clara. Nada de if then, a menos que sea una línea. Evitar en lo posible el anidamiento excesivo de Ifs. En caso de muchos If, analizar si es posible una "conversión" a case. Aplico tablas de verdad a fin de reducir la complejidad de las condiciones y el anidamiento. Por ejemplo:


delphi
  1. if Condicion1
  2.  then if Condicion2
  3.            then



En caso de ser posible, evitarse ese if, es mejor algo como:


delphi
  1. if (Condicion1) and (Condicion2)
  2.    then



6. Separar la lógica de la interfaz. Si bien hay situaciones en que no se puede, lo mejor es reducir el impacto entre ambas capas.

Y si me disculpas un momento, a ese código de limpiar se lo podría reducir si se emplease FindComponents y recorrer la lista en busca de componentes para hallar los componentes de una clase y cuyos nombre tienen un "denominador común".

en el caso de campo1, campo2, se puede hacer algo como:

for i := 1 to 5 do
 Form1.ZEjemplo.FieldByName('campo' + IntToStr(i)).AsString := ...

Claro que por 5, no me molesto en hacer algo tan "enrreversado" Pero en un caso de muchos, vale la pena.

Bueno, eso se me ocurre por ahora,

Saludos,

¿Se ve la idea?
 
  • 0

#8 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 06:26

Hola, para reducir código yo sigo más o menos estas reglas:

1. Emplear procedimientos y funciones cuando se los considere oportuno. Si tras un buen análisis se observan tareas repetitivas, lo mejor es tenerlas en un procedimiento y/o función según sea el caso.
2. Si se debe trabajar muchísimo con un objeto: With ... do. En pocas líneas mejor me lo evito.
3. Si por alguna razón existe alguna variación entre rutinas que comparten alguna similitudes y que se repiten, analizo objetivamente si se puede emplear algun parámetro de tipo bandera, o control que determine que acción realizar. Por ejemplo:



delphi
  1. procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);



La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.

4. Nombres de variables simples, y cortas aplicadas al contexto en que se la usan (si el contexto es de una acción, el nombre debe reflejarlo). Yo me he acostumbrado al inglés, se reduce muchos caracteres y armoniza con el lenguaje.

5. Identación clara. Nada de if then, a menos que sea una línea. Evitar en lo posible el anidamiento excesivo de Ifs. En caso de muchos If, analizar si es posible una "conversión" a case. Aplico tablas de verdad a fin de reducir la complejidad de las condiciones y el anidamiento. Por ejemplo:


delphi
  1. if Condicion1
  2.  then if Condicion2
  3.            then



En caso de ser posible, evitarse ese if, es mejor algo como:


delphi
  1. if (Condicion1) and (Condicion2)
  2.    then



6. Separar la lógica de la interfaz. Si bien hay situaciones en que no se puede, lo mejor es reducir el impacto entre ambas capas.

Y si me disculpas un momento, a ese código de limpiar se lo podría reducir si se emplease FindComponents y recorrer la lista en busca de componentes para hallar los componentes de una clase y cuyos nombre tienen un "denominador común".

en el caso de campo1, campo2, se puede hacer algo como:

for i := 1 to 5 do
 Form1.ZEjemplo.FieldByName('campo' + IntToStr(i)).AsString := ...

Claro que por 5, no me molesto en hacer algo tan "enrreversado" Pero en un caso de muchos, vale la pena.

Bueno, eso se me ocurre por ahora,

Saludos,

¿Se ve la idea?
 


salu2 amigo delphius lo único que no usaba para reducir código con respecto a ti es la parte donde dices :

Código

  1.
      procedure Limpiar(ArrayClase: array of TControlClass; ExceptionList: TObjectList; ... Flag: TFlag);


La idea es que este "Limpiar" pueda ofrecer no sólo las funciones para limpiar uno o varios tipos de controles. Sino que maneje alguna lista de excepciones (por poner ejemplo, deseo limpiar todos los edits excepto xxx) y se puede preveer cualquier parámetros adicional que sea oportuno para el contexto.


q aunque debe ser facil no la entiendo y se ve super util tener un solo "Limpiar para todos los formularios" siempre y cuando el número de edits se asemeje al de otro formulario

me gustaria que me aclararas eso que acabo de mencionar y pues lo de campo1 campo2 campo3 fue solo un ejemplo pero no creo que alguien llame los campos de la tabla asi ya que no hace referencia a lo que es....... bueno me parece que no ayuda..... por que a la hora de modificar algo te vas a la tabla y ves y piensas que significara ¿campo3? jajajajaja (me pasó bastante tiempo ;))
  • 0

#9 Guest_Jose Fco_*

Guest_Jose Fco_*
  • Visitante

Escrito 21 diciembre 2008 - 06:28

¿Se ve la idea?


Claro Maestro, eso esta perfecto. ;) (y)

Un Saludo.

PD: Un dia sere asi de grande yo tambien.

#10 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 06:31

o sea no esta mal tu idea pero si en la parte donde lo aplicas, creo que quedaria mejor así:



delphi
  1. For i to 5 do
  2. begin
  3. With Form1.zEjemplo do
  4. begin
  5. Insert;
  6. FieldbyName('Campo1').asstring:=Edit+IntToStr(i).Text;
  7. FieldbyName('Campo2').asstring:=Edit+IntToStr(i).Text;
  8. FieldbyName('Campo3').asstring:=Edit+IntToStr(i).Text;
  9. FieldbyName('Campo4').asstring:=Edit+IntToStr(i).Text;
  10. FieldbyName('Campo5').asstring:=Edit+IntToStr(i).Text;
  11. Post;
  12. end;
  13. end;



  • 0

#11 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 06:36

aunque es algo muy facil es muy util y no se me habia ocurrido xD

gracias delphius :p creo que ese fué el fin del Hilo aprender algo de como Ahorrar Código
  • 0

#12 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 06:42

uffff imaginense así:

un procedure limpiar

con este código


delphi
  1. For i:=0 to 10 do
  2.   begin
  3.       Edit+IntToStr(i).Clear;
  4.   end;



en ves de...



delphi
  1. Edit1.Clear;
  2. Edit2.Clear;
  3. Edit3.Clear;
  4. Edit4.Clear;
  5. Edit5.Clear;
  6. Edit6.Clear;
  7. Edit7.Clear;
  8. Edit8.Clear;
  9. Edit9.Clear;
  10. Edit10.Clear;



y con Enabled:=True y False y todo lo que se use con los Edits uffffffffffffffffffffff....
  • 0

#13 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 21 diciembre 2008 - 06:45

Pero puedes hacer esto:



delphi
  1. var nIdx: Integer;
  2. begin
  3.   for nIdx := 0 to Form1.ComponentCount - 1 do
  4.   begin
  5.       if Form1.Components[nIdx] is TEdit then
  6.         TEdit(Form1.Components[nIdx]).Clear;
  7.   end;
  8. end;



Que creo es más conveniente digo yo ;)

Saludos.
  • 0

#14 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 21 diciembre 2008 - 06:49

Bueno... es un ejemplo nada más.
Ese último código no te va a funcionar. No se puede hacer esto:

Edit+IntToStr(i). Se necesita emplear de FindComponent(). ;)

Por otro lado el tema del Limpiar con esos parámetros, eso ya es una cuestión de como uno lleva el código. No interesa como se la implementación sino la idea: indicar que tipo de controles limpiar, y en caso de ser necesario: indicarles cuales de esa lista no. Los parámetros "Flags" pueden aportar otros enfoques, y dan un soporte extra al procedimiento.

Son ideas, amigo. No te preocupes por la implementación, sino que comprendas la idea. Hay muchas maneras de concebir esto. Por ejemplo:



delphi
  1. procedure Limpiar(Control: string);
  2. procedure Limpiar(ArrayControl: array of TControl);
  3. procedure Limpiar(ListaDeControles: TObjectList; Excepto: string; ... );



Saludos,


  • 0

#15 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 07:55

Este es mi código de un formulario, específicamente de un boton guardar.... ven alguna forma de optimizarlo?



delphi
  1. if (Length(Edit1.Text)<1) or (Length(Edit2.Text)<1) or (Length(Edit3.Text)<1) then
  2.   begin
  3.     Application.MessageBox('Debe llenar todos los campos informativos','');
  4.     exit;
  5.   end;
  6. if (Length(Edit4.Text)<1) and (Length(Edit5.Text)<1) and (Length(Edit6.Text)<1) then
  7.   begin
  8.     Application.MessageBox('Debe ingresar al menos 1 Número de teléfono','');
  9.     exit;
  10.   end;
  11.   With Form1.zAsesores do
  12.     begin
  13.       if Locate('cedula',Edit1.Text,[]) then
  14.         begin
  15.           Application.MessageBox('Disculpe, está cédula ya fué registrada','');
  16.           exit;
  17.         end
  18.         else
  19.         begin
  20.           Insert;
  21.           FieldByName('registro').AsString:=DateToStr(Date);
  22.           FieldByName('cedula').AsString:=Edit1.Text;
  23.           FieldByName('nombresyapellidos').AsString:=Edit2.Text;
  24.           FieldByName('direccion').AsString:=Edit3.Text;
  25.           FieldByName('telefono').AsString:=Edit4.Text;
  26.           FieldByName('celular').AsString:=Edit5.Text;
  27.           FieldByName('celular2').AsString:=Edit6.Text;
  28.           Post;
  29.           Application.MessageBox('Asesor registrado con éxito!','');
  30.           BitBtn4.Click;
  31.           exit;
  32.         end;
  33.     end;
  34. Application.MessageBox('Error Grave!','');
  35. exit;


  • 0

#16 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 07:59

El código del BitBtn4 es:



delphi
  1. habilitar;
  2. limpiar;
  3. deshabilitar;
  4. BitBtn1.Enabled:=True;


  • 0

#17 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 21 diciembre 2008 - 09:58

Hola lKinGl,
Ummm no veo donde más se lo pueda optimizar. A mi modo de ver, está en su mínima expresión. A menos claro que estructures esas sentencias en procedimientos más chicos. Por ejemplo, esos chequeos iniciales pueden ir en una función Chequear, y dependiendo del valor devuelto seguir con el algoritmo o no. De la misma manera se podría hacer con la parte de inserción del registro.

En fin, eso es ha gusto tuyo, y según te dicte la experiencia. Es un algoritmo simple, y puede que por 35 líneas tal vez no sea útil separarlo en más.
Lo que si es bueno recomendarte, por lo que veo, es que usas ZTable (o algún análogo a Table en Zeos; desconozco Zeos). Es conveniente emplear ZQuery (o el análogo a Query) y valerse de SQL.

No se si he chequeado bien, pero me parece que por la forma en que está escrito el código que siempre recibes el mensaje "Error grave".

Bueno, eso veo yo.
Ha, por cierto mejor sería separar la lógica de la interfaz. Usa DataModules para estructurar mejor tus componentes de base de datos.

Saludos,
  • 0

#18 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 10:07

Hola lKinGl,
Ummm no veo donde más se lo pueda optimizar. A mi modo de ver, está en su mínima expresión. A menos claro que estructures esas sentencias en procedimientos más chicos. Por ejemplo, esos chequeos iniciales pueden ir en una función Chequear, y dependiendo del valor devuelto seguir con el algoritmo o no. De la misma manera se podría hacer con la parte de inserción del registro.

En fin, eso es ha gusto tuyo, y según te dicte la experiencia. Es un algoritmo simple, y puede que por 35 líneas tal vez no sea útil separarlo en más.
Lo que si es bueno recomendarte, por lo que veo, es que usas ZTable (o algún análogo a Table en Zeos; desconozco Zeos). Es conveniente emplear ZQuery (o el análogo a Query) y valerse de SQL.

No se si he chequeado bien, pero me parece que por la forma en que está escrito el código que siempre recibes el mensaje "Error grave".

Bueno, eso veo yo.
Ha, por cierto mejor sería separar la lógica de la interfaz. Usa DataModules para estructurar mejor tus componentes de base de datos.

Saludos,


me alegra que este programando bien :D:D, con respecto al error grave solo sucede si no consigue cedula y si no entra en el else....
  • 0

#19 lKinGl

lKinGl

    Advanced Member

  • Moderador
  • PipPipPip
  • 118 mensajes
  • LocationVenezuela

Escrito 21 diciembre 2008 - 10:09

con respecto a los datamodules..... nunca he sabido como se usa pero yo uso todos los ztables en un solo form que creo que es casi lo mismo
  • 0

#20 Fenareth

Fenareth

    Advanced Member

  • Moderador
  • PipPipPip
  • 3.486 mensajes
  • LocationMexico City

Escrito 22 diciembre 2008 - 12:08

con respecto a los datamodules..... nunca he sabido como se usa pero yo uso todos los ztables en un solo form que creo que es casi lo mismo


Casi pero no... es mejor hacerlo dentro de un DataModule... creo que yo, por darle a cada componente su uso "correcto", no sé, por ejemplo... de alguna manera un TLabel puede hacer algo similar a un TButton pero no por eso lo reemplazamos cierto ?  :p

Pues un DataModule simplemente es un contenedor de elementos de conexión a la Base de Datos: Tables, Querys, etc... y permite organizarlo mejor creo yo...
  • 0