Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Lightbulb Encapsulamiento en Forms

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" . Estoy seguro de que todos tenemos alguna porqueria de codigo por ahi escrito en mas de una clase (ok, en la gran mayoria )

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

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í:

Código Delphi [-]
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:

Código Delphi [-]
  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):

Código Delphi [-]
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

Código Delphi [-]
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:

Código Delphi [-]
  Form2.DateTimePicker1.DateTime := FormatDateTime('dddd-mm-yyyy', Today);

Vamos, no es mas sencillo hacer esto?

Código Delphi [-]
  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á )

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:

Código Delphi [-]
  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
Responder Con Cita
  #2  
Antiguo 22-02-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.099
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Creo que todo lo que cuentas se aprende a usar con la experiencia, porque como bien dices, al principio se usa la facilidad del IDE/RAD, aunque te das cuenta de los problemas pasado un tiempo cuando tienes que cambiar algo. Es entonces cuando empiezas a "refactorizar", a dejarlo más "profesional". Yo lo llamo "dejarlo bonito".
Pero eso toma tiempo, y si tienes a alguien esperando para entregarlo, es imposible "perder" tanto tiempo y al final lo dejas que funcione, aunque no cumpla correctamente la POO.
Con el tiempo empiezas un segundo gran proyecto, intentas "hacerlo bien" desde el principio y, realmente, está mucho mejor, has pensado todos los detalles, todos los métodos que necesitarás implementar para tener un sistema "decente", pero has tardado más tiempo y a veces tienes que dejar cosas para más adelante, para cuando tengas tiempo.
Si tienes la oportunidad de empezar un nuevo gran tercer proyecto, te dices: "esta vez va a ser un sistema perfecto desde el principio hasta el fin". Y lo consigues, pero las quejas por el tiempo empleado van en aumento, se retrasa la entrega del proyecto, empiezan las malas caras y finalmente tienes que claudicar y dar los últimos módulos en plan "que funcione y listo".
Con el tiempo, la experiencia, decides sobre la marcha en qué vale la pena "perder" el tiempo y en qué no.
Con los años vas viviendo cada etapa y finalmente después de muchos años decides hacer "tu" programa perfecto cumpliendo todas las normas de la POO, GUI, etc. pero ya quizás te apetezca no meterte en lios y te conformas con que simplemente siga funcionando bien todo lo que has hecho y que no te cree problemas
En definitiva, pienso que la mayoría de nosotros queremos "hacer las cosas bien, tanto lo que ve el usuario como lo que hay por debajo", pero la realidad de nuestra sociedad nos obliga a hacer cosas que los usuarios "lo vean y funcione bien aunque por debajo tenga algún parche", total, ellos no lo van a ver, ni les importa nada, solamente quieren las cosas lo más antes, y barato, posible. Les da igual si cumple perfectamente la POO, total, ni saben ni les interesa saber lo que es
Es que somos unos frikis.
Responder Con Cita
  #3  
Antiguo 22-02-2016
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.918
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
La GUI es una parte notoriamente dificil de hacer bien, lo cual se evidencia, entre otras cosas, por la imposibilidad de hacer una GUI multiplataforma realmente buena (solo se puede hasta cierto punto).

El problema que experimentan con Delphi es similar en todos lados: Delphi hereda los problemas del API de windows, de la OOP de entonces. Hacer GUI en web es jodido porque se heredan los problemas de html/css/js. Y así por el estilo. Abstraer esos problemas ayuda en unas cosas, pero tiene el lio de que hay que re-implementar varias otras, por lo que es una propuesta difícil.

Este tema me toca porque llevo dandole vueltas a hacer un lenguaje/herramienta y la parte de la GUI es algo que le llevo cavilando un rato, y nada de lo que hay me convence del todo (no es que no haya una solución: es que implica rehacer los controles!)

Hay formas de hacerlo mejor? Si. Pero requiere ayuda de los lenguajes/herramientas porque como dice:

Cita:
Empezado por Casimiro
Pero eso toma tiempo, y si tienes a alguien esperando para entregarlo, es imposible "perder" tanto tiempo y al final lo dejas que funcione, aunque no cumpla correctamente la POO.
Si las herramientas, APIs, etc no colaboran el esfuerzo empieza a "cansar" hasta el purista mas dedicado.


Cita:
Empezado por AgustinOrtu Ver Mensaje
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!

Hay varias cosas que son parte fundamental del problema. La OOP? Es uno de ellos!. Especificamente, la *herencia*.

Mal #1: Herencia

Como dice Agustin, el lio es que la herencia arrastra un montón de cosas y hay que esforzarse por "ocultarlas". Ironicamente, se supone que la OO promueve el encapsulamiento, pero la herencia no ayuda en ese sentido.

Peor aun, la mayoría de los toolkits gráficos se basan en armar arboles como TControl -> TEdit -> TEditPassword | TEditNumber -> TEditMoney, etc.

La falla sistematica de esto se evidencia en que cuando se adquiere una libreria (como decir, devexpress, o se usa firemonkey) hay QUE REHACER TODOS LOS CONTROLES. La OO, tal como se hizo popular cuando Delphi nació, ha fallado en su cometido en esta area especifica.

Ahora, OO es un paradigma que combina al dedillo con la GUI, asi que esto es un lio de como se ha usado de forma general...

Mal #2: Coordinacion

El segundo y mas grande problema es de coordinación. Por ejemplo, necesito deshabilitar el boton "Login" si los campos "Password1/2" no cumple con mis N-validaciones.

Aun este escenario "sencillo" muestra que hacer la coordinación es difícil (tipicamente: Requiere regar código en varios lados, hacer callbacks, y rastrear la lógica cuando se hace depuración). Cuando uno entonces intenta hacer una pantalla mas compleja, se nota mucho la carga que el manejo de estado implica ("código spaguetti!").

Mal #3: Estado + Tiempo

El siguiente gran lio es el manejo del estado y como este muta en el tiempo. Quienes hacen apps webs se dan cuenta lo simple -relativamente- que es hacer código de formularios, y eso es porque la web es "sin-estado" por defecto (opera en batch). Esto es facil porque una vez que tengo los datos del formulario, se con exactitud, que esos son los datos y no tengo que coordinarme con nadie mas diferente, si acaso, de la BD, que como esta es transaccional, todo me sale limpio.

EL problema es que el código OO tiende a tener decenas/cientos/miles de estados internos destructivos, y coordinar y estar pendiente de eso se vuelve complicado y difícil de manejar. Combinado con manejar la BD, archivos, eventos del sistema, etc todo se confabula para hacer la vida difícil.

Cuando se tiene código "Sin-estado", estructuras "inmutables" y funciones "idempotentes y sin efectos secundarios" es supremamente mas facil.

Eso es lo que los proponentes de los lenguajes funcionales llevan rato diciendo. Sin embargo, la GUI es nativamente "con-estado y mutable" así que no se puede ir al extremo en este asunto - que es por lo que les ha fallado el mensaje-.

Ademas, es critico que lo que toca la GUI sea rapido, y ahi manejar estado es vital.

----------

RAD no es incompatible con hacer código mas limpio. Sin uno se fija, armar la parte visual de las apps en Delphi es fantastico (mucho mas que en Visual Studio, Xcode... y de ahi en adelante todo es un asco). Es lo que pasa en el *código* lo que complica la cosa.

---------

Como se ve manejo de GUI mejor? Bueno, si han visto el sistema Modelo-Vista-Controlador y similares, entonces no es muy lejos. La Web tiene un modelo casi ideal, lastima que usa DOM, CSS y Javascript! - que lo complica mucho-.

Asi es como seria (usando como ejemplo, una pantalla login):

1- EL modelo es simple:

Código PHP:
//LoginModel es facil de testear, e independiente de plataforma, diseño,
//toolkit y demás!

class LoginModel:
    
Email=EmailString
    Pass1
=PassString
    Pass2
=PassString

//EmailString y PassString son strings que han pasado validaciones y con
//certeza no están vacíos

constructor Login.create(email:EmalStringpass1pass2:PassString)

function 
Login.TryLogin():Boolean
//Hacer el login


//Esto valida las cadenas
function isValidEmail(value:string):Boolean

function isValidPassword(value:string):Boolean 
Ahora, esto es solo una idea de modelo. Puede ser aun mas simple (como un hashtable) y no usarse e ir directo al controlador.

-------

Para la parte de GUI, la idea es usar composición en vez de herencia. Ahora el problema es que Delphi, VS usa herencia por todos lados.

Porque composición? Porque en una GUI se reusa un monton de cosas. Por ejemplo, bordes, fondos, captura de eventos de teclado, etc. En vez de tener una arbol profundo de clases, seria ideal poder elejir que usar, como:

Código PHP:
//Supongamos que intento hacer un control de chart de barra

//No heredo nada, excepto declaro soy un control, pero si hago composicion
class ChartBar:UIControl
    
//Esto es privado!
    
BarRectangle array
    
KeyListenKeyboardListener
    MouseListen
MouseListener

function create()
    
this.parent parent
    this
.view.dimensiones = ...
    
this.view.Add(Bar)

    
this.KeyListen.ListenFor(this.view)
    
this.MouseListen.ListenFor(this.view)

//Metodos de negocio!
function draw(values:Integer Array)
    for 
value in values
        this
.Bar[i].draw(width=10height=value
Para coordinar, tengo 2 lios: Como coordino valores con controles, y como coordino el thread de la GUI con el de negocios (para no bloquear la GUI).

Para el primer caso, el modelo reactivo (http://reactivex.io/) y los controles reactivo (https://facebook.github.io/react/) son una gran mejora.

Para el segundo, es el mismo lio que el manejo multi-hilo, el modelo de Actor, pero en especial, el de CSP es todo un avance (https://swannodette.github.io/2013/0...ial-processes/).

-----

Con respecto a que se puede hacer en Delphi? Todo esto (ya el lenguaje es mas que avanzado)

1- La parte de hacer los formularios se puede dejar tal cual
2- Hacer el modelo es trivial en Delphi
3- Hacer el coordinador es la parte compleja, porque Delphi, que yo sepa, no tiene una solucion inmediata.
4- Hacer la parte de multi-hilos es muy viable. Delphi ya tiene muchas mejoras. Implementar CSP estoy viendo como es pero parece ser muy simple...
__________________
El malabarista.

Última edición por mamcx fecha: 22-02-2016 a las 16:26:56.
Responder Con Cita
  #4  
Antiguo 22-02-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Me extraña un poco no leer en estos mensajes tan interesantes nada acerca de las Acciones. No recuerdo en qué versión de Delphi se introdujeron pero claramente fueron una corrección de Borland para evitar la barbarie de progamar directamente en los manejadores de eventos de los controles visuales. Pero además, las Acciones centralizan las validaciones. Por ejemplo, esto:

Cita:
Empezado por mamcx
El segundo y mas grande problema es de coordinación. Por ejemplo, necesito deshabilitar el boton "Login" si los campos "Password1/2" no cumple con mis N-validaciones.

Aun este escenario "sencillo" muestra que hacer la coordinación es difícil (tipicamente: Requiere regar código en varios lados, hacer callbacks, y rastrear la lógica cuando se hace depuración). Cuando uno entonces intenta hacer una pantalla mas compleja, se nota mucho la carga que el manejo de estado implica ("código spaguetti!").
yo no le veo problema. Se usa el evento OnUpdate de la acción asociada al botón para hacer las N validaciones.

LineComment Saludos
Responder Con Cita
  #5  
Antiguo 22-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Cita:
Me extraña un poco no leer en estos mensajes tan interesante nada acerca de las Acciones
Cierto, pero tienen un problema.

La aplicacion esta constantemente realizando los chequeos (esta todo el tiempo recorriendo los ActionList y ejecutando los eventos OnUpdate), lo cual puede terminar siendo un gasto innecesario

Saludos
Responder Con Cita
  #6  
Antiguo 22-02-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No me parece un argumento sólido. En cualquier aplicación siempre hay algo recorriendo los controles y verificando cosas (ya seamos nosotros mismos o el sistema operativo). Desde luego, si las validaciones son muy complejas (como, por ejemplo, incluir consultas a base de datos) se puede ver afectado el rendimiento de la aplicación, pero bien utilizadas no tiene por qué dar problemas. Y, al final de cuentas, las acciones resumen mucho de lo que uno termina programando en aras de evitar lo que comentas desde un principio.

LineComment Saludos
Responder Con Cita
  #7  
Antiguo 22-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Sigo pensando que exponer un metodo es mejor

Como ejecutas una accion desde afuera del form en cuestion?
Responder Con Cita
  #8  
Antiguo 22-02-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Ah, pero es que yo no estoy peleado con lo que propones. Su usamos el manejador de una acción para todo, terminamos simplemente traslandando el problema a otro lugar.

De todas formas, habría que ver las justificaciones en cada caso particular para llamar desde el exterior un determinado método. Por ejemplo, ¿por qué llamar al método GuardarArchivo? No digo que sea el caso, pero posiblemente GuardarArchivo no debería ser, en primera instancia, un método del formulario, sino de otro objeto al cual llama el formulario. Es decir, ¿por qué anexar el método final para guardar un archivo a la interfaz de usuario que pregunta dónde guardarlo? Repito, no es que sea el caso, pero habría que ver en cada situación las justificaciones.

LineComment Saludos
Responder Con Cita
  #9  
Antiguo 22-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Yo tampoco estoy peleando, es simplemente un intercambio de ideas

Estoy de acuerdo con lo que propones:

Código Delphi [-]
type
  IGuardadorDeArchivos = interface
    procedure GuardarArchivo(const Ruta: string);
  end;


...

var
  Form: TAlgunForm;
  GuardadorDeArchivos: IGuardadorDeArchivos;
begin
  GuardadorDeArchivos := TGuardadorDeArchivos.Create;
  Form := TAlgunForm.Create(Self, GuardadorDeArchivos);
end;

// en algun otro punto se puede disparar esto

procedure
begin
  GuardadorDeArchivos.GuardarArchivo('C:\nueva carpeta\');
end;

Eso es genial, pero lo que a mi me molesta es que si yo quisiera, podria hacer esto:

Código Delphi [-]
procedure
begin
  Form.ActionList1.Actions[0].ExecuteTarget(NIL);
  Form.ActionGuardarArchivoExecute({hay que mandar un parametro sender ¡?¡?¡?¡});
end;

La "solucion" es meter el ActionList en la parte privada del form e instanciarlo en runtime

Pero es muy incomodo, a todos nos gusta diseñar forms con el IDE; por codigo es mucho mas tedioso (una subclase de TForm es "posible" manejar el layout de todo los controles por codigo, pero cuando estas por los tataranietos de TForm?? se hace imposible)

Código Delphi [-]
type
  TFormAlgo = class(TForm);
    // todo lo que esta desde aca hasta el "private" es accesible desde afuera! esto me molesta mucho
    edRutaArchivo: TEdit;
    btnAceptar: TButton;
    btnCancelar: TButton;
  private
  end;
Responder Con Cita
  #10  
Antiguo 22-02-2016
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por AgustinOrtu Ver Mensaje
Yo tampoco estoy peleando, es simplemente un intercambio de ideas
Ja, ja. Nunca quise decir que estuviéramos peleando. Dije:

Cita:
Empezado por myself
Ah, pero es que yo no estoy peleado con lo que propones
como una forma de decir que no estoy en desacuerdo. Otra cosa habría sido decir:

Cita:
Empezado por myself
Ah, pero es que yo no estoy peleando contigo


LineComment Saludos
Responder Con Cita
  #11  
Antiguo 22-02-2016
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.918
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por roman Ver Mensaje
En cualquier aplicación siempre hay algo recorriendo los controles y verificando cosas

.... si las validaciones son muy complejas (como, por ejemplo, incluir consultas a base de datos) se puede ver afectado el rendimiento de la aplicación

Claro que es así. El asunto no es de posibilidades, sino de comodidad , pero mas importante, de claridad y que el código sea correcto.

El problema de la GUI es que los datos se "mueven" en el tiempo, y esto muta los objetos. Mantener la coordinación requiere moverse entre varios lugares (que cierto que acciones y demás cosas ayudan). La idea aqui es como evitarlo? Como centralizarlo? Como "aplanar" el proceso?

-----
Pensemos por ejemplo, en el caso de la pantalla de login, que ademas chequea en tiempo real si el usuario ya esta tomado, y obtiene el gravatar de ese correo. Debe ademas actualizar la interface de forma correcta, no interrumpir y que ademas cuando le de "Login" cancele cualquier solicitud de red pendiente.

En un estilo tipico, esto seria relativamente engorroso de hacer. Veamos como es al estilo de "Programacion Reactiva". Me perdonan la syntaxis inventada pero me di cuenta que si lo hago en otros lenguajes le puedo meter cosas que tocaria explicar.

Código PHP:
FetchNetwork Events.
    ([
email], TextChange)
    .
each(function editevent
        
return IsValidEmail(edit.text)
    
//Ejecutar concurrentemente las llamadas de red, sin esperar la anterio
    
).nextAsync(function edit
        fetchGravatar
(edit.text)
    ).
nextAsync(function edit
        isEmailTaken
(edit.text)
    
//Cuando obtengo ambas respuestas...
    
).merge(function imgisTaken
        
if isTaken
            
return False

        form
.imgUser.Load(img)

        return 
True
    
)
//Password parecen validos, y son iguales
IsValidPass Events.
    ([
Pass1Pass2], TextChange)
    
//Por cada control...
    
.each (function editevent
        
return IsValidPassword(edit.Text)
    )
    .
merge()
    .
filter(function result1:boolresult2:bool
        
//Si son iguales
        
result1==result2
    
)

//Combino todo
Loop Events.([IsValidPassFetchNetwork])

//Cuando login Ok, cancelo el proceso de eventos

Loop.Stop() 
La parte importante, es que se puede hacer composicion de eventos, que estos hacen cascada y que solo continuan cuando el anterior tiene exito (o saca error, y se va al manejo de errores), por lo tanto, si esto en .filter(function result1:bool, result2:bool) ya se con certeza que las claves son validas y solo queda averiguar si son iguales. Se tengo que agregar otros edits no hay problema, y como puede hacer composicion y combinan eventos, puedo generar una libreria de soluciones universales y re-combinar al gusto.

El estilo anterior tiene la contra de que es un monton de callbacks y eso se pone algo pesado a la vista. Es mucho mas limpio si se hace con Communicating sequential processes, pero lastima no hay mucho de eso en el mundo GUI.

El asunto es que se requiere algo de ayuda del lenguaje para que sea natural de operar.
__________________
El malabarista.
Responder Con Cita
  #12  
Antiguo 23-02-2016
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
No olviden que no es necesario programar "en visual". Me explico: crear componentes con código. Puedes crear toda la aplicación sin usar el diseñador ni los recursos, haciendo herencia, poniendo los componentes en la sección PRIVATE de nuestros objetos de ventana... Mucho más OO, y encima genera ejecutables más pequeños.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #13  
Antiguo 23-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Claro que se puede, pero es más difícil

Diseña un reporte con una línea de herencia de 3 o 4 clases, vamos que no está fácil
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
MDI Forms karocs Varios 8 12-07-2007 16:38:03
MDI Forms La__X C++ Builder 3 01-06-2006 06:08:00
Forms nenufer Varios 5 17-05-2006 22:16:37
dll con forms Rafa Varios 10 15-02-2005 20:43:11
Forms.....por fa buitrago Varios 1 19-11-2003 22:42:52


La franja horaria es GMT +2. Ahora son las 18:36:44.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi