Code Structure: Organization and Conventions
A well-organized code structure is the foundation of a maintainable project. Claude can help you define conventions, organize folders, and maintain separation of concerns consistently throughout development.
In this article, we'll explore best practices for organizing Spring Boot and Angular projects, focusing on naming conventions, configuration management, and code organization patterns.
What You'll Learn
- Folder organization for scalable projects
- Naming conventions for files, classes, and variables
- Effective separation of concerns
- Multi-environment configuration management
- Patterns for shared code
Organization Principles
5 Principles of Code Structure
| Principle | Description | Benefit |
|---|---|---|
| Colocation | Related files together | Quick navigation, less context switching |
| Predictability | Consistent structure | Fast onboarding, fewer errors |
| Modularity | Isolated features | Reusability, independent testing |
| Scalability | Grows without refactor | Long-term maintenance |
| Explicitness | Descriptive names | Self-documenting code |
Backend Structure: Spring Boot
Package by Feature vs Package by Layer
Package by Layer
com.company.app/
├── controller/
│ ├── OrderController
│ └── ProductController
├── service/
│ ├── OrderService
│ └── ProductService
└── repository/
└── OrderRepository
Pro: Simple, familiar
Con: High coupling, hard to navigate
Package by Feature
com.company.app/
├── order/
│ ├── OrderController
│ ├── OrderService
│ └── OrderRepository
├── product/
│ └── ...
└── shared/
└── ...
Pro: High cohesion, easy to navigate
Con: Requires discipline
Java Naming Conventions
## CLASSES
# Controllers: {{ '{' }}Entity{{ '}' }}Controller
OrderController, ProductController
# Services: {{ '{' }}Entity{{ '}' }}Service
OrderService, PaymentProcessingService
# Repositories: {{ '{' }}Entity{{ '}' }}Repository
OrderRepository, CustomerRepository
# DTOs: {{ '{' }}Action{{ '}' }}{{ '{' }}Entity{{ '}' }}Request/Response
CreateOrderRequest, OrderResponse
# Exceptions: {{ '{' }}Cause{{ '}' }}Exception
OrderNotFoundException, PaymentFailedException
## METHODS
# Controller: implicit HTTP verb
@PostMapping → create(...)
@GetMapping("/{id}") → getById(...)
# Service: explicit verb
createOrder(), findOrderById(), updateOrderStatus()
## VARIABLES
# Collections: plural
List<Order> orders, Set<String> tags
# Booleans: is/has/can prefix
boolean isActive, boolean hasPayment
Frontend Structure: Angular
src/app/
├── core/ # Singleton, app-wide
│ ├── services/
│ │ ├── api.service.ts
│ │ └── auth.service.ts
│ ├── interceptors/
│ └── guards/
│
├── shared/ # Reusable
│ ├── components/
│ │ ├── button/
│ │ ├── modal/
│ │ └── table/
│ ├── pipes/
│ └── directives/
│
├── features/ # Feature modules
│ ├── orders/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── services/
│ │ └── orders.routes.ts
│ └── products/
│
└── layouts/
└── main-layout/
Angular Naming Conventions
## FILES
# Components: kebab-case.component.ts
order-list.component.ts
user-profile-card.component.ts
# Services: kebab-case.service.ts
order.service.ts
auth.service.ts
## CLASSES
# Components: PascalCase + Component suffix
export class OrderListComponent
# Services: PascalCase + Service suffix
export class OrderService
## SELECTORS
# Prefix app- + kebab-case
selector: 'app-order-list'
## VARIABLES
# Signals
ordersSignal = signal<Order[]>([]);
# Observables: $ suffix
orders$ = this.http.get<Order[]>(...)
Configuration Management
Spring Boot: Multi-Environment
spring:
application:
name: order-service
datasource:
url: ${DATABASE_URL}
app:
cors:
allowed-origins: ${CORS_ORIGINS:http://localhost:4200}
Angular: Environment Files
export const environment = {{ '{' }}
production: false,
apiUrl: 'http://localhost:8080/api/v1',
features: {{ '{' }}
enableAnalytics: false,
enableDarkMode: true,
{{ '}' }}
{{ '}' }};
Conclusion and Next Steps
In this article, we've defined the foundations for a maintainable and scalable code structure. In the next article, we'll explore advanced Prompt Engineering techniques to get the most out of Claude in complex scenarios.
Key Takeaways
- Package by feature: Keep related code together
- Consistent naming: Clear conventions for the whole team
- Core/Shared/Features: Clear separation of responsibilities
- Config per environment: Nothing hardcoded, everything configurable
- Document the structure: README with folder tree







