Como devo organizar minha árvore de fontes?

83

Sou um desenvolvedor individual trabalhando, em grande parte, em projetos da web (W / LAMP) e, às vezes, em projetos C / C ++ (não-GUI) de escala média.

Eu sempre luto com a estruturação da minha árvore de código-fonte. Na verdade, normalmente, não concluo um projeto sem despejar a árvore inteira e reorganizar as peças três a quatro vezes, o que realmente exige muito esforço e, além disso, o resultado final parece ser um compromisso.

Às vezes, acabo com a classificação acima da fonte - uma árvore muito longa de pastas e subpastas. Em outras ocasiões, eu simplesmente acabo concentrando todos os arquivos em uma pasta específica com base no propósito maior que eles servem e, assim, levando a pastas "caóticas" na origem.

Eu gostaria de perguntar:

  • Existem princípios / lógicas / práticas recomendadas que podem ajudar-me a estruturar melhor minha árvore de fontes?
  • Existem técnicas gráficas / diagramáticas (por exemplo: DFD no caso de fluxo de dados) que podem me ajudar a visualizar minha árvore de origem com base na análise do projeto?
  • Qual estratégia adotar para estruturar a árvore de arquivos multimídia associada ao projeto?

Sobre a recompensa : Aprecio as respostas existentes com os membros compartilhando suas próprias práticas, no entanto, gostaria de incentivar respostas mais gerais e instrutivas (ou recursos) e mais respostas dos membros.

    
por check123 06.06.2011 / 15:33
fonte

11 respostas

22

O layout da árvore de origem deve refletir a arquitetura; Como um corolário, uma arquitetura bem estruturada pode levar a um layout de árvore de origem bem estruturado. Sugiro ler o padrão POSA1 Layers , tentando encaixar sua arquitetura em uma estrutura em camadas e, em seguida, nomear cada uma das camadas resultantes e usando isso como base para sua hierarquia de origem. Tomando uma arquitetura de três camadas comum como uma linha de base:

  • apresentação / webService (apresenta uma interface de serviço da web para nossa lógica de negócios)
  • logic / * (módulos de lógica de negócios entram aqui)
  • storage / sql (APIs de armazenamento de backend aqui - isso usa uma interface SQL para armazenar em um banco de dados)
  • util / * (código utilitário - utilizável por todas as outras camadas, mas que não se refere fora do util, vai aqui)

Observe que as camadas não contêm código diretamente, mas são estritamente usadas para organizar módulos.

Dentro de um módulo, uso o seguinte tipo de layout:

  • <module> (caminho para o módulo diretamente; define a interface modular)
  • <module>/impl/<implName> (uma implementação específica da interface modular)
  • <module>/doc (Documentação para usar o módulo)
  • <module>/tb (código de teste de unidade para o módulo)

onde o <module> está localizado no repositório de acordo com a camada à qual ele pertence.

    
por 08.06.2011 / 22:14
fonte
41

Eu não posso te dar muitos conselhos relacionados a webprojetos, mas aqui está como eu estruturo minha árvore em um projeto de programação (principalmente de uma perspectiva C / C ++):

  • /
    • src - Arquivos de origem escritos por mim
    • ext - Contém bibliotecas de terceiros
      • libname-1.2.8
        • incluir - Cabeçalhos
        • lib - Arquivos de lib compilados
        • Donwload.txt - Contém o link para baixar a versão usada
    • ide - eu armazeno arquivos de projeto aqui
      • vc10 - eu organizo arquivos de projeto dependendo do IDE
    • bin - Exe compilado vai aqui
    • build - Os arquivos de compilação do compilador
    • doc - Documentação de qualquer tipo
    • README
    • INSTALAR
    • COPIANDO

Algumas notas:

  1. Se eu estiver escrevendo uma biblioteca (e estou usando C / C ++), organizarei meus arquivos de origem primeiro em duas pastas chamadas "include" e "src" e, em seguida, por módulo. Se for um aplicativo, vou organizá-los apenas por módulo (cabeçalhos e fontes irão para a mesma pasta).

  2. Arquivos e diretórios listados acima em itálico não serão adicionados ao repositório de código.

por 06.06.2011 / 17:43
fonte
13

Embora o Layout do Diretório padrão do Maven seja específico para Java, mas pode servir como uma boa base para outros tipos de projetos também.

Aqui está a estrutura básica (você pode substituir os diretórios 'java' por 'php', 'cpp', etc):

src/main/java       Application/Library sources 
src/main/resources  Application/Library resources  
src/main/filters    Resource filter files 
src/main/assembly   Assembly descriptors 
src/main/config     Configuration files 
src/main/webapp     Web application sources 
src/test/java       Test sources 
src/test/resources  Test resources 
src/test/filters    Test resource filter files 
src/site            Site 
LICENSE.txt         Project's license 
NOTICE.txt          Notices and attributions required by libraries
README.txt          Project's readme

A estrutura básica é dividida em 'src / main' e 'src / test' e depois agrupada por tipo.

    
por 08.06.2011 / 16:25
fonte
5

Eu realmente não sei sobre convenções, mas todos os meus projetos principais são feitos usando o Symfony Framework e eu me acostumei com uma estrutura de árvore como segue:

raiz /

  • apps
  • app_name
    • config (arquivos de configuração específicos do aplicativo)
    • lib (arquivos php específicos do aplicativo)
    • módulos (distribuição modular de funcionalidade)
      • module_name
        • modelos (html)
        • ações (código php)
  • confing (arquivos de configuração do projeto)
  • lib (código php que pode ser usado no projeto do furo)
  • model (classes que representam as informações do projeto)
    • base
  • form (arquivos php que manipulam formulários, isso pode ser bem difícil de ser feito sem o symfony)
    • base (classes de formulário básico)
  • web
  • css
    • imagens
    • file.css
  • js
  • log (arquivos de log que podem ser gerados)
  • dados (informações específicas de dados, como patches do SQL ou o que for)
  • sql
  • plugins (bibliotecas usadas que podem ser mescladas com qualquer aplicativo do projeto)

Se você estiver interessado, por favor leia a documentação do symfony sobre o assunto para mais informações ( MVC e Organização de Código no Symfony ).

    
por 06.06.2011 / 16:54
fonte
5

O ideal é que a organização tenha um único repositório, cuja estrutura é destinada a aumentar o engajamento entre engenharia & negócios e promover a reutilização.

...\products\
...\products\productName\
...\products\productName\doc\

...\systems\
...\systems\systemName\
...\systems\systemName\doc\
...\systems\systemName\res\
...\systems\systemName\build\
...\systems\systemName\test\

...\library\
...\library\libraryName\
...\library\libraryName\doc\
...\library\libraryName\build\
...\library\libraryName\test\

...\devops\

produtos

Uma pasta por produto; ajuda a comunicar como o software suporta o negócio.

Idealmente, cada "produto" é pouco mais que um arquivo de configuração indicando quais sistemas serão invocados e como eles devem ser configurados.    A subpasta doc pode conter o resumo \ spec & qualquer material promocional etc ...

Ao separar produtos e sistemas, comunicamos o potencial de reutilização para o lado voltado para o cliente da empresa e dividimos os silos por produto.    (Isso contrasta com a abordagem da "linha de produtos" para o mesmo problema)

systems

Uma pasta por sistema; ajuda a comunicar os recursos primários & oportunidade / valor do conteúdo do repositório.

  1. Arquivos "Gerenciamento de configuração", especificando compilar & ambientes de implementação.
  2. Configuração do teste no nível do sistema (pode ser uma quantidade significativa).
  3. Lógica de nível superior & funcionalidade; a maior parte do levantamento pesado é feito pelas funções da biblioteca.

biblioteca

Componentes reutilizáveis invocados por vários sistemas.    A maioria das atividades de desenvolvimento é organizada em torno da produção de bibliotecas, em vez de sistemas, portanto, a reutilização é "incorporada" ao processo de desenvolvimento.

devops

Build, Integração Contínua & outra funcionalidade de automação de desenvolvimento.

Conclusão

A árvore de fontes é uma peça chave da documentação e molda a abordagem, estrutura e psicologia do relacionamento do negócio com sua tecnologia proprietária.

Os drivers para essa abordagem são explicados com mais profundidade na minha resposta a essa pergunta: link

    
por 04.12.2011 / 09:10
fonte
3

O que estou tentando fazer para cada projeto é semelhante:

  • src - arquivos fonte, uma pasta para cada namespace / pacote para recuperar facilmente arquivos (até mesmo arquivos de cabeçalho para C / C ++)
  • ext - para bibliotecas externas / de terceiros, é simples adicionar elementos externos (como repositórios SVN). Dentro, uma pasta para cada biblioteca (binários e arquivos de inclusão)
  • bin - para binários criados, pode ser rapidamente exportado para liberação
    • inc - para o arquivo de cabeçalhos C / C ++ (copiado pelo IDE / makefile / etc ...)
  • out - para todos os arquivos gerados temporariamente (.class, .obj etc ...) e pode ser ignorado (por exemplo, pelo SVN)
  • doc - para qualquer documentação, geralmente gerada com o Doxygen
  • res - colocando recursos aqui, é possível separar arquivos de origem de texto e recursos binários usados pelo programa. Eu realmente não tenho hierarquia específica por dentro.
    • config - para alguns arquivos de configuração
    • drawable - para algumas fotos ou ícones

Todos os arquivos ou makefiles do IDE são salvos diretamente na raiz, se você usar apenas um deles.

    
por 10.08.2011 / 14:59
fonte
2

Eu faço algo assim. Funciona bem para um jogo de plataforma cruzada que estou fazendo no meu tempo livre. Infelizmente no trabalho, as coisas são muito menos organizadas ...

Output                      <-- Build outputs
Docs
External
   <libname>
      Include
      Lib
Data
<ProjectName>.xcodeproj
<ProjectName>VS2010
Source
Temp                        <-- Intermediate stuff from builds and other tools
Tools
    
por 09.06.2011 / 14:23
fonte
2

Para as minhas equipes, tentamos impor uma estrutura padrão em todos os projetos para facilitar a localização de coisas conforme a equipe muda de contexto e para evitar a necessidade de reaprender toda vez. Nem todos os projetos precisam de todos os sistemas, por isso começamos com o conjunto mínimo.

/Source/Component/Language

/Source/Component/3rd Party/

/Documentation/Requirements

/Documentation/Design

/Tests/Automated/Unit

/Tests/Automated/ToolName

/Tests/Manual

Isso resulta em alguma duplicação, especialmente sob o código e bibliotecas de terceiros, mas pelo menos nunca esquecemos a resposta para algo como "O que usa o RogueWave Editor?"

    
por 13.06.2011 / 16:50
fonte
2

Eu gosto das ideias apresentadas nesta página www.javapractices.com/topic/TopicAction.do?Id = 205 . Basicamente, a recomendação é organizar seu projeto em recursos (ou módulos, componentes). Além das razões apresentadas:

  1. Menor carga cognitiva quando você pensa no escopo do código em que está trabalhando, pois tem a garantia de que qualquer código no recurso no qual você está trabalhando é "recurso privado".
  2. Existe uma sensação adicional de segurança quando você tem a garantia de que está apenas modificando o código para determinado recurso. Por exemplo, você não quebrará nada além do recurso em que está trabalhando. Novamente, isso é por causa do "recurso privado".
  3. Carga cognitiva menor, porque há menos arquivos que você pode ver para um determinado pacote. Tenho certeza de que todos já viram um pacote que contém mais de 15 arquivos.

Observe que isso é focado em pacotes Java (também conhecidos por namespaces). Para grandes projetos, recomendo, pelas mesmas razões, dividir o projeto em vários projetos (como em vários projetos maven) que representa um recurso de negócios. Para projetos maven, eu recomendo este reading .

Até agora, os projetos em que eu estava envolvido não seguem estes. Existem muitas razões, mas aqui estão algumas:

  1. O mal-entendido do modificador de acesso padrão do Java (modificador de acesso mais incompreendido de acordo com este livro )
  2. "Argumentum ad populum": cultura predominante de pacote por camada (provavelmente causada pelo motivo # 1)

Acho que há uma oportunidade perdida de evitar a complexidade se a organização da fonte do projeto não for levada a sério no início do projeto, como disse o arquiteto Alexander:

"As any designer will tell you, it is the first steps in a design process which count for most. The first few strokes, which create the form, carry within them the destiny of the rest." - Christopher Alexander

Dependendo do tamanho & complexidade de um projeto, a oportunidade perdida de cortar custos ou ROI pode ser muito grande. (estou interessado em ver um estudo para ver os números exatos para isso)

    
por 05.06.2013 / 07:00
fonte
2

Minha recomendação é fazer o download de vários frameworks ou mecanismos e ver como grandes equipes de desenvolvimento lidaram com o layout das pastas.

Existem tantas maneiras de organizar os arquivos que é melhor escolher um deles e tentar mantê-lo em qualquer projeto. Atenha-se a uma convenção específica até a conclusão ou renovação para evitar erros e perder tempo desnecessário.

Você pode fazer o download das estruturas do Laravel, Symphony ou Codeigniter para projetos da web para ter um layout de pasta instantânea que funcione.

Então, tentarei transmitir um layout de pastas comum a qualquer desenvolvimento:

O MVC (Model View Controller) oferece um bom paradigma de organização.

O código fonte da raiz pode ser src (C ++) ou app (desenvolvimento da web)

Uma estrutura de arquivos que não tenha um objetivo claro para as classes que ela agrupa definitivamente causará confusão. Não é apenas para organizar o código, mas sim para auto-carregadores, fábrica de classes, armazenamento local, armazenamento remoto e namespacing.

Esta estrutura de pastas é derivada e simplificada do Laravel Framework . Minha preferência neste post é a nomeação plural, mas eu uso palavras singulares em meus projetos.

src / storage (implementações de models / file-storage / api / mysql / sql-lite / memcached / redis)

src / repositories (Um wrapper de 'implementações de armazenamento' com alguma lógica de armazenamento, uma interface comum e uma convenção de resultados de retorno.)

src / services | lógica | entidades (lógica do aplicativo bussiness)

src / controllers (usado no desenvolvimento da web para rotear solicitações do servidor para seus serviços)

src / modules | sistemas (Sistemas modulares que estendem sua funcionalidade geral de framework. Os serviços podem usar módulos, mas não vice-versa)

src / helpers (Classes Helper ou wrapper, como, por exemplo, manipulação de strings. Muitas vezes isso pode estar no fornecedor de libs quando terceiros)

src / types (enumerados enums)

público | construir | saída (web ou c ++)

config (arquivos de configuração. O YAML está se tornando popular para arquivos de configuração de plataforma cruzada)

cache

registros

lang (en / es / ru /...)

bootstrap (inicia a estrutura e o aplicativo)

docs (documentação escrita no formato de marcação .md)

testes (teste de unidade)

banco de dados / migrações (Criar estrutura de banco de dados a partir do zero)

database / seeds (preenche seu banco de dados com dados fictícios para testar)

libs | fornecedor (todos os softwares de terceiros. 'libs' em C ++ e 'vendor' geralmente em php)

ativos | recursos (images / sons / scripts / json / qualquer mídia)

    
por 05.05.2017 / 03:08
fonte
1

Com linguagens orientadas a objeto, você pode construir namespaces. Esse desdobramento lógico usado para separar partes do aplicativo para evitar o acoplamento é a principal fonte de quebra da localização do arquivo lógico. Usar o acoplamento como um motivo para desmembrar namespaces é um bom lugar para iniciar o link .

Outros falaram sobre a configuração do projeto em relação à construção, mas uma vez que você entra na própria fonte, é sobre o que faz sentido - apenas use como você separa logicamente o código de qualquer maneira.

    
por 10.06.2011 / 01:53
fonte