OOP vs. programación procedimental - página 11

 
Реter Konow:

En mi opinión, hay un fallo en su sistema de resolución de problemas. El problema en sí debe ser muy claro y preciso, y por lo tanto su solución también. Si la solución es turbia y se define con las palabras "El sistema ha demostrado ser muy razonable" (¡¿cómo puede ser razonable en 270 kb de código?!), significa que el autor entiende a grandes rasgos cómo funciona su sistema. Y son los espantosos artificios de la sintaxis y las entidades superfluas en la solución los que le impiden entenderla hasta el final.

La razonabilidad radica en el "poder de predicción": un cambio significativo de los protocolos de trabajo no requirió cambios en el código de los expertos responsables de la lógica de su trabajo. La modificación del código fue sólo en el lugar que manejaba directamente el terminal a bajo nivel.


El código dado muestra muy bien cómo todos los "OOP-hacks" pueden ser bien reemplazados con "functional hacks". Es decir, exactamente lo que decía más arriba: se puede escribir en ambos sentidos.

Pero mirando tu código veo que tienes que guardar mucho más en memoria. Digamos que en la mayoría de sus "si" me "ahogué" en un momento. Son correctos, pero si tuviera que mantener este código - insertaría antes de cada condición unas líneas de comentarios, qué hace esta comprobación y por qué se utilizan estos campos en el array. Similar al comentario antes de declarar la interfaz CTradePositionI en mi código. Además, las condiciones complejas también me estresarían mucho personalmente.

Personalmente, cometería más errores en su código, y sería más difícil detectarlos. Es decir, a pesar de la corrección y la lógica de dicho código me sería más difícil mantenerlo, que si lo hubiera escrito todo en estilo OOP.

En el estilo OOP declararía interfaces de ventanas, partes de lienzo, elementos, lienzo, luego escribiría clases reales de esos objetos, y luego daría punteros a esas interfaces en los bloques adecuados, y trabajaría específicamente con esas entidades, que serían necesarias en ese momento - todo lo demás no estaría disponible en ese momento. Esto es para que no tengas que recordar qué pertenece a qué y qué es responsable de qué. Cuando consigues la interfaz más sencilla, que consiste en un par de funciones, te limitas a trabajar con ella, y el resto es innecesario y no está disponible para ti. No necesitas recordar nada en absoluto.

 
George Merts:

Bueno, te has hecho un lío...

Está claro que cualquier tarea puede ser resuelta tanto al estilo OOP, con la asignación de interfaces, la construcción de la jerarquía de la herencia, la declaración de funciones virtuales, como al puro estilo procedimental - incluso se puede meter todo en una enorme función.

La cuestión está en la comodidad y la eficacia del apoyo.

En MT - el lugar más apropiado para la OOP es el sistema de pedidos. Personalmente, tengo interfaces virtuales para "posición" y "componentes de posición". "Posición" es un conjunto de órdenes en MT4 o un conjunto de posiciones en MT5. "Componente de la posición" es una orden individual o una posición individual de MT5 (cobertura o compensación).

Aquí está el archivo de la interfaz real(Retag Konow, se puede apreciar el número de comentarios en comparación con la cantidad de código, y periódicamente los agrego allí cuando encuentro algunas sutilezas que no recuerdo. Por ejemplo, suelo olvidar qué objetos reales constituyen un "componente de posición". Simplemente no necesito recordarlo - el Asesor Experto trabaja con componentes según la interfaz, y lo que hay detrás de esa interfaz en realidad no importa. Pero, tengo que volver a él durante la modificación - es por eso que necesito el primer comentario en este archivo muy a menudo):

El archivo de la interfaz del componente comercial es el siguiente (ya lo he dado más arriba, pero lo repetiré:

De acuerdo con estas interfaces - tengo implementado tanto el sistema de órdenes de MT4 como el de MT5 para órdenes reales e históricas.

El Asesor Experto que solicita una posición recibe esta interfaz y no tiene que tener en cuenta la diferencia entre las órdenes de MT4 y MT5. Y si se añade un nuevo tipo de orden o se cambia el orden de trabajo con ellos - nada cambiará para el Asesor Experto, sólo se añadirá la nueva clase de tipo de orden, y también soportará esta interfaz.

El sistema demostró ser muy inteligente cuando se introdujeron las cuentas de cobertura. Los expertos - absolutamente ningún cambio de eso.

Reg Konow, ¿cómo se maneja la diferencia de tipos de órdenes en MT4 y MT5?

Si se introduce un nuevo tipo de cuenta (además de la cobertura y la compensación), ¿qué cambios habrá que hacer, y en el mismo lugar?

En mi opinión, realmente, si recuerdas todo tu código al pie de la letra, y puedes decir fácilmente por qué se escribió tal o cual línea en tu código hace un año - entonces, realmente, todos estos potenciadores de POO son sólo gestos innecesarios.

La POO es necesaria precisamente cuando no te acuerdas de todo al modificar el código: la POO te permite aislar los bloques entre sí para limitar el conjunto de entidades disponibles en un momento dado a un lugar concreto del programa.


George, a veces escribes esas clínicas sobre las mujeres, pero respeta el código ))))

 
George Merts:

La razonabilidad radica en el "poder predictivo" -un cambio significativo en los protocolos de funcionamiento- no requirió cambios en el código EA responsable de la lógica de su funcionamiento. La modificación del código se hizo sólo en el lugar que manejaba directamente el terminal a bajo nivel.


El código dado muestra muy bien cómo todos los "OOP-hacks" pueden ser bien reemplazados con "functional hacks". Es decir, exactamente lo que decía más arriba: se puede escribir en ambos sentidos.

Pero mirando tu código veo que tienes que guardar mucho más en memoria. Digamos que en la mayoría de sus "si" me "ahogué" en un momento. Son correctos, pero si tuviera que mantener este código - insertaría antes de cada condición unas líneas de comentarios, qué hace esta comprobación y por qué se utilizan estos campos en el array. Similar al comentario antes de declarar la interfaz CTradePositionI en mi código. Además, las condiciones complejas también me estresarían mucho personalmente.

Personalmente, cometería más errores en su código, y sería más difícil detectarlos. Es decir, a pesar de la corrección y la lógica de dicho código, su soporte sería más difícil para ME que si lo hubiera escrito todo en estilo OOP.

En el estilo OOP declararía interfaces de ventanas, partes de lienzo, elementos, lienzo, luego escribiría clases reales de esos objetos, y luego daría punteros a esas interfaces en los bloques adecuados, y trabajaría específicamente con esas entidades, que serían necesarias en ese momento - todo lo demás no estaría disponible en ese momento. Esto es para que no tengas que recordar qué pertenece a qué y qué es responsable de qué. Cuando consigues la interfaz más sencilla, que consiste en un par de funciones, te limitas a trabajar con ella, y el resto es innecesario y no está disponible para ti. No tienes que recordar nada en absoluto.

En mi código, el gran número de fuentes y su anidamiento se debe al complejo comportamiento de diferentes definiciones de control en diferentes eventos y en diferentes estados. Sin embargo, esta función cubre todas estas opciones y "sirve" completamente a toda la GUI. Al redibujar cualquier elemento, el color de la pieza se determina por el valor del color original en el núcleo y esta función.

P.D. En cuanto al estilo OOP o procedimental, entonces - "A cada uno lo suyo" (c).

 
Alexey Volchanskiy:

Georges, a veces escribes un clinic sobre las mujeres, pero respeta el código )))

En cuanto al código, me siento halagado. (De verdad, no es broma).

Y sobre las chicas... No soy un casanova como tú... Yo soy el que se contiene y no dice lo que piensa... Siempre he tenido y tengo muchos problemas en ese sentido, aunque una vida personal cómoda siempre ha sido muy importante para mí... Menos mal que a veces la suerte me ha sonreído, y al fin y al cabo hay algo que recordar.

 
George Merts:

En cuanto al código, me siento halagado. (De verdad, no es broma).

Y sobre las mujeres... No soy un casanova como tú... Yo soy el que se contiene y no dice lo que piensa... Siempre he tenido y tengo muchos problemas en ese sentido, aunque una vida personal cómoda siempre ha sido muy importante para mí... Menos mal que a veces la suerte me ha sonreído, y al fin y al cabo hay algo que recordar.


Es que tenemos actitudes diferentes hacia las mujeres. Creo que hay que ayudarles. Sí, son malhumorados, con sus propias argucias, inconstantes en sus pasiones, etc. Sólo hay que no tomarlos en serio, de lo contrario habrá tragedias morales.

 
George Merts:

Bueno, te has hecho un lío...

Está claro que cualquier tarea puede ser resuelta tanto al estilo OOP, con la asignación de interfaces, la construcción de la jerarquía de la herencia, la declaración de funciones virtuales, como al puro estilo procedimental - incluso se puede meter todo en una enorme función.

La cuestión está en la comodidad y la eficacia del apoyo.


Podemos hacerlo, pero la eficacia del funcionamiento varía. No estamos hablando de apoyo aquí, es demasiado relativo.

Hay tareas que procedimentalmente no se pueden resolver de forma óptima.

 
Alexey Volchanskiy:

Simplemente tenemos diferentes actitudes hacia las mujeres. Creo que hay que ayudarles. Sí, son malhumorados, con sus manías, inconstantes en sus predilecciones, etc. Sólo hay que no tomarlos en serio, de lo contrario habrá tragedias morales.


Alexei, ¿has hecho un experimento sobre lo interminable que es el deseo de ayuda de una mujer? ¿Ha conocido la satisfacción de la ayuda y cuánto tiempo ha durado?

 
Реter Konow:


¿Supongo que ni siquiera utilizas estructuras para almacenar datos? Sus arrays multidimensionales me traen recuerdos del antiguo MQL4, donde había que utilizar este tipo de soluciones por falta de estructuras. Pero ahora, ¿qué sentido tiene? Por ejemplo

 int Элемент                     =  G_CORE[Окно][Деталь_полотна][_MAIN_ELEMENT];
 int Состояние_детали            =  G_CORE[Окно][Элемент][_CURRENT_STATE]; 

se puede sustituir por

 int Элемент                     =  G_CORE[Окно][Деталь_полотна].MAIN_ELEMENT;
 int Состояние_детали            =  G_CORE[Окно][Элемент].CURRENT_STATE; 

Esto es más corto, más seguro y más rápido. En el primer caso no hay control en la fase de compilación sobre los valores de los índices de los arrays que le pasas. Y luego tienes que limpiar todo tipo de "array fuera de rango" en tiempo de ejecución - y esto es en el mejor de los casos. Peor es cuando el índice es aceptable pero incorrecto. Por eso es una buena práctica de programación involucrar al compilador tanto como sea posible, detectando los errores en la etapa de compilación y no atrapándolos en tiempo de ejecución como en tu caso.

Sí, ahora mismo eres bueno recordando qué valores alimentar a dónde. Pero esto se debe probablemente a que está constantemente ocupado con este proyecto. Prueba a tomarte un descanso de, por ejemplo, medio año, y siente la diferencia. Algunas personas ya lo han mencionado. ¿O crees que todos somos escleróticos o algo así? :) Es algo común para un programador...

Así que la tarea consiste en minimizar la probabilidad de dispararse en el pie. Te recomiendo encarecidamente que crees tus propios tipos utilizando enum en lugar del omnipresente int. Y no necesariamente tienen que tener valores enumerados, lo principal es que sea un tipo independiente, que será controlado por el compilador, y no permitirá intercambiar argumentos de funciones, etc.

 

Escribo única y exclusivamente OOP.

En la década de los 1900, no pude entrar en ella: Pascal 6.0, luego Borland C++ 4.5. Pero cuando lo domino, no puedo imaginarme otra cosa, es tan sencillo y cómodo ahora.

 
Alexey Navoykov:

¿Supongo que ni siquiera utilizas estructuras para almacenar datos? Sus arrays multidimensionales me traen recuerdos del antiguo MQL4, donde había que utilizar este tipo de soluciones por falta de estructuras. Pero ahora, ¿qué sentido tiene? Por ejemplo

se puede sustituir por

Esto es más corto, más seguro y más rápido. En el primer caso no hay control en la fase de compilación sobre los valores de los índices de los arrays que le pasas. Y luego tienes que limpiar todo tipo de "array fuera de rango" en tiempo de ejecución - y esto es en el mejor de los casos. Peor es cuando el índice es aceptable pero incorrecto. Por eso es una buena práctica de programación involucrar al compilador tanto como sea posible, detectando los errores en la etapa de compilación y no atrapándolos en tiempo de ejecución como en tu caso.

Sí, ahora mismo eres bueno recordando qué valores alimentar a dónde. Pero esto se debe probablemente a que está constantemente ocupado con este proyecto. Prueba a tomarte un descanso de, por ejemplo, seis meses, y notarás la diferencia. Algunas personas ya lo han mencionado. ¿O crees que todos somos escleróticos o algo así? :) Es algo común para un programador...

Así que la tarea consiste en minimizar la probabilidad de dispararse en el pie. Te recomiendo encarecidamente que crees tus propios tipos utilizando enum en lugar del omnipresente int. Y no es necesario que tengan valores enumerados, lo principal es que sea un tipo independiente, que será controlado por el compilador, y no permitirá intercambiar argumentos de funciones, etc.

He leído tus posts en otros hilos y me he dado cuenta de que eres un gran experto en programación. Por supuesto, no soy ni pretendo serlo. Sin embargo, me considero un especialista en resolver tareas como tal. ¿No está de acuerdo en que la eficacia de la solución es lo más importante?

La sobrecarga de la sintaxis y la complejidad de las reglas nunca han contribuido a mantener la eficacia de la solución. La simplicidad y la brevedad, expresadas en la concisión, la universalidad y la legibilidad de los bloques de código, lo lograron.

Mis reglas en la programación son menos código, menos reglas, menos sintaxis y menos comentarios a expensas de utilizar el lenguaje nativo y nombres significativos de las variables y funciones.

Mi tesis principal es que "si se puede prescindir de algo en una solución, hay que prescindir de ello".

No creo que haya gente esclerótica aquí en absoluto)). Simplemente mirando los códigos dados queda claro por qué se olvidan fácilmente. Incluso el propio hecho de programar en una lengua extranjera influye. Cuando programas en tu propio idioma, la sensación es absolutamente diferente. Sientes poder y libertad en lugar de tensión y restricción. Un idioma extranjero requiere más esfuerzo, tarda más tiempo en introducirse en el código y se te escapa de la cabeza más rápidamente. Es sólo un "factor biológico".

Por lo tanto, considero (bastante razonablemente) ineficiente utilizar la POO en general para resolver mis tareas. Muchas reglas, sintaxis y todo en una lengua extranjera. De este modo, el talento no puede desarrollarse realmente, lo que significa que el resultado será más pobre.