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

 
Реter Konow:

Na minha opinião, há uma falha em seu sistema de solução de problemas. O problema em si deve ser cristalino e preciso e, portanto, sua solução também. Se a solução está nublada e definida pelas palavras "O sistema se mostrou muito razoável" (como pode ser razoável em 270 kb de código?!), isso significa que o autor entende aproximadamente como seu sistema funciona. E são os artifícios assustadores de sintaxe e entidades supérfluas na solução que o impedem de compreendê-la até o fim.

A razoabilidade reside no "poder preditivo" - uma mudança significativa dos protocolos de trabalho não exigiu mudanças no código dos especialistas responsáveis pela lógica de seu trabalho. A modificação do código estava apenas no local que manipulava diretamente o terminal a um nível baixo.


O código dado mostra muito bem como todos os "hacks" do OOP podem ser bem substituídos por "hacks funcionais". Isto é, exatamente o que eu estava dizendo acima - pode ser escrito nos dois sentidos.

Mas, olhando para seu código, vejo que você tem que manter muito mais na memória. Digamos, na maioria de seus "se" eu "afoguei" em um momento. Eles estão corretos, mas se eu tivesse que manter este código - eu inseriria antes de cada condição algumas linhas de comentários, o que esta verificação faz e por que estes campos são usados na matriz. Semelhante ao comentário antes de declarar a interface CTradePositionI em meu código. Além disso - condições complexas - também me estressariam muito pessoalmente.

Eu pessoalmente cometeria mais erros em seu código, e seria mais difícil pegá-los. Isto é, apesar da correção e lógica de tal código, seria mais difícil para mim mantê-lo, do que se eu o tivesse escrito tudo no estilo OOP.

No estilo OOP eu declararia interfaces de janelas, partes de tela, elementos, telas, depois escreveria classes reais desses objetos, e então daria indicações para essas interfaces nos blocos certos, e trabalharia especificamente com essas entidades, o que seria necessário no momento - tudo mais estaria indisponível naquele momento. Isto para que você não tenha que lembrar o que pertence a quê e o que é responsável por quê. Quando você obtém a interface mais simples que consiste em algumas funções, você simplesmente trabalha com ela, e o resto é desnecessário e indisponível para você. Você não precisa se lembrar de nada.

 
George Merts:

Bem, você fez uma bagunça...

É claro que qualquer tarefa pode ser resolvida tanto no estilo OOP, com alocação de interfaces, construção de hierarquia de herança, declaração de funções virtuais, como em puro estilo procedimental - você pode até mesmo colar tudo em uma enorme função.

A questão está na conveniência e eficiência do apoio.

Em MT - o lugar mais apropriado para o OOP é o sistema de pedidos. Pessoalmente, tenho interfaces virtuais para "posição" e "componentes de posição". "Posição" é um conjunto de ordens em MT4 ou um conjunto de posições em MT5. "Posição componente" é um pedido individual ou uma posição MT5 individual (hedge ou netting).

Aqui está o arquivo de interface real(Retag Konow, você pode apreciar o número de comentários em comparação com a quantidade de código, e eu os adiciono periodicamente lá quando encontro algumas sutilezas que não me lembro. Por exemplo, eu esqueço regularmente quais objetos reais constituem um "componente de posição". Só não preciso lembrar - o Expert Advisor trabalha com componentes de acordo com a interface, e o que está por trás dessa interface na realidade não importa. Mas, eu tenho que voltar a ele durante a modificação - é por isso que eu preciso do primeiro comentário neste arquivo com muita freqüência):

O arquivo para a interface do componente comercial é o seguinte (eu já o dei acima, mas vou repeti-lo:

De acordo com estas interfaces - tenho o sistema de pedidos MT4 e MT5 implementado tanto para pedidos reais como para pedidos históricos.

O Expert Advisor que solicita uma posição recebe esta interface e não precisa levar em conta a diferença entre as ordens MT4 e MT5. E se um novo tipo de pedido for adicionado ou a ordem de trabalho com eles for alterada - nada mudará para o Expert Advisor, apenas a nova classe de tipo de pedido será adicionada, e ele também suportará esta interface.

O sistema provou ser muito inteligente quando as contas de cobertura foram introduzidas. Os especialistas - absolutamente nenhuma mudança em relação a isso.

Reg Konow, como você lida com a diferença nos tipos de pedidos em MT4 e MT5 ?

Se um novo tipo de conta for introduzido (além de hedge e netting) - quais mudanças precisarão ser feitas, e no mesmo lugar ?

Na minha opinião, realmente, se você se lembra de todo seu código à letra, e pode facilmente dizer por que esta ou aquela linha foi escrita em seu código há um ano - então, na verdade, todos estes aperfeiçoamentos do OOP são apenas gestos desnecessários.

OOP é necessário precisamente quando você não se lembra de tudo ao modificar o código - OOP permite isolar blocos uns dos outros para limitar o conjunto de entidades disponíveis em um determinado momento a um determinado lugar no programa.


George, você às vezes escreve uma clínica desse tipo sobre mulheres, mas respeite o código ))))

 
George Merts:

A razoabilidade reside no "poder de previsão" - uma mudança significativa nos protocolos operacionais - não exigiu mudanças no código EA responsável pela lógica de sua operação. A modificação do código foi feita somente no local que manipulava diretamente o terminal a um nível baixo.


O código dado mostra muito bem como todos os "hacks" do OOP podem ser bem substituídos por "hacks funcionais". Isto é, exatamente o que eu estava dizendo acima - pode ser escrito nos dois sentidos.

Mas, olhando para seu código, vejo que você tem que manter muito mais na memória. Digamos, na maioria de seus "se" eu "afoguei" em um momento. Eles estão corretos, mas se eu tivesse que manter este código - eu inseriria antes de cada condição algumas linhas de comentários, o que esta verificação faz e por que estes campos são usados na matriz. Semelhante ao comentário antes de declarar a interface CTradePositionI em meu código. Além disso - condições complexas - também me estressariam muito pessoalmente.

Eu pessoalmente cometeria mais erros em seu código, e seria mais difícil capturá-los. Isto é, por toda a correção e lógica de tal código, seu suporte seria mais difícil para mim do que se eu tivesse escrito tudo isso no estilo OOP.

No estilo OOP eu declararia interfaces de janelas, partes de tela, elementos, telas, depois escreveria classes reais desses objetos, e então daria indicações para essas interfaces nos blocos certos, e trabalharia especificamente com essas entidades, o que seria necessário no momento - tudo mais estaria indisponível naquele momento. Isto para que você não tenha que lembrar o que pertence a quê e o que é responsável por quê. Quando você obtém a interface mais simples que consiste em algumas funções, você apenas trabalha com ela, e o resto é desnecessário e indisponível para você. Você não precisa se lembrar de nada.

Em meu código, o grande número de fontes e seus ninhos se deve ao complexo comportamento de diferentes definições de controle em diferentes eventos e em diferentes estados. Entretanto, esta função cobre todas estas opções e "serve" plenamente a toda a GUI. Ao redesenhar qualquer elemento, a cor da peça é determinada pelo valor da cor original no núcleo e por esta função.

P.S. em relação ao OOP ou estilo de procedimento, então - "Para cada um o seu" (c).

 
Alexey Volchanskiy:

Georges, você às vezes escreve uma clínica desse tipo sobre mulheres, mas respeite o código )))

Sobre o código - Sinto-me lisonjeado. (Realmente, sem brincadeira).

E sobre os filhotes... Eu não sou um Casanova como você... Sou eu quem se retrai e não diz o que estou pensando... Sempre tive e ainda tenho muitos problemas a esse respeito, embora uma vida pessoal confortável tenha sido sempre muito importante para mim... É bom que às vezes a sorte sorriu para mim, e há algo a ser lembrado, afinal de contas.

 
George Merts:

Sobre o código - Sinto-me lisonjeado. (Realmente, sem brincadeira).

E sobre as mulheres... Eu não sou um Casanova como você... Sou eu quem se retrai e não diz o que eu penso... Sempre tive e ainda tenho muitos problemas a esse respeito, embora uma vida pessoal confortável tenha sido sempre muito importante para mim... É bom que às vezes a sorte sorriu para mim, e há algo a ser lembrado, afinal de contas.


É que temos atitudes diferentes em relação às mulheres. Acho que eles devem ser ajudados. Sim, eles são caprichosos, com suas próprias quibbles, inconstantes em suas predileções, etc. Basta não levá-los a sério, caso contrário, haverá tragédias morais.

 
George Merts:

Bem, você fez uma bagunça...

É claro que qualquer tarefa pode ser resolvida tanto no estilo OOP, com alocação de interfaces, construção de hierarquia de herança, declaração de funções virtuais e em puro estilo processual - você pode até mesmo colar tudo em uma enorme função.

A questão está na conveniência e eficiência do apoio.


Podemos fazer isso, mas a eficiência da operação varia. Não estamos falando aqui de apoio, é muito relativo.

Há tarefas que não podem ser resolvidas de forma otimizada.

 
Alexey Volchanskiy:

Apenas temos atitudes diferentes em relação às mulheres. Acho que eles devem ser ajudados. Sim, eles são rabugentos, com suas peculiaridades, inconstantes em suas predileções, etc. Basta não levá-los a sério, caso contrário, haverá tragédias morais.


Alexei, você já fez alguma experiência sobre como é infinito o desejo de ajuda de uma mulher? Você já encontrou a satisfação da ajuda e quanto tempo ela durou?

 
Реter Konow:


Presumo que você nem usa estruturas para armazenar dados? Suas matrizes multidimensionais trazem de volta memórias da antiga MQL4, onde você tinha que usar tais soluções por falta de estruturas. Mas agora qual é o objetivo? Por exemplo

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

você poderia substituí-lo por

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

Isto é mais curto, mais seguro e mais rápido. No primeiro caso, não há controle na fase de compilação sobre os valores dos índices de array que você passa para ele. E então você tem que limpar todos os tipos de "conjuntos fora de alcance" em tempo de execução - e isto é na melhor das hipóteses. Pior ainda é quando o índice é aceitável, mas incorreto. É por isso que é uma boa prática de programação envolver o compilador tanto quanto possível, detectando erros na fase de compilação e não capturá-los em tempo de execução, como no seu caso.

Sim, neste momento você é bom em lembrar quais valores alimentar para onde. Mas isto provavelmente se deve ao fato de que você está constantemente ocupado com este projeto. Tente fazer uma pausa por, digamos, seis meses, e você sentirá a diferença. Algumas pessoas já mencionaram isso. Ou você acha que somos todos escleróticos ou algo assim? :) É uma coisa comum para um programador...

Portanto, a tarefa é minimizar a probabilidade de atirar no próprio pé. Recomendo vivamente que você crie seus próprios tipos usando enumeração em vez da intrigante ubíqua. E eles não precisam necessariamente ter valores enumerados, o principal é que é um tipo independente separado, que será controlado pelo compilador, e não permitirá que você troque argumentos de função, etc.

 

Eu escrevo única e exclusivamente OOP.

Nos anos 1900, eu não conseguia entrar nele - Pascal 6.0, depois Borland C++ 4.5. Mas quando a domino, não consigo imaginar mais nada - agora é tão simples e conveniente.

 
Alexey Navoykov:

Presumo que você nem usa estruturas para armazenar dados? Suas matrizes multidimensionais trazem de volta memórias da antiga MQL4, onde você tinha que usar tais soluções por falta de estruturas. Mas agora qual é o objetivo? Por exemplo

você poderia substituí-lo por

Isto é mais curto, mais seguro e mais rápido. No primeiro caso, não há controle na fase de compilação sobre os índices de matriz que você lhe dá. E então você tem que limpar todos os tipos de "conjuntos fora de alcance" em tempo de execução - e isto é na melhor das hipóteses. Pior ainda é quando o índice é aceitável, mas incorreto. É por isso que é uma boa prática de programação envolver o compilador tanto quanto possível, detectando erros na fase de compilação e não capturá-los em tempo de execução, como no seu caso.

Sim, neste momento você é bom em lembrar quais valores alimentar para onde. Mas isto provavelmente se deve ao fato de que você está constantemente ocupado com este projeto. Tente fazer uma pausa por, digamos, meio ano, e sinta a diferença. Algumas pessoas já mencionaram isso. Ou você acha que somos todos escleróticos ou algo assim? :) É uma coisa comum para um programador...

Portanto, a tarefa é minimizar a probabilidade de atirar no próprio pé. Recomendo vivamente que você crie seus próprios tipos usando enumeração em vez da intrigante ubíqua. E eles não precisam ter valores enumerados, o principal é que é um tipo independente separado, que será controlado pelo compilador, e não permitirá que você troque argumentos de função, etc.

Li seus posts em outros tópicos e percebi que você é um grande especialista em programação. É claro que não sou e não pretendo ser tal. No entanto, considero-me um especialista em resolver tarefas como tal. Bem, você não concorda que a eficácia da solução é a coisa mais importante?

A sobrecarga de sintaxe e complexidade das regras nunca contribuiu para manter a solução eficiente. Foi a simplicidade e a brevidade expressas na concisão, universalidade e legibilidade dos blocos de código que o fizeram.

Minhas regras na programação são menos código, menos regras, menos sintaxe e menos comentários às custas do uso de linguagem nativa e nomes significativos de variáveis e funções.

Minha tese principal é "se você pode prescindir de algo em uma solução, você deve definitivamente prescindir".

Acho que não há escleróticos aqui)). Olhando simplesmente para os códigos dados, torna-se claro por que eles são facilmente esquecidos. Mesmo o próprio fato de programar em uma língua estrangeira tem um papel importante. Quando você programa em seu próprio idioma, a sensação é absolutamente diferente. Você sente poder e liberdade ao invés de tensão e restrição. Uma língua estrangeira exige mais esforço, leva mais tempo para entrar no código e escorrega de sua cabeça mais rapidamente. É apenas um "fator biológico".

Portanto, considero (razoavelmente) ineficiente usar o OOP em geral para resolver minhas tarefas. Muitas regras, sintaxe e tudo em uma língua estrangeira. Desta forma, o talento não pode realmente se desenvolver, o que significa que o resultado será mais pobre.