AgustinOrtu
22-02-2016, 03:54:19
Saludos,
Me voy a tomar el atrevimiento de robar un pequeño espacio en el Club para "pensar en voz alta", y de paso, si hay algun interesado, comenzar un debate ;)
En mis ultimas aventuras programando con Delphi, me estoy dedicando mas que nada a refactorizar un sistema que vengo desarrollando desde practicamente que empece mi vida como programador: con el he aprendido, he crecido, he sufrido, he disfrutado.. en fin creo que todos pasamos por lo mismo
Pero ahora estoy refactorizando lo mas posible aplicando "los nuevos conceptos aprendidos" :D. Estoy seguro de que todos tenemos alguna porqueria de codigo por ahi escrito en mas de una clase (ok, en la gran mayoria :p)
Mi nuevo estilo de programacion es muy enfocado a la programacion orientada a objetos, casi en un estilo purista (el amigo escafandra me ha llamado en una ocasion, un enamorado de la POO)
Pasa algo de tiempo hasta que realmente uno se da cuenta que cuando diseña un form con el fabuloso IDE Delphi, en realidad lo que tiene es un objeto: tiene metodos, tiene propiedades, tiene una interfaz publica, una parte privada u oculta, todo aquello que todos ya sabemos que aprendimos, casi practicamente el primer dia que empezamos a estudiar POO
Y lo sabemos, pero cuando nos sentamos con Delphi nos olvidamos de todo y rompemos los principios basicos de POO, porque, seamos sinceros, es muy facil y rapido y todo parece funcionar bonito
No quiero determe mucho mas en esta pequeña reflexion, hay excelentes articulos que describenes esta situacion mucho mejor que yo, el que mas me gusto fue leer al compañero mamcx, en este enlace (http://blog.elmalabarista.com/post/4263479306/click-click-tap-run-crash-un-mejor-rad)
Lo ideal, como el tiempo me enseño, es meterse en la cabeza que cuando tenemos un TForm, y estamos diseñandolo, en realidad tenemos un objeto, y que debemos aplicar los principios basicos de POO; una efectiva regla que yo sigo para programar, consiste en diferenciar dos conceptos y cuales son sus equivalencias en nuestro codigo:
1. Cómo se hacen "las cosas"
2. Cuándo se hacen "las cosas"
El primer concepto evidentemente se podría traducir en métodos de los objetos
El segundo concepto hace referencia a los eventos de los objetos
Cuando diseñamos en "modo RAD", solemos usar los eventos para resolver el cuando cuándo y el cómo
Yo mismo he escrito código así:
procedure TForm1.KeyDown...;
begin
if Key = VK_F3 then
begin
btnGuardarArchivo.Click;
end;
end;
Me ha tomado tiempo darme cuenta de los problemas que supone esto:
1. Primero, si remplazo el boton por otro control, pierdo el evento, y tengo que "acordarme" de volver a llamar al metodo "vaya a saber uno que" del nuevo control
2. Me ha pasado que quiero realizar la funcion implementada dentro del boton en cuestion, desde un formulario externo, y no me ha quedado otra solucion que escribir esto:
VariableForm.btnGuardarArchivo.Click;
Obviamente empeora exponencialmente según lo explicado en el punto 1)
3. Es imposible (inmanejable) implementar herencia de forms de esta manera (mi nuevo gran descubrimiento del 2016)
Claramente es una muy mala idea el mezclar el cómo y el cuándo
Cual es la solución? Muy sencillo, declaramos e implementamos un metodo "GuardarArchivo" en la clase; ahora podemos invocarlo desde un monton de lados: desde una clase externa, desde el evento OnKeyDown, desde el AfterNoSeQue de aquel DataSet, etc. Ya no hay ningun problema con cambiar, o incluso eliminar el dichoso button
---
Otro tema importante: las propiedades. Los objetos tienen propiedades. Si, y los TForm tambien.
Quien alguna vez no ha escrito este tipo de porqueria (ehm, codigo):
var
Form1: TFormPersona;
begin
Form1 := TFormPersona.Create(Self);
Form1.edNomPers.Text := DataModule.qryBuscPersPorNom.FieldByName('npers').AsString;
Form1.ShowModal;
end;
Ok, lo admito, me esforzé en poner nombres complicados para hacerlo mas chistoso (me he topado con bases de datos que ponen nombres en las columnas que parecen cifrados)
Por que violamos los principios de POO, y accedemos directamente a la implementacion, al T(DB)Edit, para colocar "el nombre de la persona"?
Si podemos hacer algo mucho mejor, usar propiedades
var
Form1: TFormPersona;
begin
Form1 := TFormPersona.Create(Self);
Form1.PersonName := DataModule.qryBuscPersPorNom.FieldByName('npers').AsString;
Form1.ShowModal;
end;
Mucho mejor verdad? Basicamente las propiedades nos dan las mismas ventajas que los puntos que expuse mas arriba:
1. Encapsulamos implementacion (que diablos me importa como TFormPersona va a mostrar el nombre? Si no me gusta como lo hace me busco otro "componente" mas lindo)
2. Hacemos responsable al TFormPersona (o mejor dicho, confiamos en él) en que va a mostrar el nombre de la mejor manera posible.
Ok, en este caso fue un simple string; pero cuaaantas veces hemos hecho esto:
Form2.DateTimePicker1.DateTime := FormatDateTime('dddd-mm-yyyy', Today);
Vamos, no es mas sencillo hacer esto?
Form2.FechaDesde := Today;
---
Reflexiones acerca del metodo RAD: Cuando usar RAD? Es malo programar a lo RAD?
No estoy de acuerdo con los que dicen que es "malo", que crea programadores "maleducados", que no fomenta el uso de la POO
No estoy de acuerdo con los que lo defienden como algo "bueno"; que permite desarrollar rapido, que es facil, que es "visual basic"
Yo creo que es una metodologia incomprendida. Creo que hay casos de uso reales, o mejor dicho, situaciones o circustancias que ameritan el uso de RAD, e incluso es justificado
Si es cierto que todo lo que describí arriba, al principio es díficil; en el corto plazo, consume más tiempo: los beneficios son más bien a largo plazo, cuando ya sabes que si creas una subclase de TDimForm sabes que cuando se invoca a ShowModal automaticamente se oscurece la pantalla que esta "debajo" y luego cuando lo cierras todo vuelve a la normalidad; pero todo esto lleva tiempo
Asi que, si la respuesta a la pregunta: ¿Para qué vas a desarrollar X proyecto? es "ganar dinero", yo creo que el metodo RAD merece una cierta mención, un pequeño espacio en nuestro dia a dia:
Desarrollar una aplicacion a lo RAD lleva menos tiempo (por lo tanto menos dinero); asi que creo que es una buena forma de desarrollar prototipos, demos, o versiones preliminares del proyecto en cuestión, y hacer lo que yo llamo un "tanteo" o "estudio de mercado": Mostrar la aplicacion, ver como reacciona el publico, ver si se va a poder vender o ya desde el vamos esta mal. Incluso hoy en dia en las ultimas versiones de Delphi con los componentes de prototipado se puede disponer de "informacion de prueba" para los controles enlazados por LiveBindings, que es genial para casos como este
Y luego recién ahi "diseñar algo bien", o comenzar con el desarrollo como debe ser
---
Voy a finalizar este primer post con la idea que originó realmente la creación del mismo (hoy tenía ganas de expresarme y me fui por las ramas quizá :D)
Hay un problema que aún le veo a mi "metodo":
Muy bien, ahora tenemos los metodos públicos para invocar a la funcionalidad
Mejor aún, tenemos las propiedades para modificar el estado del objeto
Pero aún hay un problema, y es que Delphi aun asi te permite hacer alegremente esto:
Form2.CantCopiasImpresion := 3; // usando propiedad, bien!
Form2.edtCantidadCopias.Text := IntToStr(3); // Delphi permite acceder a un objeto privado del form!! porque!!
Estos casos se dan cuando se diseñan Forms con el IDE; si se implementa todo "a pulmón", es tan sencillo como incluir los componentes/controles en la visibilidad privada de Form2 y ya no se podrá acceder desde afuera (al menos no de la forma idiomatica); ya no estaremos escribiendo Form2 y al llegar al "." veremos en la lista "edtCantidadCopias"
Existirá alguna manera (o es viable que Embarcadero implemente) la posibilidad de ocultar estos detalles de implementación?
La primera solucion que vino a mi cabeza son interfaces; pero no estoy conforme con eso, ya que es facilmente hackeable ("solucionable"): en vez de usar la interface uso la clase! en un periquete! al demonio con la POO!
En fin, creo que el post ya es suficientemente largo
Un saludo
Me voy a tomar el atrevimiento de robar un pequeño espacio en el Club para "pensar en voz alta", y de paso, si hay algun interesado, comenzar un debate ;)
En mis ultimas aventuras programando con Delphi, me estoy dedicando mas que nada a refactorizar un sistema que vengo desarrollando desde practicamente que empece mi vida como programador: con el he aprendido, he crecido, he sufrido, he disfrutado.. en fin creo que todos pasamos por lo mismo
Pero ahora estoy refactorizando lo mas posible aplicando "los nuevos conceptos aprendidos" :D. Estoy seguro de que todos tenemos alguna porqueria de codigo por ahi escrito en mas de una clase (ok, en la gran mayoria :p)
Mi nuevo estilo de programacion es muy enfocado a la programacion orientada a objetos, casi en un estilo purista (el amigo escafandra me ha llamado en una ocasion, un enamorado de la POO)
Pasa algo de tiempo hasta que realmente uno se da cuenta que cuando diseña un form con el fabuloso IDE Delphi, en realidad lo que tiene es un objeto: tiene metodos, tiene propiedades, tiene una interfaz publica, una parte privada u oculta, todo aquello que todos ya sabemos que aprendimos, casi practicamente el primer dia que empezamos a estudiar POO
Y lo sabemos, pero cuando nos sentamos con Delphi nos olvidamos de todo y rompemos los principios basicos de POO, porque, seamos sinceros, es muy facil y rapido y todo parece funcionar bonito
No quiero determe mucho mas en esta pequeña reflexion, hay excelentes articulos que describenes esta situacion mucho mejor que yo, el que mas me gusto fue leer al compañero mamcx, en este enlace (http://blog.elmalabarista.com/post/4263479306/click-click-tap-run-crash-un-mejor-rad)
Lo ideal, como el tiempo me enseño, es meterse en la cabeza que cuando tenemos un TForm, y estamos diseñandolo, en realidad tenemos un objeto, y que debemos aplicar los principios basicos de POO; una efectiva regla que yo sigo para programar, consiste en diferenciar dos conceptos y cuales son sus equivalencias en nuestro codigo:
1. Cómo se hacen "las cosas"
2. Cuándo se hacen "las cosas"
El primer concepto evidentemente se podría traducir en métodos de los objetos
El segundo concepto hace referencia a los eventos de los objetos
Cuando diseñamos en "modo RAD", solemos usar los eventos para resolver el cuando cuándo y el cómo
Yo mismo he escrito código así:
procedure TForm1.KeyDown...;
begin
if Key = VK_F3 then
begin
btnGuardarArchivo.Click;
end;
end;
Me ha tomado tiempo darme cuenta de los problemas que supone esto:
1. Primero, si remplazo el boton por otro control, pierdo el evento, y tengo que "acordarme" de volver a llamar al metodo "vaya a saber uno que" del nuevo control
2. Me ha pasado que quiero realizar la funcion implementada dentro del boton en cuestion, desde un formulario externo, y no me ha quedado otra solucion que escribir esto:
VariableForm.btnGuardarArchivo.Click;
Obviamente empeora exponencialmente según lo explicado en el punto 1)
3. Es imposible (inmanejable) implementar herencia de forms de esta manera (mi nuevo gran descubrimiento del 2016)
Claramente es una muy mala idea el mezclar el cómo y el cuándo
Cual es la solución? Muy sencillo, declaramos e implementamos un metodo "GuardarArchivo" en la clase; ahora podemos invocarlo desde un monton de lados: desde una clase externa, desde el evento OnKeyDown, desde el AfterNoSeQue de aquel DataSet, etc. Ya no hay ningun problema con cambiar, o incluso eliminar el dichoso button
---
Otro tema importante: las propiedades. Los objetos tienen propiedades. Si, y los TForm tambien.
Quien alguna vez no ha escrito este tipo de porqueria (ehm, codigo):
var
Form1: TFormPersona;
begin
Form1 := TFormPersona.Create(Self);
Form1.edNomPers.Text := DataModule.qryBuscPersPorNom.FieldByName('npers').AsString;
Form1.ShowModal;
end;
Ok, lo admito, me esforzé en poner nombres complicados para hacerlo mas chistoso (me he topado con bases de datos que ponen nombres en las columnas que parecen cifrados)
Por que violamos los principios de POO, y accedemos directamente a la implementacion, al T(DB)Edit, para colocar "el nombre de la persona"?
Si podemos hacer algo mucho mejor, usar propiedades
var
Form1: TFormPersona;
begin
Form1 := TFormPersona.Create(Self);
Form1.PersonName := DataModule.qryBuscPersPorNom.FieldByName('npers').AsString;
Form1.ShowModal;
end;
Mucho mejor verdad? Basicamente las propiedades nos dan las mismas ventajas que los puntos que expuse mas arriba:
1. Encapsulamos implementacion (que diablos me importa como TFormPersona va a mostrar el nombre? Si no me gusta como lo hace me busco otro "componente" mas lindo)
2. Hacemos responsable al TFormPersona (o mejor dicho, confiamos en él) en que va a mostrar el nombre de la mejor manera posible.
Ok, en este caso fue un simple string; pero cuaaantas veces hemos hecho esto:
Form2.DateTimePicker1.DateTime := FormatDateTime('dddd-mm-yyyy', Today);
Vamos, no es mas sencillo hacer esto?
Form2.FechaDesde := Today;
---
Reflexiones acerca del metodo RAD: Cuando usar RAD? Es malo programar a lo RAD?
No estoy de acuerdo con los que dicen que es "malo", que crea programadores "maleducados", que no fomenta el uso de la POO
No estoy de acuerdo con los que lo defienden como algo "bueno"; que permite desarrollar rapido, que es facil, que es "visual basic"
Yo creo que es una metodologia incomprendida. Creo que hay casos de uso reales, o mejor dicho, situaciones o circustancias que ameritan el uso de RAD, e incluso es justificado
Si es cierto que todo lo que describí arriba, al principio es díficil; en el corto plazo, consume más tiempo: los beneficios son más bien a largo plazo, cuando ya sabes que si creas una subclase de TDimForm sabes que cuando se invoca a ShowModal automaticamente se oscurece la pantalla que esta "debajo" y luego cuando lo cierras todo vuelve a la normalidad; pero todo esto lleva tiempo
Asi que, si la respuesta a la pregunta: ¿Para qué vas a desarrollar X proyecto? es "ganar dinero", yo creo que el metodo RAD merece una cierta mención, un pequeño espacio en nuestro dia a dia:
Desarrollar una aplicacion a lo RAD lleva menos tiempo (por lo tanto menos dinero); asi que creo que es una buena forma de desarrollar prototipos, demos, o versiones preliminares del proyecto en cuestión, y hacer lo que yo llamo un "tanteo" o "estudio de mercado": Mostrar la aplicacion, ver como reacciona el publico, ver si se va a poder vender o ya desde el vamos esta mal. Incluso hoy en dia en las ultimas versiones de Delphi con los componentes de prototipado se puede disponer de "informacion de prueba" para los controles enlazados por LiveBindings, que es genial para casos como este
Y luego recién ahi "diseñar algo bien", o comenzar con el desarrollo como debe ser
---
Voy a finalizar este primer post con la idea que originó realmente la creación del mismo (hoy tenía ganas de expresarme y me fui por las ramas quizá :D)
Hay un problema que aún le veo a mi "metodo":
Muy bien, ahora tenemos los metodos públicos para invocar a la funcionalidad
Mejor aún, tenemos las propiedades para modificar el estado del objeto
Pero aún hay un problema, y es que Delphi aun asi te permite hacer alegremente esto:
Form2.CantCopiasImpresion := 3; // usando propiedad, bien!
Form2.edtCantidadCopias.Text := IntToStr(3); // Delphi permite acceder a un objeto privado del form!! porque!!
Estos casos se dan cuando se diseñan Forms con el IDE; si se implementa todo "a pulmón", es tan sencillo como incluir los componentes/controles en la visibilidad privada de Form2 y ya no se podrá acceder desde afuera (al menos no de la forma idiomatica); ya no estaremos escribiendo Form2 y al llegar al "." veremos en la lista "edtCantidadCopias"
Existirá alguna manera (o es viable que Embarcadero implemente) la posibilidad de ocultar estos detalles de implementación?
La primera solucion que vino a mi cabeza son interfaces; pero no estoy conforme con eso, ya que es facilmente hackeable ("solucionable"): en vez de usar la interface uso la clase! en un periquete! al demonio con la POO!
En fin, creo que el post ya es suficientemente largo
Un saludo