Programação OOP vs procedimento - página 23

 
Maxim Kuznetsov:

Parece que você perdeu a conversa :-) os moderadores se agarraram a temas em chamas ... mas aqui é OOP vs.

A propósito, 99% dos @Peter Konow's usam OOP, mas ele não está ciente disso :-) O OOP não é necessariamente "classe & modelo".

E vice-versa, a propósito...a presença de objetos e classes em um programa não é indicativa do OOP

Esse é um pensamento muito interessante. Talvez seja, e eu não desconfio disso. ))


Mas como você sabe disso?

 
Реter Konow:

Esse é um pensamento muito interessante. Talvez seja, e eu não desconfio disso. ))


E como você sabe sobre isso?

Por exemplo, o OO pode ser implementado através do envio de mensagens (e com algumas "vantagens" que não estão na classe/modelo MQL),

Ainda não vi seu código e provavelmente não conseguirei lê-lo, mas como você tem uma biblioteca GUI, tenho certeza que ela tem sua própria (pelo menos uma) fila e através do processamento de eventos/envios/estados está toda embrulhada. E esta mesma "torção" no final é apenas herança/polimorfismo.

 
Dmitry Fedoseev:

Sobre o ouriço:

"O porco-espinho está na clareira, posando, flexionando seu bíceps: - Sou forte, sou corajoso, sou ágil, sou forte, sou corajoso, sou ágil...

Um urso passa - pontapeia-o uma vez, o ouriço voa atrás da árvore, levanta-se e sacode a si mesmo:

- Sou forte, corajoso, ágil... ...mas eu sou leve...


Como meu amigo de infância costumava dizer, o ouriço é um pássaro orgulhoso, se você não o chutar, ele não voará ))
 
Alexey Volchanskiy:

Georges, hoje fui dar um pequeno passeio com uma garota, conversamos um pouco, lembramos um pouco sobre homens tímidos. Honestamente, eu não me divirto, cada um tem personalidades diferentes e uma educação diferente.

Oh... E Lekha's para pintos... E com razão. Muito mais interessante do que o Partido Republicano.

Bem, meu problema não é timidez. É a "língua bem falada" que é a única coisa de que posso me gabar. Meu problema é o vaginocentrismo com a falta de dinheiro. Eu valorizo demais a privacidade e o sexo. Você escreveu acima, "...eu vi como os homens podem trabalhar duro quando mulheres bonitas se aproximam". Bem, eu sou um desses caras. Exceto, filhotes, eles precisam de você enquanto você é jovem, forte e rico. E se uma garota tem a chance de foder com você, mais cedo ou mais tarde ela vai foder com você. Mesmo um jovem, forte e rico. Sou um velho inválido sem um tostão e sem casa. Então minhas chances são nulas... Nem me surpreende que minha esposa tenha ido embora. Só que você parece não se importar com o fato de estar divorciado. Eu, por outro lado, acho extremamente frustrante que eu não tenha conseguido criar as condições em que minha esposa não pudesse sair.

 

E sobre o OOP...

Se eu tivesse a mesma memória que a Retag Konow, talvez concordasse que o OOP é desnecessário, de que adianta construir todas essas interfaces, classes, objetos, sistema de herança e funções virtuais...

Alexey disse corretamente - o processador não sabe nada sobre nenhum objeto... Ele nem sequer sabe nada sobre funções. O que prova que qualquer tarefa pode ser resolvida não apenas sem OOP, mas até mesmo sem funções, apenas lembrando endereços de retorno e passando o controle via registro IP (ou qualquer CPUs moderna que se utilize hoje em dia).

Eu não entendia a posição de Retug Konow até que ele me mostrou seu código. Agora tudo está claro e eu posso até concordar com ele, se eu conseguir manter tudo na memória e demorar se não me incomodar, eu suspeito que é mais razoável escrevê-lo da maneira como ele o faz. Além disso, neste caso, o OOP se torna realmente uma "quinta roda no carrinho".

Mas, pessoalmente, meu problema é que a maior parte das sutilezas do trabalho - isso me escorrega a mente. Por exemplo, sempre esquecerei o que cada índice na matriz multidimensional G_CORE é responsável; em cada condição em determinado fragmento - sempre pensarei seriamente - no que ele define. A análise de condições longas também será tensa para mim.

E às vezes eu mesmo escrevo tal código, o que é difícil de entender. Aqui está um fragmento do meu código"incorreto" onde estou afundando da mesma forma (já citei acima):

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 é a função da interface do componente comercial CTradePosComponentI, que determina se este componente está no breakeven.

"A "injustiça" deste código é que a legibilidade é sacrificada aqui à custa da compacidade e da legibilidade. Como a função está incluída na interface - eu queria que toda a interface estivesse visível em uma tela, se possível. Só para não ter que me lembrar das características que ele proporciona, para que todas essas características possam ser vistas de uma só vez. Se eu me lembrasse de tudo - não haveria necessidade de "esticar" a função em uma corda. Assim, a função se estendeu em uma dúzia de linhas - tudo bem... Entretanto, era importante para mim que todas as funções se encaixassem na interface uma ao lado da outra, e que todas elas fossem visíveis. Eu queria que uma olhada na interface me desse instantaneamente uma idéia do conjunto de funções que ela oferece. É por isso - eu tive que escrever as funções em uma longa linha. No entanto, é totalmente irrealista entendê-lo.

Inicialmente, ao escrever o código - eu escrevi esta função de forma bem diferente no início. De uma forma clara e com comentários. Para que eu pudesse entendê-lo.

Assim:

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); 
};

E somente depois de tudo isso ter sido testado e depurado - o código foi limpo de comentários e "puxado para a linha".

Mas isto é uma exceção. Faço isso muito raramente, em casos especiais, quando a "visibilidade" é importante. Em todos os outros casos - escrevo código tanto "largo" como com recuo, e com comentários em qualquer lugar, onde poderia haver o menor obstáculo com uma pergunta "o que está aqui".

Caso contrário, eu esqueço muito rapidamente onde, o que e para que serve

 
Maxim Kuznetsov:

Por exemplo, OO é bastante viável através do envio de mensagens (e com algumas "vantagens" que não estão na classe/modelo MQL),

Eu não olhei seu código e não consigo lê-lo, mas como você tem uma biblioteca GUI, tenho certeza de que ela tem sua própria (pelo menos uma) fila e através do processamento de eventos/sentenças/estados, há muitas coisas estragadas. E esta mesma "torção" no final é apenas herança/polimorfismo.

Bem, agora que eu disse "A", eu gostaria de dizer "B" também). Vou descrever minha tecnologia mais especificamente.

Ao combinar a funcionalidade trabalhando em um determinado tipo de tarefas em grandes blocos, reduzo o número de ligações que precisam ser construídas entre as funções. Isto tem seus prós e contras.

Primeiro sobre os profissionais:

No OOP, um mecanismo decomposto em um grande número de funções, requer a criação de muitos objetos para ligar as classes e as estruturas. Ao mesmo tempo, cada protótipo de função é cercado por um grande número de parâmetros formais, através dos quais a função se comunica com o código ao redor. A estrutura interna do código torna-se mais complexa precisamente por causa do aumento das ligações entre as partes do mecanismo durante o desenvolvimento deste mecanismo.

Em minha tecnologia, a comunicação entre funções e blocos é totalmente simplificada através do uso de variáveis globais, que são estampadas em toda a sua extensão. As funções não precisam passar parâmetros porque os vêem imediatamente em nível global.

Osvalores das variáveis globais são definidos pelo bloco Object Focus, que "rastreia" o cursor. Ele usa as coordenadas atuais do cursor para determinar em qual objeto o mouse está ligado e acessa o kernel (G_CORE) que armazena todas as propriedades de todos os elementos, objetos e janelas. A partir do núcleo, o bloco toma os valores atuais de todas as propriedades principais do objeto sob o cursor e os coloca nas variáveis globais. Se o cursor se mover sobre os objetos, as variáveis globais são redefinidas neste bloco e sempre correspondem ao objeto que está em foco.

Em seguida, a função OnChartEvent() captura os eventos do gráfico que devem mudar o estado do elemento sob o cursor. Nesses eventos, o bloco de controle estatal (que é integrado ao próprio OnChartEvent()) vê imediatamente qual janela, elemento e objeto estão em foco e quais são suas propriedades. Você não precisa passar nada para este bloco, porque tudo o que você precisa já está em foco, em variáveis globais. Sua tarefa é alterar os valores das propriedades do objeto no núcleo do G_CORE e redesenhar o elemento. Ele muda os valores e chama o bloco de sorteio.

Apenas três parâmetros precisam ser passados ao bloco de desenho - janela, tela e elemento. Ele redesenhou o elemento, dando-lhe uma aparência apropriada ao seu estado atual. Todas as funções auxiliares do bloco de pintura, também utilizam variáveis globais em foco. Por exemplo, a função acima "Color part()" usa "WINDOW", "OBJECT", "CATEGORY_OBJECT" etc... Tudo isso é muito útil.


Agora para os contras:

Sem dúvida, blocos grandes e objetos de foco simplificam a relação entre as partes de código, mas isso se deve ao fato de que os blocos são grandes, criando dificuldades quando se trabalha com eles. O idioma russo e a simplificação total da sintaxe me ajudam aqui, já que eu não uso o OOP.

Com o tempo, os blocos chegam a um ponto em que não precisam mais ser trocados e deixam de crescer. Gradualmente, sua estrutura é totalmente memorizada e o trabalho com eles é simplificado ao máximo.

É claro que a moagem de blocos em si é algo longo e doloroso, mas é disso que se trata a depuração de qualquer mecanismo.

 
George Merts:

E sobre o OOP...

Se eu tivesse a mesma memória que a Retag Konow, talvez concordasse que o OOP é desnecessário, de que adianta construir todas essas interfaces, classes, objetos, sistema de herança e funções virtuais...

Alexey disse corretamente - o processador não sabe nada sobre nenhum objeto... Ele nem sequer sabe nada sobre funções. O que prova que qualquer tarefa pode ser resolvida não apenas sem OOP, mas até mesmo sem funções, apenas lembrando endereços de retorno e passando o controle via registro IP (ou qualquer CPUs moderna que se utilize hoje em dia).

Eu não entendia a posição de Retug Konow até que ele me mostrou seu código. Agora tudo está claro e eu posso até concordar com ele, se eu conseguir manter tudo na memória e demorar se não me incomodar, eu suspeito que é mais razoável escrevê-lo da maneira como ele o faz. Além disso, neste caso, o OOP se torna realmente uma "quinta roda no carrinho".

Mas, pessoalmente, meu problema é que a maior parte das sutilezas do trabalho - isso me escorrega a mente. Por exemplo, sempre esquecerei o que cada índice na matriz multidimensional G_CORE é responsável; em cada condição em determinado fragmento - sempre pensarei seriamente - no que ele define. A análise de condições longas também será tensa para mim.

E às vezes eu mesmo escrevo tal código, o que é difícil de entender. Aqui está um fragmento do meu código"incorreto" onde estou afundando da mesma forma (já citei acima):

Esta é a função da interface do componente comercial CTradePosComponentI, que determina se este componente está no breakeven.

"A "injustiça" deste código é que a legibilidade é sacrificada aqui à custa da compacidade e da legibilidade. Como a função está incluída na interface - eu queria que toda a interface estivesse visível em uma tela, se possível. Só para não ter que me lembrar das características que ele proporciona, para que todas essas características possam ser vistas de uma só vez. Se eu me lembrasse de tudo - não haveria necessidade de "esticar" a função em uma corda. Assim, a função se estendeu em uma dúzia de linhas - tudo bem... Entretanto, era importante para mim que todas as funções se encaixassem na interface uma ao lado da outra, e que todas elas fossem visíveis. Eu queria que uma olhada na interface me desse instantaneamente uma idéia do conjunto de funções que ela oferece. É por isso - eu tive que escrever as funções em uma longa linha. No entanto, é totalmente irrealista entendê-lo.

Inicialmente, ao escrever o código - eu escrevi esta função de forma bem diferente no início. De uma forma clara e com comentários. Para que eu pudesse entendê-lo.

Assim:

E somente depois de tudo isso ter sido testado e depurado - o código foi limpo de comentários e "puxado para a linha".

Mas isto é uma exceção. Faço isto muito raramente - em casos particulares, quando a "visibilidade" é importante. Em todos os outros casos eu escrevo código tanto "largo" quanto recuado, e com comentários em qualquer lugar onde possa haver o menor obstáculo de uma pergunta "o que está aqui".

Caso contrário, esqueço muito rapidamente onde, o quê e para quê.

Nossas tarefas são muito diferentes, portanto, é difícil para mim dizer algo sobre suas soluções. Não tenho certeza se é apenas a minha memória, deve haver algo mais. Fazer sentido de seu próprio código sem dúvida melhora sua memorabilidade. Não estou dizendo que seu código é menos significativo. Só não sei como eu abordaria seus problemas. Talvez sua abordagem seja a correta. Eu não estou julgando. Pessoalmente, acho este estilo de código muito difícil de compreender.

Acho que é uma questão de hábito).

 
Реter Konow:

Nossas tarefas são muito diferentes, portanto, é difícil para mim dizer algo sobre suas soluções. Não tenho certeza se é apenas a minha memória, deve haver algo mais. Fazer sentido de seu próprio código, sem dúvida, torna mais fácil lembrá-lo. Não estou dizendo que seu código é menos significativo. Só não sei como eu abordaria seus problemas. Talvez sua abordagem seja a correta. Eu não estou julgando. Pessoalmente, acho este estilo de código muito difícil de entender.

Provavelmente, é uma questão de hábito).


É uma conversa completamente sem sentido: não há critério de classificar o código como "bom" ou "ruim". É por isso que não está claro sobre o OOP.

Para mim tal critério é a FACILIDADE do código, que se manifesta no fato de que o autor ou um terceiro pode ler o código e usá-lo para modificação, procurando por bugs após um período de tempo bastante longo.....


Aqui acima Fedoseyev substituiu a chave OOP. Este exemplo particular, talvez lamentável, para mim é uma prova da maldade do OOP: código claro com um interruptor de 100 posições é substituído por uma única linha. Para entender esta linha, você tem que ir a algum lugar. Não é permitido para mim.

O segundo exemplo acimapor George Merts

Quando o código claro foi substituído pelo código NÃO claro após a depuração. Pelo meu critério código de qualidade (fácil de ler) foi substituído por inaceitável para mim.


Então tenho uma pergunta a fazer a todos os defensores da OOP: o programa torna-se mais visível quando a OOP é aplicada e o exemplo dado por Fedoseev no interruptor é um fracasso ou, pelo contrário, o exemplo de Fedoseev caracteriza com muita precisão a OOP e a OOP quase sempre leva a uma perda de visibilidade?

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

1. Uma conversa completamente inútil: não há critério para classificar o código como "bom" ou "ruim". É por isso que não está claro sobre o OOP.

Para mim, tal critério é a FACILIDADE do código, que se manifesta no fato de que o autor ou um terceiro pode ler o código e usá-lo para modificá-lo, encontrar bugs após um período de tempo bastante longo.....


2. Aqui acima Fedoseyev substituiu a chave OOP. Este exemplo particular, talvez lamentável, para mim é uma prova de malícia do OOP: código claro com um interruptor de 100 posições é substituído por uma única linha. Para entender esta linha, você tem que ir a algum lugar. Não é permitido para mim.

O segundo exemplo acimapor George Merts

Quando o código claro foi substituído pelo código NÃO claro após a depuração. Pelo meu critério o código de qualidade (fácil de ler) foi substituído por inaceitável para mim.


3. Então tenho uma pergunta para todos os defensores da OOP: o programa torna-se mais visível quando a OOP é aplicada e o exemplo dado por Fedoseyev no interruptor é um fracasso, ou pelo contrário, o exemplo de Fedoseyev é uma descrição muito precisa da OOP e da OOP quase sempre leva a uma perda de visibilidade?


1. Há um critério. O critério principal é a velocidade.

A clareza do código é o critério errado. O código está escrito não para ser visto, mas para funcionar.

2. Vejo que alguns de nós não são suficientemente maduros para estruturar nosso código com funções. Então você está no tópico errado, você deve abordar o tópico "código de uma página versus código estruturado por função".

Além disso, a amostra não se tratava de estruturação e clareza/não-obviedade, mas de eliminar fragmentos de código de lastro.

3... por que você não... Aceitar gráficos de engenharia? Ou geometria descritiva. É tudo muito visual lá.

 
Dmitry Fedoseev:

A visibilidade do código é o critério errado. O código não é escrito para ser examinado, mas para funcionar.

Bem, eu discordo.

A visibilidade do código é uma coisa muito importante porque um código claro é muito mais fácil de manter e modificar.

Isso mesmo - eu escrevi uma função nua e depois a "ofusquei", tornando-a invisível e incompreensível. Esta foi uma decisão forçada. Neste caso, foi mais importante para mim tornar a classe inteira transparente. Eu sacrifiquei a clareza de uma função bastante trivial. É claro que poderíamos ter colocado o corpo desta função no arquivo .mq5, mas acredito que as interfaces não devem ser divididas em dois arquivos e devem ser completamente descritas no arquivo de cabeçalho .mqh.

Velocidade também é algo a se ter em mente, mas não acho que devemos nos esforçar por "velocidade a qualquer custo". Tem que haver uma suficiência razoável.

Razão: