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

 
Maxim Kuznetsov:

Parece que te has perdido la charla :-) los moderadores han tomado medidas contra los temas flaming ... pero aquí es OOP vs.

Por cierto, el 99% de @Peter Konow's utiliza OOP, pero no es consciente de ello :-) La POO no es necesariamente "clase y plantilla".

Y viceversa por cierto...la presencia de objetos y clases en un programa no es indicativo de POO

Es una idea muy interesante. Tal vez lo sea, y no lo sospecho. ))


¿Pero cómo lo sabes?

 
Реter Konow:

Es una idea muy interesante. Tal vez lo sea, y no sospecho que lo sea. ))


¿Y cómo lo sabes?

Por ejemplo, la OO puede ser implementada a través del envío de mensajes (y con algunos "pluses" que no están en la clase/plantilla MQL),

No he mirado tu código y probablemente no podré leerlo, pero como tienes una librería GUI, estoy seguro de que tiene su propia (al menos una) cola y mediante el procesamiento de eventos/envíos/estados se envuelve todo. Y esta misma "torsión" al final no es más que herencia/polimorfismo.

 
Dmitry Fedoseev:

Sobre el erizo:

"El erizo está de pie en el claro, posando, flexionando sus bíceps: - Soy fuerte, soy valiente, soy ágil, soy fuerte, soy valiente, soy ágil...

Pasa un oso y le da una patada, el erizo vuela detrás del árbol, se levanta y se sacude:

- Soy fuerte, soy valiente, soy ágil... ...pero soy ligero...


Como decía mi amigo de la infancia, el erizo es un pájaro orgulloso, si no le das una patada no vuela ))
 
Alexey Volchanskiy:

Georges, hoy he ido a dar un pequeño paseo con una chica, hemos charlado un poco, nos hemos acordado un poco de los hombres tímidos. Sinceramente, no me burlo, cada uno tiene diferentes personalidades y diferente educación.

Oh... Y Lekha es para las chicas... Y con razón. Mucho más interesante que el GOP.

Bueno, mi problema no es la timidez. La "lengua bien colgada" es lo único de lo que puedo presumir. Mi problema es el vaginocentrismo con la penosidad. Le doy demasiado valor a la privacidad y al sexo. Has escrito más arriba: "...he visto lo duro que pueden trabajar los chicos cuando las mujeres hermosas asoman por delante". Bueno, yo soy uno de esos tipos. Excepto, chicas, que te necesitan mientras eres joven, fuerte y rico. Y si una chica tiene la oportunidad de joderte, seguro que te jode antes o después. Incluso uno joven, fuerte y rico. Yo soy un viejo inválido sin dinero y sin casa. Así que mis posibilidades son nulas... Ni siquiera me sorprende que mi mujer me haya dejado. Sólo que a ti no parece importarte que estés divorciado. A mí, en cambio, me resulta extremadamente frustrante no haber podido crear las condiciones para que mi mujer no pudiera irse.

 

Y sobre la OOP...

Si tuviera la misma memoria que Retag Konow, quizás estaría de acuerdo en que la POO es innecesaria, para qué construir todas esas interfaces, clases, objetos, sistema de herencia y funciones virtuales...

Alexey dijo correctamente: el procesador no sabe nada de ningún objeto... Ni siquiera sabe nada sobre las funciones. Lo que demuestra que cualquier tarea puede ser resuelta no sólo sin POO sino incluso sin funciones, simplemente recordando las direcciones de retorno y pasando el control a través del registro IP (o lo que sea que usen las CPUs modernas hoy en día).

No entendí la posición de Retug Konow hasta que me mostró su código. Ahora todo está claro y hasta puedo estar de acuerdo con él, si consigo mantenerlo todo en la memoria y los largos si no me molestan, sospecho que es más razonable escribirlo como él lo hace. Además, en este caso la OOP se convierte realmente en una "quinta rueda del carro".

Pero, personalmente, mi problema es que la mayoría de las sutilezas del trabajo - se me escapa. Por ejemplo, siempre olvidaré de qué es responsable cada índice en el array multidimensional G_CORE; en cada condición en un fragmento dado - cada vez pensaré seriamente - lo que define. El análisis de las condiciones a largo plazo también será tenso para mí.

Y a veces yo mismo escribo ese código que es difícil de entender. Aquí hay un fragmento de MI código"incorrecto" en el que me estoy hundiendo de la misma manera (lo he citado arriba):

virtual bool IsTPCInUnloss() const { if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE) return(false); if(GetTPCType() == POSITION_TYPE_BUY) { if(GetTPCStopLoss() >= GetTPCOpenPrice()) return(true); } else { if(GetTPCStopLoss() <= GetTPCOpenPrice())return(true); }; return (false); };

Esta es la función de la interfaz del componente de negociación CTradePosComponentI, que determina si este componente está en el punto de equilibrio.

"Lo malo" de este código es que aquí se sacrifica la legibilidad a costa de la compacidad y la facilidad de lectura. Como la función está incluida en la interfaz, quería que toda la interfaz fuera visible en una sola pantalla, si era posible. Sólo para no tener que recordar qué características ofrece, para que todas esas características se puedan ver a la vez. Si lo recordara todo, no habría necesidad de "estirar" la función en una cadena. Así que la función se extendió en una docena de líneas - bien... Sin embargo, para mí era importante que todas las funciones encajaran en la interfaz, una al lado de la otra, y que todas fueran visibles. Quería que un vistazo a la interfaz me diera al instante una idea del conjunto de funciones que ofrece. Por eso, tuve que escribir las funciones en una sola línea larga. Sin embargo, es totalmente irreal entenderlo.

Al principio, al escribir el código, escribí esta función de forma bastante diferente. De forma clara y con comentarios. Para poder entenderlo.

Así:

virtual bool IsTPCInUnloss() const 
{ 
    // Отсеем вариант, когда СЛ отсутствует
    if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE)
         return(false);

    //  Проверим тип торговой компоненты
    if(GetTPCType() == POSITION_TYPE_BUY)
        { 
        // Торговая компонента - лонг
        if(GetTPCStopLoss() >= GetTPCOpenPrice())
            return(true);
        }
    else
        { 
        // Торговая компонента - шорт
        if(GetTPCStopLoss() <= GetTPCOpenPrice())
             return(true); 
        }; 

    return (false); 
};

Y sólo después de que todo esto se probara y depurara, el código se limpiaba de comentarios y se "ponía en línea".

Pero esto es una excepción. Lo hago en muy pocas ocasiones, en casos especiales en los que la "visibilidad" es importante. En todos los demás casos - escribo el código tanto "a lo ancho" como con sangría, y con comentarios en cualquier lugar, donde podría haber el más mínimo inconveniente con una pregunta "qué hay aquí".

De lo contrario, olvido muy rápidamente dónde, qué y para qué.

 
Maxim Kuznetsov:

Por ejemplo, la OO es bastante factible mediante el envío de mensajes (y con algunas "ventajas" que no están en la clase/plantilla MQL),

No he mirado tu código y no puedo leerlo, pero como tienes una librería GUI, seguro que tiene su propia cola (al menos una) y a través del procesamiento de eventos/sentencias/estados hay muchas cosas jodidas. Y esta misma "torsión" al final no es más que herencia/polimorfismo.

Bueno, ahora que he dicho "A", me gustaría decir también "B"). Describiré mi tecnología de forma más específica.

Al combinar la funcionalidad que trabaja en un tipo de tareas concreto en grandes bloques, reduzco el número de enlaces que hay que construir entre las funciones. Esto tiene sus pros y sus contras.

En primer lugar, sobre los pros:

En la programación orientada a objetos, un mecanismo desglosado en un gran número de funciones requiere la creación de muchos objetos para enlazar las clases con las estructuras. Al mismo tiempo, cada prototipo de función está rodeado de un gran número de parámetros formales, a través de los cuales la función se comunica con el código circundante. La estructura interna del código se vuelve más compleja precisamente por el aumento de los vínculos entre las partes del mecanismo durante su desarrollo.

En mi tecnología, la comunicación entre las funciones y los bloques se simplifica por completo mediante el uso de variables globales, que se estampan en todo momento. Las funciones no necesitan pasar parámetros porque los ven inmediatamente a nivel global.

Losvalores de las variables globales son fijados por el bloque Object Focus, que "rastrea" el cursor. Utiliza las coordenadas actuales del cursor para determinar sobre qué objeto está el ratón y accede al núcleo (G_CORE) que almacena todas las propiedades de todos los elementos, objetos y ventanas. Desde el núcleo, el bloque toma los valores actuales de todas las propiedades principales del objeto bajo el cursor y los coloca en las variables globales. Si el cursor se desplaza sobre los objetos, las variables globales se redefinen en este bloque y corresponden siempre al objeto que está enfocado.

A continuación, la función OnChartEvent() captura los eventos del gráfico que deben cambiar el estado del elemento bajo el cursor. En estos eventos, el bloque de control de estado (que está integrado en la propia OnChartEvent()) ve inmediatamente qué ventana, elemento y objeto están enfocados y cuáles son sus propiedades. No necesitas pasar nada a este bloque, porque todo lo que necesitas ya está en el foco, en las variables globales. Su tarea es cambiar los valores de las propiedades del objeto en el núcleo G_CORE y redibujar el elemento. Cambia los valores y llama al bloque Draw.

Sólo hay que pasar tres parámetros al bloque de dibujo: ventana, lienzo y elemento. Redibuja el elemento, dándole una apariencia adecuada a su estado actual. Todas las funciones auxiliares del bloque de pintura, también utilizan variables globales en foco. Por ejemplo, la función anterior "Color part()" utiliza "WINDOW", "OBJECT", "CATEGORY_OBJECT", etc. Todo esto es muy útil.


Ahora los contras:

Sin duda, los bloques grandes y los objetos de enfoque simplifican la relación entre las partes del código, pero es por el hecho de que los bloques son grandes, lo que crea dificultades al trabajar con ellos. El idioma ruso y la simplificación total de la sintaxis me ayudan aquí, ya que no uso OOP.

Con el tiempo, los bloques llegan a un punto en el que ya no es necesario cambiarlos y dejan de crecer. Poco a poco, su estructura se memoriza por completo y el trabajo con ellas se simplifica al máximo.

Por supuesto, la molienda de bloques en sí, es algo bastante largo y doloroso, pero de eso se trata la depuración de cualquier mecanismo.

 
George Merts:

Y sobre la OOP...

Si tuviera la misma memoria que Retag Konow, quizás estaría de acuerdo en que la POO es innecesaria, para qué construir todas esas interfaces, clases, objetos, sistema de herencia y funciones virtuales...

Alexey dijo correctamente - el procesador no sabe nada de ningún objeto... Ni siquiera sabe nada sobre las funciones. Lo que demuestra que cualquier tarea puede ser resuelta no sólo sin POO sino incluso sin funciones, simplemente recordando las direcciones de retorno y pasando el control a través del registro IP (o lo que sea que usen las CPUs modernas hoy en día).

No entendí la posición de Retug Konow hasta que me mostró su código. Ahora todo está claro y hasta puedo estar de acuerdo con él, si consigo mantenerlo todo en la memoria y los largos si no me molestan, sospecho que es más razonable escribirlo como él lo hace. Además, en este caso la OOP se convierte realmente en una "quinta rueda del carro".

Pero, personalmente, mi problema es que la mayoría de las sutilezas del trabajo - se me escapa. Por ejemplo, siempre olvidaré de qué es responsable cada índice en el array multidimensional G_CORE; en cada condición en un fragmento dado - cada vez pensaré seriamente - lo que define. El análisis de las condiciones a largo plazo también será tenso para mí.

Y a veces yo mismo escribo ese código que es difícil de entender. Aquí hay un fragmento de MI código"incorrecto" en el que me estoy hundiendo de la misma manera (lo he citado arriba):

Esta es la función de la interfaz del componente de negociación CTradePosComponentI, que determina si este componente está en el punto de equilibrio.

"Lo malo" de este código es que aquí se sacrifica la legibilidad a costa de la compacidad y la facilidad de lectura. Como la función está incluida en la interfaz, quería que toda la interfaz fuera visible en una sola pantalla, si era posible. Sólo para no tener que recordar qué características ofrece, para que todas esas características se puedan ver a la vez. Si lo recordara todo, no habría necesidad de "estirar" la función en una cadena. Así que la función se extendió en una docena de líneas - bien... Sin embargo, para mí era importante que todas las funciones encajaran en la interfaz, una al lado de la otra, y que todas fueran visibles. Quería que un vistazo a la interfaz me diera al instante una idea del conjunto de funciones que ofrece. Por eso, tuve que escribir las funciones en una sola línea larga. Sin embargo, es totalmente irreal entenderlo.

Al principio, al escribir el código, escribí esta función de forma bastante diferente. De forma clara y con comentarios. Para poder entenderlo.

Así:

Y sólo después de haber probado y depurado todo esto, se limpiaba el código de comentarios y se "tiraba a la línea".

Pero esto es una excepción. Yo lo hago así en muy pocas ocasiones, sobre todo cuando la "visibilidad" es importante. En todos los demás casos escribo el código tanto "a lo ancho" como con sangría, y con comentarios en cualquier lugar donde pueda haber el más mínimo inconveniente de una pregunta "qué hay aquí".

De lo contrario, me olvido rápidamente de dónde, qué y para qué sirve

Nuestras tareas son muy diferentes, así que me resulta difícil decir algo sobre sus soluciones. No estoy seguro de que sea sólo mi memoria, debe haber algo más. Dar sentido a su propio código hace que, sin duda, sea más fácil de recordar. No estoy diciendo que tu código sea menos significativo. No sé cómo enfocaría tus problemas. Tal vez su enfoque sea el correcto. No estoy juzgando. Personalmente, encuentro este estilo de código muy difícil de comprender.

Supongo que es una cuestión de costumbre).

 
Реter Konow:

Nuestras tareas son muy diferentes, así que me resulta difícil decir algo sobre sus soluciones. No estoy seguro de que sea sólo mi memoria, debe haber algo más. Dar sentido a su propio código hace que, sin duda, sea más fácil de recordar. No estoy diciendo que tu código sea menos significativo. No sé cómo enfocaría tus problemas. Tal vez su enfoque sea el correcto. No estoy juzgando. Personalmente, encuentro este estilo de código muy difícil de entender.

Probablemente sea una cuestión de costumbre).


Esuna conversación completamente sin sentido: no hay ningún criterio para clasificar el código como "bueno" o "malo". Por eso no está claro lo de OOP.

Para mí ese criterio es la VIABILIDAD del código, que se manifiesta en el hecho de que el autor o un tercero pueda leer el código y utilizarlo para modificarlo, buscando los errores después de un periodo de tiempo bastante largo.....


Aquí arriba Fedoseyev ha sustituido el interruptor OOP. Este ejemplo en particular, tal vez desafortunado, para mí es una prueba de la vileza de la POO: un código claro con un interruptor de 100 posiciones es reemplazado por una sola línea. Para entender esta línea hay que ir a algún sitio. No es permisible para mí.

El segundo ejemplode George Merts

Cuando el código claro fue reemplazado por el código NO claro después de la depuración. Según mi criterio, el código de calidad (fácil de leer) fue sustituido por el inaceptable para mí.


Así que tengo una pregunta para todos los partidarios de la POO: ¿el programa se hace más visible cuando se aplica la P OO y el ejemplo dado por Fedoseev sobre el interruptor es un fracaso o, por el contrario, el ejemplo de Fedoseev caracteriza con mucha precisión la POO y ésta casi siempre conduce a una pérdida de visibilidad?

 
СанСаныч Фоменко:

1. Una conversación completamente inútil: no hay ningún criterio para clasificar el código como "bueno" o "malo". Por eso no está claro lo de OOP.

Para mí, dicho criterio es la VIABILIDAD del código, que se manifiesta en el hecho de que el autor o un tercero pueda leer el código y utilizarlo para modificarlo, encontrar errores después de un periodo de tiempo bastante largo.....


2. Aquí arriba Fedoseyev ha sustituido el interruptor OOP. Este ejemplo en particular, tal vez desafortunado, para mí es una prueba de la viciosidad de la POO: un código claro con un interruptor de 100 posiciones es reemplazado por una sola línea. Para entender esta línea hay que ir a algún sitio. No es permisible para mí.

El segundo ejemplode George Merts

Cuando el código claro fue reemplazado por el código NO claro después de la depuración. Según mi criterio, el código de calidad (fácil de leer) fue sustituido por uno inaceptable para mí.


3. Así que tengo una pregunta para todos los partidarios de la POO: ¿el programa se hace más visible cuando se aplica la P OO y el ejemplo dado por Fedoseyev sobre el interruptor es un fracaso, o por el contrario, el ejemplo de Fedoseyev es una descripción muy precisa de la POO y la POO casi siempre conduce a una pérdida de visibilidad?


1. Hay un criterio. El criterio principal es la velocidad.

La claridad del código es el criterio equivocado. El código está escrito no para ser mirado sino para funcionar.

2. Ya veo, resulta que algunos no somos lo suficientemente maduros para estructurar nuestro código con funciones. Así que estás en el tema equivocado, deberías dirigirte al tema "código de una página vs. código estructurado por funciones".

Además, la muestra no trataba de la estructuración y la claridad/no obviedad, sino de la eliminación de fragmentos de código de lastre.

3... por qué no... ¿Empezar con la ingeniería gráfica? O la geometría descriptiva. Todo es muy visual allí.

 
Dmitry Fedoseev:

La visibilidad del código es un criterio equivocado. El código no se escribe para ser mirado, sino para funcionar.

Bueno, no estoy de acuerdo.

La visibilidad del código es algo muy importante porque un código claro es mucho más fácil de mantener y modificar.

Así es, escribí una función desnuda y luego la "ofusqué", la hice no visible e incomprensible. Esta fue una decisión forzada. En este caso, era más importante para mí que toda la clase fuera transparente. He sacrificado la claridad de una función bastante trivial. Por supuesto, podríamos haber puesto el cuerpo de esta función en el archivo .mq5, pero creo que las interfaces no deberían estar divididas en dos archivos y deberían estar completamente descritas en el archivo de cabecera .mqh.

La velocidad también es algo que hay que tener en cuenta, pero no creo que debamos buscar la "velocidad a toda costa". Tiene que haber una suficiencia razonable.

Razón de la queja: