Sobre o estilo de codificação - página 3

 

Prefiro separar as funções em ações separadas, para que o código tenha uma estrutura clara... é mais fácil de otimizar...

 
Mathemat >> :

Basicamente, é o código normal que realiza os mesmos cálculos que o aninhado se construção. Mas em algum lugar eu ouvi dizer que o retorno na função deveria ser um. Provavelmente, isso é feito para não se misturar neles. Eu não sigo estritamente esta regra.

Em outros aspectos, minha abordagem é muito próxima à sua, C-4, exceto por alguns detalhes.


Sim, existe essa opinião. Mas o operador de retorno não é a mesma coisa que GOTO. Na prática, nunca encontrei nenhum lançamento de retorno inesperado. Pelo contrário, o programa se torna mais legível e texturizado quando tais operadores e condições são utilizados (todas as verificações vão uma a uma de cima para baixo formando uma espécie de coluna). Além disso, ao contrário de se() o retorno do operador garantir uma saída da função, e isto é exatamente o que é necessário na maioria dos casos, pois não adianta avaliar mais os dados se alguma condição não for cumprida.

 

Gostei muito da última regra: "Nunca usar a operação 'copiar e colar'". Mas, infelizmente, eu não o sigo. Como é possível usar o editor IDE e não usar o "Copy&Paste" que economiza muito tempo?

Acontece que não: noto que é por causa disso que muitas vezes encontro erros lógicos, que são difíceis de serem apanhados.

P.S. O mecanismo do fórum não me permite formatar este fragmento do meu primeiro post

// open
// .pairsToOpen
// .combineAndVerify( )
// Собирает из двух валют символ и выполняет все проверки, нужные для его открытия.
// Возвращает валидность пары для открытия.
// Последний аргумент - [...]
bool
combineAndVerify( string quoted, string base, double& fp1 )

exatamente do jeito que é feito comigo: as três primeiras linhas parecem diferentes, mais estruturadas. OK, por gancho ou por vigarista:


Como eu comento as funções

 

Aqui estão mais algumas regras que me vieram à mente recentemente e que eu já implementei em meu próprio lugar:


1. As variáveis globais (GV) não são declaradas todas no início do código, mas conforme necessário, antes das funções correspondentes que as utilizam.

2. Antes de cada função, também descrevemos quais GPs ele usa (input) e quais modifica (output) quando é realmente chamado. E após a função, você também pode explicar quais GPs não serão mais usados.

3. Todos estes comentários, juntamente com linhas de separação vazias entre funções e limitação "comprimento da função não superior a 20 linhas" aumentam o tamanho do arquivo de código 1,5-2 vezes. Não torna mais difícil a compilação, e não temos papel de sobra nele.

4. Para que os GPs são úteis? Suponha que calculamos alguma variável de tipo complexo em foo( ..., <tipo>& variável ), passando-a por referência. Então, se usarmos esta variável repetidamente em vários fragmentos de código, teremos que chamar a função foo( ) a cada vez. Parece estar tudo bem - além de gastarmos tempo cada vez para avaliação desta variável, adicionamos também um par de linhas (para declaração de variável e chamada de função) em cada função usando a variável. Por quê? Se isto é assim chamado de reutilização de código, é de alguma forma subótimo: além de fazer com que foo( ) funcione muito freqüentemente em uso, também quebramos a estrutura das chamadas de função, fazendo com que foo( ) funcione "fora das categorias" e suas chamadas não sejam hierárquicas. É mais fácil declarar a variável como uma variável "fora de categoria", ou seja, global.

Pessoalmente, eu preferiria funções hierárquicas rígidas a uma reutilização tão questionável do código. Já disse sobre a hierarquia: cada função da n-ésima ordem é chamada apenas por uma função da (n-1)-a ordem e apenas "sua própria" função. Veja meu exemplo que explica a hierarquia de funções na figura com fundo verde acima.

5. Mas é claro, o código nem sempre é ótimo no sentido da hierarquia, e às vezes é preciso chamar funções "alienígenas". Neste caso, você pode escrever seu lugar na hierarquia de funções entre parênteses /* */ antes do nome da função "alienígena".


Talvez tudo isso seja bobagem e excessivo, mas sei muito bem que estou escrevendo código que provavelmente terei que editar mais de uma vez. Aqui acho que é melhor me tranquilizar em comentários e estruturação.

 
Vinin >> :
Sobre o tamanho da função. Eu tento fazer com que a função se ajuste a uma tela. Para que você possa ver a coisa toda.

Eu tento escrever código para que o código fonte possa ser corrigido em blocos, e é conveniente adicionar e mudar

os comentários não devem ser inferiores a 30% do tamanho do código

( aprendeu a fazer isso nos 80x, olhando para o código fonte dos sistemas operacionais UNIX, RT11)

meio ano depois o código é esquecido - se você precisar corrigi-lo, os comentários lhe darão uma rápida compreensão do assunto!

(eu tive uma experiência real em um local de produção quando estava lendo meu próprio código após 5 anos)

graças aos comentários, lembrei-me de tudo em um dia e fiz mudanças até a noite)

Eu tento alinhar o código para que a legibilidade não seja prejudicada por espaços e recuos.

compare os dois exemplos ! qual código lê melhor ?


1)

extern string gslM001rus="Все что касается индикации" ;
// 
extern bool gpInfoParameter =false ; // выводить параметры
extern bool gpInfoLevel =true ; // выводить параметры
extern bool _gDeleteObjectGrafic =0 ; // 1-Удалять объекты на графике при завершении 0-не удалять
extern double FlatSBuy =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int DayHistory =50 ; // Сколько дней в истории показывать
// флет азии 
extern int iTimeEndFlatAsiaHour = 5 ; // Конец утреннего флета
extern int iTimeEndFlatAsiaMin = 15 ; // Конец утреннего флета
// Время длины флета измеряется минутами от окончания и назад
// 360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
extern int iTimeEndFlatAsiaSizeMin = 360 ; // + количество минут  флета// 
extern string sTimeBreakFlatAsia ="20:00:00" ; // Время до которого разумно ждать пробой и выставление ордеров
extern int pУровниHighLowDAY =1 ; // выводить уровни HIGH LOW
extern color ЦветПятницыHIGH =DeepSkyBlue ;
extern color ЦветПятницыLOW =DeepSkyBlue ;
extern color ЦветHIGHDAY =DarkViolet ;
extern color ЦветLOWDAY =DarkViolet ;
extern color lColorFAH =OrangeRed ;
extern color lColorFAL =SandyBrown ;
extern color lColorSignalSELL =Red ;
extern color lColorSignalBUY =Red ;

 


2)


extern string gslM001rus="Все что касается индикации"      ;
//                                                                  
extern bool   gpInfoParameter         =false               ; // выводить параметры
extern bool   gpInfoLevel             =true                ; // выводить параметры
extern bool   _gDeleteObjectGrafic    =0                   ; // 1-Удалять объекты на графике при завершении 0-не удалять
//                                                            
extern double FlatSBuy                =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell               =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int    DayHistory              =50                  ; // Сколько дней в истории показывать

//                                                         
// флет азии                                               
//                                                         
extern int    iTimeEndFlatAsiaHour    = 5                  ; // Конец утреннего флета
extern int    iTimeEndFlatAsiaMin     = 15                 ; // Конец утреннего флета
// 
// Время длины флета измеряется минутами от окончания  и назад
//   360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
//
extern int    iTimeEndFlatAsiaSizeMin = 360                ; // + количество минут  флета
//                                                            
//                                                              
//                                                            
extern string sTimeBreakFlatAsia      ="20:00:00"          ; // Время до которого разумно ждать пробой и выставление ордеров
//                                                         
extern int    pУровниHighLowDAY       =1                   ; // выводить уровни HIGH LOW
//
extern color  ЦветПятницыHIGH         =DeepSkyBlue         ;
extern color  ЦветПятницыLOW          =DeepSkyBlue         ;
extern color  ЦветHIGHDAY             =DarkViolet          ;
extern color  ЦветLOWDAY              =DarkViolet          ;
extern color  lColorFAH               =OrangeRed           ;
extern color  lColorFAL               =SandyBrown          ;
extern color  lColorSignalSELL        =Red                 ;
extern color  lColorSignalBUY         =Red                 ;
//
//
 
                                                    
 
Mathemat >> :

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

Print("Наконец-то дошли!");

Basicamente, é o código normal que realiza os mesmos cálculos que o aninhado se construção. Mas em algum lugar eu ouvi dizer que o retorno na função deveria ser um. Provavelmente, isso é feito para não se misturar neles. Eu não sigo estritamente esta regra.

Quanto ao resto, minha abordagem é muito próxima à sua, exceto por alguns detalhes.

Eu prefiro a mesma maneira de sair sozinho!

mais fácil de controlar


Se você quiser devolver um valor, então


em vez de

se ( a > c )

retornar ( 3 );

se ( l < b )

retornar (5);

...

...

se ( h != b )

retorno (100);

---

prefira


se ( a > c )

codret = 3;

se ( l < b )

codret = 5;

...

...

se ( h != b )

codret = 100;


// especialmente se algumas operações adicionais comuns para todas as saídas forem realizadas antes do retorno

... por exemplo, aqui nós fazemos algo mais

retrun( codret);

}


 

um pouco de comentário...

Para dividir os textos em blocos, uso uma linha de caracteres com o código U0151. Para aqueles que não sabem, é datilografado assim:

  1. segurar Alt
  2. no teclado numérico pressione em seqüência os dígitos do código do símbolo 0, depois 1, depois 5, depois 1
  3. liberação Alt

para fontes "corretas" obtemos um sinal de menos mas sem "espaços" nas extremidades. depois copie-o quantas vezes forem necessárias uma linha sólida que serve como uma boa borda visual...

// обычная линия
// -----------------------------------------------------------------------------------

// сплошная линия
// —————————————————————————————————

// —————————————————————————————————
// Вот такие часто делаю ЗАГОЛОВКИ
// —————————————————————————————————

 

também uma linha inteligente para o bloco de texto de comentário - parece perfeitamente simétrica, mas há uma primeira abertura e uma segunda linha de fechamento:


/*///—————————————————————————————————————————
это

bloco de comentários de várias linhas


/*///...................

 

Yura, seu exemplo com um retorno, é claro, é lógico. Mas preste atenção que, neste caso, todos os ifs são sempre executados, ao contrário do caso com muitos retornos, quando a saída da função é obtida imediatamente após atingir a corda com a condição.

ForexTools, obrigado, eu aceitei suas idéias de projeto.