Conversando sobre a OLP no salão - página 5

 
Alexey Volchanskiy:

Li os diferentes interesses de cada um... Estou atualmente redesenhando uma classe para exposição e controle da grade virtual, eu preciso dela.

E eu tenho lutado durante 2 dias com o construtor de cópias e o operador da tarefa. É uma classe complicada com membros de dados sob a forma de ponteiros.

 
Dennis Kirichenko:

Há dois dias estou lutando com o construtor de cópias e o operador da tarefa. Há uma classe complexa com membros de dados sob a forma de ponteiros.

Parece que escrevo coisas muito primitivas...

 
Dennis Kirichenko:

Você pode usar um ponteiro para uma função.

Funcionaria dessa forma com uma função virtual?

Sempre não gostei de indicadores de função internamente, e não me lembro por que, ao trabalhar em "C puro" - foram usados indicadores de função. Mas quando mudei para C++ tive que desistir deles por alguma razão. E não as utilizo desde então. Um ponteiro - deve ser para um objeto.

Mas eu não vou dizer que estou "absolutamente certo". Concordo que tenho muita experiência da velha guarda da velha guarda em mim.

 
fxsaber:

Parece que escrevo coisas muito primitivas...

Não seja modesto.

Não creio que alguém possa igualar seu uso virtuoso das definições.

 
George Merts:


...Comigo, esta função se parece com esta:

int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(_CompareByPartOfMaxDDWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(_CompareByPartOfMaxDDWith(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,false));

      case FSM_BY_LAST_PRCDATA_A:      return(_CompareByLastPrcdataWith(pfdsAnother,true));
      case FSM_BY_LAST_PRCDATA_D:      return(_CompareByLastPrcdataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYDATA_A:      return(_CompareByLastMnydataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYDATA_D:      return(_CompareByLastMnydataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYLOTDATA_A:   return(_CompareByLastMnylotdataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYLOTDATA_D:   return(_CompareByLastMnylotdataWith(pfdsAnother,false));
      
      case FSM_BY_PRCYEARRECOVERY_A:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,true));
      case FSM_BY_PRCYEARRECOVERY_D:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYYEARRECOVERY_A:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYYEARRECOVERY_D:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYLOTYEARRECOVERY_A:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYLOTYEARRECOVERY_D:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,false));
      
      case FSM_BY_PRCVAR_A:            return(_CompareByPrcVarWith(pfdsAnother,true));
      case FSM_BY_PRCVAR_D:            return(_CompareByPrcVarWith(pfdsAnother,false));
      case FSM_BY_MNYVAR_A:            return(_CompareByMnyVarWith(pfdsAnother,true));
      case FSM_BY_MNYVAR_D:            return(_CompareByMnyVarWith(pfdsAnother,false));
      case FSM_BY_MNYLOTVAR_A:         return(_CompareByMnylotVarWith(pfdsAnother,true));
      case FSM_BY_MNYLOTVAR_D:         return(_CompareByMnylotVarWith(pfdsAnother,false));
      
      case FSM_BY_PRC_GRAILRATIO_A:    return(_CompareByPrcGrailratioWith(pfdsAnother,true));
      case FSM_BY_PRC_GRAILRATIO_D:    return(_CompareByPrcGrailratioWith(pfdsAnother,false));

      case FSM_BY_MAGIC_A:             return(_CompareByMagicWith(pfdsAnother,true));
      case FSM_BY_MAIGC_D:             return(_CompareByMagicWith(pfdsAnother,false));
      default:
         break;
      };
         
   return(NULL);
};

George, você não pode ver aqui se _CompareByPrcVarWith() é um método de classe ou uma função comum, por exemplo. Em C++, há indicações sobre os métodos de classe. Eles têm lá suas próprias especificidades. Para ser honesto, eu não tentei usar tais ponteiros na MQL5.

Mas eu acho que você ainda tem uma reserva para melhorar a estrutura do código.

Afinal de contas, o que é uma função?

FUNÇÃO(lat.functio, "execução, desempenho; dever") é uma relação entre elementos em que uma mudança em um implica uma mudança no outro.

É uma função que faz alguma coisa. As mesmas ações devem ser combinadas no corpo de uma função.

Em seu exemplo, é óbvio que as funções

_CompareByPartOfMaxDDWith(),

_CompareByPartOfMaxSLQueueWith(),

_CompareByLastPrcdataWith(),

_CompareByLastMnydataWith(), etc.

fazer um COMPARARISE e dar o resultado desta comparação. Eles diferem nos nomes. Imho, não é uma boa prática. Eles devem se distinguir por parâmetros.

Portanto. Acho que você deveria fundir todas as funções em uma só, ou torná-las como métodos virtuais, ou métodos modelo. Obviamente, as classes devem seguir a hierarquia "pai-filho".

De modo geral, é muito fácil escrever códigos complexos e muito difícil escrever códigos simples.

 
Dennis Kirichenko:

George, você não pode ver aqui se _CompareByPrcVarWith() é um método de classe ou uma função comum. Em C++ há indicações sobre os métodos de classe. Eles têm lá suas próprias especificidades. Honestamente, não tentei usar tais indicadores na MQL5.

Esta (e todas aquelas que começam com um sublinhado) é uma função de proteção da classe.

Eles estão engajados no ARRANGEMENTO e dão o resultado desta comparação. Eles diferem nos nomes. Imho, não é uma boa prática. É melhor que sejam diferentes nos parâmetros.

Portanto. Acho que você deveria fundir todas as funções em uma só, ou torná-las como métodos virtuais, ou métodos modelo. Obviamente, as classes devem seguir a hierarquia "pai-filho".

Bem, todos eles estão fundidos em um só!

Há apenas uma função - Comparar() mas ela tem que realizar uma comparação com uma chave passada. De forma correspondente, escolhemos uma das funções específicas do protetor. É por isso que eles são protegidos (protegidos), para que o usuário não possa acessá-los - eles são chamados apenas de Compare() e isto é indicado sublinhando.

Esta também é uma das regras de projeto de código - uma função que começa com um sublinhado não se destina a ser chamada pelos usuários, ela serve apenas a certas tarefas da classe. O acesso a ele é restrito.

 
Dennis Kirichenko:

Há dois dias estou lutando com o construtor de cópias e o operador da tarefa. Há uma classe complexa com membros de dados sob a forma de ponteiros.


Denis, eu queria dizer que todos têm abordagens diferentes. Na verdade, quando eu abri a linha ontem, eu estava interessado em ver se os queixumes de ontem iriam aparecer, a la "a-a-a-a OOP é muito complicado, SB é uma caixa preta horrível". Eles não apareceram, o que é de se esperar.

Mas as pessoas têm surgido e cada uma tem uma abordagem diferente. Também é interessante em termos de projetos compartilhados, dos quais Renat tanto fala.

ZS: a participação em projetos ainda não funciona, tentou recentemente.

 
George Merts:

Isto (e todos aqueles que começam com um sublinhado) são funções de proteção da classe.

Bem, eles estão fundidos em um só!

Há apenas uma função - Comparar(), mas ela deve realizar uma comparação com uma chave passada. Correspondentemente, uma das funções protestadas em particular é escolhida. É por isso que eles são protegidos (protegidos), para que o usuário não possa acessá-los - eles são chamados apenas de Comparar(), o que é indicado pelo sublinhado.

Esta também é uma das regras de projeto de código - uma função que começa com um sublinhado não se destina a ser chamada pelos usuários, ela serve apenas a certas tarefas da classe. O acesso a ele é restrito.


Como eles são fundidos se você tem muitos métodos _CompareXXX() ? E deveria haver 1 como eu o entendo.

A pergunta, por exemplo, é o método_CompareByPartOfMaxDDWith() chamado em qualquer outro lugar, exceto na série CFactoryBalanceResultSeries::Comparar() ?

 
Dennis Kirichenko:

Como fundir se você tem muitos métodos _CompareXXX() ? E deveria haver 1 como eu o entendo.

A pergunta, por exemplo, é o método_CompareByPartOfMaxDDWith() chamado em qualquer outro lugar, exceto na série CFactoryBalanceResultSeries::Comparar() ?

Se o método _CompareXXX() está sozinho, não é diferente da função virtual Comparar() original.

A questão é que os métodos _CompareBy...() são chamados apenas a partir do Comparativo Principal(). E o sublinhado no início adverte sobre isso.

O método Compare() geral aceita apontadores para dois objetos e a chave que especifica a comparação. Neste método geral, a chave é analisada, e depois é chamado o método específico, que é projetado para comparar apenas uma chave. Além disso, cada um desses métodos calcula o valor das chaves de dois objetos passados e dependendo se a chave é int, double, bool ou string - o método (também protegido) de comparação do tipo concreto é chamado de

Todos os métodos _CompareBy...() - poderíamos escrever em uma função. Mas então, na minha opinião, a legibilidade do código se deterioraria.

 
George Merts:

Se houver apenas um método _CompareXXX(), ele não é diferente da função virtual Comparar() original.

A questão é que os métodos _CompareBy...() são chamados apenas a partir do Comparativo Principal(). E o sublinhado no início adverte sobre isso.

O método Compare() geral aceita apontadores para dois objetos e a chave que especifica a comparação. Neste método geral, a chave é analisada, e depois é chamado o método específico, que é projetado para comparar apenas uma chave. E cada um desses métodos calcula o valor das chaves de dois objetos passados e dependendo se a chave é int, double, bool ou string - é chamado de método (também protegido) de comparação do tipo concreto.

Todos os métodos _CompareBy...() poderiam ser escritos em uma única função. Mas então a legibilidade do código se deterioraria, em minha opinião.


Eu entendo o que você quer dizer. Acho que é uma questão de gosto. Mas eu faria tudo em um só método. Especialmente, se métodos protegidos e privados não forem chamados em nenhum outro lugar, excetoComparar().