Pasta por tipo ou Pasta por recurso


59

Uso um guia de estilo do AngularJS. Dentro deste guia, existe um estilo chamado folder-by-feature, em vez de folder-by-type, e estou realmente curioso sobre qual é a melhor abordagem (neste exemplo para Java)

Digamos que eu tenha um aplicativo onde possa recuperar Usuários e Animais de Estimação, usando serviços, controladores, repositórios e objetos de domínio ofcourse.

Tomando a pasta por estilos, temos duas opções para nossa estrutura de embalagem:

1. Pasta por tipo

com.example
├── domain
│    ├── User.java
│    └── Pet.java
├── controllers
│    ├── UserController.java
│    └── PetController.java
├── repositories
│    ├── UserRepository.java
│    └── PetRepository.java
├── services
│    ├── UserService.java
│    └── PetService.java
│   // and everything else in the project
└── MyApplication.java

2. Pasta por recurso

com.example
├── pet
│    ├── Pet.java
│    ├── PetController.java
│    ├── PetRepository.java
│    └── PetService.java
├── user
│    ├── User.java
│    ├── UserController.java
│    ├── UserRepository.java
│    └── UserService.java
│   // and everything else in the project
└── MyApplication.java

Qual seria uma boa abordagem e quais são os argumentos para fazê-lo?



1
Eu não sei @Laiv. O idioma / estrutura realmente afeta a resposta? Independentemente disso, a outra questão é certamente relevante.
precisa

1
Então eu tenho que editar minha resposta. E yest, é um possível duplicado
LAIV

2
Eu nunca entendi o benefício de pasta por tipo. Se eu estiver trabalhando em um ticket pertencente ao recurso Pet, provavelmente me beneficiaria da localidade Pet, do controlador, do repositório e do serviço. Em que situação eu precisaria de todos os controladores, mas não das visualizações, repositórios ou serviços?
22416 Alexander

2
Parece que ninguém mencionou que pacotes em Java não são apenas pastas; eles também afetam o acesso para as classes contidas. Por esse motivo, pacote por camada / tipo pode realmente fornecer algum valor semântico em Java.
Angus Goldsmith

Respostas:


69

Pasta por tipo funciona apenas em projetos de pequena escala. Pasta por recurso é superior na maioria dos casos.

Pasta por tipo está ok quando você tem apenas um pequeno número de arquivos (menos de 10 por tipo, digamos). Assim que você obtém vários componentes em seu projeto, todos com vários arquivos do mesmo tipo, fica muito difícil encontrar o arquivo real que você está procurando.

Portanto, pasta por recurso é melhor devido à sua escalabilidade. No entanto, se você pasta por recurso, acaba perdendo informações sobre o tipo de componente que um arquivo representa (porque não está mais em uma controllerpasta, digamos), então isso também se torna confuso. Existem 2 soluções simples para isso.

Primeiro, você pode respeitar as convenções de nomenclatura comuns que implicam em digitação no nome do arquivo. Por exemplo, o popular guia de estilo AngularJS de John Papa tem o seguinte:

Diretrizes de nomeação

  • Use nomes consistentes para todos os componentes, seguindo um padrão que descreva o recurso do componente e depois (opcionalmente) seu tipo. Meu
    padrão recomendado é feature.type.js. Existem 2 nomes para a maioria dos
    ativos:

    • o nome do arquivo (avengers.controller.js)
    • o nome do componente registrado com Angular (AvengersController)

Segundo, você pode combinar estilos de pasta por tipo e pasta por recurso em pasta por recurso por tipo:

com.example
├── pet
|   ├── Controllers
│   |   ├── PetController1.java
|   |   └── PetController2.java
|   └── Services
│       ├── PetService1.java
│       └── PetService2.java
├── user
|   ├── Controllers
│   |   ├── UserController1.java
│   |   └── UserController2.java
|   └── Services
│       ├── UserService1.java
│       └── UserService2.java

1
O guia de estilo johnpapa era exatamente o que eu estava fakking sobre :-)
Jelle

1
Algumas vezes (mais frequentemente do que pensamos), adicionamos complexidade demais às coisas que deveriam ser fáceis. Nomear e empacotar são algumas dessas coisas. O melhor conselho é mantê-lo simples. A mistura de ambos tem as vantagens e as desvantagens de ambas as abordagens.
LAIV

1
@Laiv No exemplo que dei, concordo com seu exagero, mas na maioria dos meus casos de negócios reais, em que cada pasta de tipo pode facilmente ter 10 a 20 arquivos, acho muito útil, porque a pasta de recursos geral teria da ordem de 50 arquivos caso contrário.
Reintegrar Monica

6
fakking, obrigado iPhone correção automática! Eu quis dizer 'conversando'.
Jelle

2
@Chaotic Este exemplo é muito trivial para começar a falar sobre detalhes, mas nesses casos em que você tem peças que são usadas em vários componentes, provavelmente esse deve ser um componente próprio do qual outros componentes dependem.
Reintegrar Monica

26

Isso realmente não tem nada a ver com a tecnologia em questão, a menos que você use uma estrutura que force a pasta por tipo como parte de uma abordagem de convenção sobre configuração.

Pessoalmente, sou fortemente da opinião de que a pasta por recurso é muito superior e deve ser usada em todos os lugares o máximo possível. Ele agrupa classes que realmente funcionam juntas, enquanto pasta por tipo apenas duplica algo que geralmente já está presente no nome da classe.


10
Eu acrescentaria que, na pasta por recurso, é mais fácil brincar com escopos de classes e métodos (protegido, pacote, ...).
LAIV

Para projetos menores, você pode ter apenas um recurso. É muito mais fácil organizar por tipo nesse cenário.
Aaaaaa

Como exemplo, Grails faz forçar pasta-a-tipo para os seus domínios, controladores, serviços, etc.
tylerwal

17

O trabalho com pacotes por recurso destaca - se pela alta modularidade e coesão . Isso nos permite brincar com o escopo dos componentes. Por exemplo, podemos usar os modificadores de acesso para aplicar LoD e a inversão de dependência para integrações ou extensões.

Outras razões são:

  • Navegação de código mais fácil
  • Um nível mais alto de abstração
  • Minimizar escopos (contextos delimitadores)
  • Modularização vertical

Pasta por camada coloca muita ênfase nos detalhes da implementação (como o @David mencionou), o que não diz muito sobre o aplicativo em que estamos trabalhando. Diferentemente do pacote por recurso , o pacote por camada incentiva a modularização horizontal. Esse tipo de modularização torna o trabalho com componentes transversais difícil e entediante.

Finalmente, há uma terceira opção. " Pacote por componente " que, nas palavras do tio Bob, parece melhor alinhado com seus princípios de pacote . Se a opinião de Bob do tio é importante ou não, deixo que você decida. Acho interessante, já que esta convenção está alinhada com a arquitetura limpa, da qual gosto.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.