Google Analytics

quinta-feira, 26 de abril de 2012

Esqueletos

Eu gosto de usar esqueletos, ou seja, aqueles arquivos de modelo. Eles me ajudam a lembrar de coisas que normalmente precisamos e também deixam o código com uma cara homogênea.

Mas eu não gosto de esqueletos mortos, daqueles que estão estáticos e não podem ser mudados, ou que são iguais para todos os projetos. Gosto de esqueletos vivos, que evoluem, sendo customizados para cada projeto conforme vão sendo usados e gosto também que eles estejam versionados no sistema de versionamento DO PROJETO EM QUESTÃO.

Costumo usar os seguintes esqueletos:

header:
//*****************************************************************************
// Version/Revision log :
// ====================
//$Log: $
//
//*****************************************************************************

#ifndef TODO_NAME_H_INCLUDED
#define TODO_NAME_H_INCLUDED

//################################# Includes ##################################


//################################## Types ####################################


//################################ Constants ##################################


//############################## Public Variables #############################


//############################# ForwardDeclarations ###########################


//################################# Classes ###################################


//####################### Public Function Declarations ########################


#endif // TODO_NAME_H_INCLUDED

//*************************    E n d   F i l e    *****************************



cpp:

//*****************************************************************************
// Version/Revision log :
// ====================
//$Log: $
//
//*****************************************************************************

//################################# Includes ##################################
#include "TODO_NAME.h"


//################################## Types ####################################


//######################### Private Classes Declaration  ######################


//################################ Constants ##################################


//############################# Private Variables #############################


//############################## Public Variables #############################


//############################# Private Functions #############################


//###################### Private Classes Implementation #######################


//###################### Public Classes Implementation ########################


//##################### Public Functions Implementation #######################


//-------------------------------------------------
// Unit tests
//-------------------------------------------------
#ifdef UNIT_TESTS
#include <iostream>
#include <assert.h>
using namespace std;

int main ()
{
    cout << "Unit Testing for TODO_NAME class" << endl;
    Logger::logTostdout();
       
    cout << "Testing TODO" << endl;
    {
        assert(!"No UNITTESTS implemented yet!");
    }

    cout << ">>>>>> Tests finished with no errors" << endl;
    return 0;
}

#endif

//*************************    E n d   F i l e    *****************************


declaração de classe:
//=============================================================================
// Class: TODO_NAME
// Remarks: TODO
//=============================================================================
class TODO_NAME
{
public:
    TODO_NAME() {}
    ~TODO_NAME() {}
private:
    TODO_NAME(const TODO_NAME& x);    // Hide copy ctor to avoid implicit calling
    TODO_NAME& operator=(const TODO_NAME& x);    // Hide = operator to avoid implicit calling
}; // End of class TODO_NAME



Implementação de clase:
//=============================================================================
// Class: TODO_NAME
//=============================================================================
//-----------------------------------------------------------------------------
// Method: TODO
// Remarks: TODO
//-----------------------------------------------------------------------------
void TODO_NAME::TODO(TODO)
{
    //TODO
}


Makefile:
#*****************************************************************************
# Version/Revision log :
# ====================
#$Log: $
#
#*****************************************************************************
all:
    <<TODO: Implement all target to build your items in the current dir

clean:
    <<TODO: Implement clean target that undoes what all does...

install:
    <<TODO: Implement install target that installs the itens created by all to the correct places.

uninstall:
    <<TODO: Implement clean target that undoes EVERYTHING that install does...


.PHONY: all clean install uninstall



Um comentário:

  1. Eu acho que templates como esta que tu descreveu explicando que o copy constructor e operador de cópia são intencionalmente private para que o compilador não os crie automaticamente, não são má idéia de se usar. Mas eu preferiria mil vezes colocar num wiki com todas as regras para todos projetos e depois uma entrada específica para cada projeto com suas peculiaridades do que manter o arquivo de código no repositório.

    Uma coisa que é extremamente importante é revisão de código usando um sistema (imagino Web) para isto. E que não precise mexer no próprio código para fazer a revisão porque daí entra no nível da tragédia (ou tragicomédia). Só vi isto funcionando em umas das empresas que trabalhei e funcionava extremamente bem. Esta forma é bem mais útil para manter a consistência do projeto (especialmente quando se considera mantenedores que já conhecem e gente nova que entra constantemente).

    Já falando dos esqueletos em geral especialmente para C (não to pensando em C++ mas o argumento deve se aplicar também), cada vez que abro um arquivo assim meus olhos começar a se revirar nas órbitas. Podiam escrever em cima "seu burrinho, aprenda agora onde se põe as coisas!". Infelizmente é a mensagem que me passa. Eu não lembro a última vez que li um código começando no começo do arquivo e fui descendo sequencialmente até o final. Eu sempre gero os ctags ou uso cscope e abro o arquivo que tem o main() (ou equivalente) e vou seguindo daí para as funções. E quando vou colocar coisas novas eu pelo menos tenho assim uma idéia de onde colocar, quer dizer, não vou colocar macros #define no final do arquivo! :P

    Já vi muitas vezes código em empresas que tinha mais deste comentários de esqueleto do que propriamente código útil. Acho isto profundamente feio esteticamente. Como considerações estéticas de código são boas para gerar discussões inúteis que não levam a lugar algum fiz questão de dar minha opinião aqui! :)

    No fim das contas acho que estas coisas nunca deveriam aparecer nos arquivos do código de um produto/projeto. Acho que se estiverem catalogadas em algum lugar que não nos próprios arquivos do código, como num wiki, muito melhor.

    ResponderExcluir