Skip to content

Code Organization

This guide covers best practices for organizing code structure, file layout, and project architecture across different programming languages.

🎯 Core Organization Principles

Single Responsibility Principle

Each file, class, and module should have one clear responsibility.

Good Example

# user_service.py - Only handles user business logic
class UserService:
    def create_user(self, user_data):
        # User creation logic only
        pass

    def update_user(self, user_id, user_data):
        # User update logic only
        pass

# user_repository.py - Only handles data access
class UserRepository:
    def save(self, user):
        # Database operations only
        pass

    def find_by_id(self, user_id):
        # Database queries only
        pass

Bad Example

# user_manager.py - Multiple responsibilities
class UserManager:
    def create_user(self, user_data):
        # User creation logic
        pass

    def save_to_database(self, user):
        # Database logic (wrong place)
        pass

    def send_email(self, user):
        # Email logic (wrong place)
        pass

    def validate_input(self, data):
        # Validation logic (wrong place)
        pass

Dependency Direction

Dependencies should point inward, from high-level to low-level modules.

Application Layer (High Level)
    ↓ depends on
Business Logic Layer
    ↓ depends on
Data Access Layer (Low Level)

📁 Directory Structure Best Practices

Standard Project Layout

project_name/
├── src/                    # Source code
│   ├── main/              # Production code
│   │   ├── java/         # Java source files
│   │   ├── python/       # Python source files
│   │   └── resources/     # Configuration files
│   └── test/              # Test code
│       ├── java/         # Test source files
│       └── python/        # Test source files
├── docs/                  # Documentation
├── config/                # Configuration files
├── scripts/               # Build and deployment scripts
├── tests/                 # Integration tests
├── build/                 # Build output
└── README.md              # Project documentation

Language-Specific Structures

Java Maven Structure

my-java-project/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── mycompany/
│   │   │           ├── controller/
│   │   │           ├── service/
│   │   │           ├── repository/
│   │   │           └── model/
│   │   └── resources/
│   │       ├── application.properties
│   │       └── logback.xml
│   └── test/
│       └── java/
│           └── com/
│               └── mycompany/
│                   ├── controller/
│                   ├── service/
│                   └── repository/
├── pom.xml
└── README.md

Python Package Structure

my-python-project/
├── my_package/
│   ├── __init__.py
│   ├── models/
│   │   ├── __init__.py
│   │   ├── user.py
│   │   └── product.py
│   ├── services/
│   │   ├── __init__.py
│   │   ├── user_service.py
│   │   └── product_service.py
│   ├── repositories/
│   │   ├── __init__.py
│   │   ├── user_repository.py
│   │   └── product_repository.py
│   └── utils/
│       ├── __init__.py
│       ├── validators.py
│       └── helpers.py
├── tests/
│   ├── test_models/
│   ├── test_services/
│   └── test_repositories/
├── requirements.txt
├── setup.py
└── README.md

C Project Structure

my-c-project/
├── src/
│   ├── main.c
│   ├── user/
│   │   ├── user.h
│   │   └── user.c
│   ├── product/
│   │   ├── product.h
│   │   └── product.c
│   └── utils/
│       ├── utils.h
│       └── utils.c
├── include/
│   ├── common.h
│   └── config.h
├── tests/
│   ├── test_user.c
│   └── test_product.c
├── build/
├── Makefile
└── README.md

🏗️ Architectural Patterns

Layered Architecture

┌─────────────────────────────────────┐
│           Presentation Layer          │  (Controllers, UI)
├─────────────────────────────────────┤
│            Business Layer            │  (Services, Logic)
├─────────────────────────────────────┤
│           Data Access Layer          │  (Repositories, DAOs)
├─────────────────────────────────────┤
│            Database Layer            │  (Database, Files)
└─────────────────────────────────────┘

Java Implementation

// Controller Layer
@RestController
@RequestMapping("/api/users")
public class UserController {
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

// Service Layer
@Service
public class UserService {
    private UserRepository userRepository;

    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
    }
}

// Repository Layer
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findById(Long id);
}

Modular Architecture

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│   User      │  │  Product    │  │  Order      │
│   Module    │  │  Module     │  │  Module     │
└─────────────┘  └─────────────┘  └─────────────┘
       │                │                │
       └────────────────┼────────────────┘
              ┌─────────────┐
              │   Common    │
              │   Module    │
              └─────────────┘

Python Implementation

# user/module.py
from ..common.database import DatabaseConnection
from ..common.validators import validate_email

class UserModule:
    def __init__(self):
        self.db = DatabaseConnection()

    def create_user(self, user_data):
        if validate_email(user_data['email']):
            return self.db.insert('users', user_data)
        raise ValueError("Invalid email")

# product/module.py
from ..common.database import DatabaseConnection

class ProductModule:
    def __init__(self):
        self.db = DatabaseConnection()

    def create_product(self, product_data):
        return self.db.insert('products', product_data)

# common/database.py
class DatabaseConnection:
    def __init__(self):
        self.connection = self._create_connection()

    def insert(self, table, data):
        # Database insertion logic
        pass

📋 File Organization Rules

Naming Conventions

## File Naming Standards

### General Rules
- Use descriptive, meaningful names
- Be consistent across the project
- Use language-specific conventions
- Avoid abbreviations unless widely understood

### Language-Specific Conventions
- **Java**: PascalCase for classes (UserService.java)
- **Python**: snake_case for modules (user_service.py)
- **C**: snake_case for files (user_service.c)
- **Oracle**: snake_case for packages (user_management.pks)

File Size Guidelines

## File Size Recommendations

### Maximum File Sizes
- **Classes**: 300-500 lines maximum
- **Functions**: 50-100 lines maximum
- **Modules**: 1000 lines maximum
- **Configuration files**: As needed

### When to Split Files
- Single file exceeds 500 lines
- Multiple distinct responsibilities
- Different abstraction levels
- Different feature areas

🔧 Code Organization Techniques

Package/Module Organization

// Good: Organized by feature
com.company.app
├── user/
   ├── UserController.java
   ├── UserService.java
   ├── UserRepository.java
   └── User.java
├── product/
   ├── ProductController.java
   ├── ProductService.java
   ├── ProductRepository.java
   └── Product.java
└── common/
    ├── BaseController.java
    ├── BaseService.java
    └── BaseEntity.java

// Bad: Organized by type
com.company.app
├── controller/
   ├── UserController.java
   ├── ProductController.java
   └── OrderController.java
├── service/
   ├── UserService.java
   ├── ProductService.java
   └── OrderService.java
└── repository/
    ├── UserRepository.java
    ├── ProductRepository.java
    └── OrderRepository.java

Dependency Injection

# Good: Dependency injection
class UserService:
    def __init__(self, user_repository: UserRepository, email_service: EmailService):
        self.user_repository = user_repository
        self.email_service = email_service

    def create_user(self, user_data):
        user = self.user_repository.save(user_data)
        self.email_service.send_welcome_email(user.email)
        return user

# Bad: Hard dependencies
class UserService:
    def __init__(self):
        self.user_repository = UserRepository()  # Hard dependency
        self.email_service = EmailService()     # Hard dependency

    def create_user(self, user_data):
        user = self.user_repository.save(user_data)
        self.email_service.send_welcome_email(user.email)
        return user

Configuration Management

# config/application.yml
app:
  name: "My Application"
  version: "1.0.0"

database:
  url: "jdbc:postgresql://localhost:5432/mydb"
  username: "user"
  password: "password"

logging:
  level: "INFO"
  file: "logs/application.log"
// Configuration class
@Configuration
@ConfigurationProperties(prefix = "app")
public class AppConfig {
    private String name;
    private String version;

    // getters and setters
}

@Service
public class ApplicationService {
    private final AppConfig config;

    public ApplicationService(AppConfig config) {
        this.config = config;
    }

    public String getAppInfo() {
        return config.getName() + " v" + config.getVersion();
    }
}

📚 Documentation Organization

Code Documentation

/**
 * Service for managing user operations.
 * 
 * <p>This service provides methods for creating, updating, and retrieving users.
 * It handles business logic and coordinates with the repository layer.</p>
 *
 * @author John Doe
 * @version 1.0
 * @since 1.0
 */
@Service
public class UserService {

    /**
     * Creates a new user.
     *
     * @param userDto the user data transfer object
     * @return the created user
     * @throws IllegalArgumentException if user data is invalid
     * @throws EmailAlreadyExistsException if email already exists
     */
    public User createUser(UserDto userDto) {
        // Implementation
    }
}

README Structure

# Project Name

## Description
Brief description of the project purpose and functionality.

## Quick Start
Instructions for getting the project running quickly.

## Project Structure
Overview of the project organization and key directories.

## Configuration
How to configure the project for different environments.

## API Documentation
Link to API documentation or key endpoints.

## Contributing
Guidelines for contributing to the project.

## License
Project license information.

🔄 Refactoring Organization

Signs of Poor Organization

  • Large files with multiple responsibilities
  • Deep nesting and complex hierarchies
  • Circular dependencies
  • Duplicated code across modules
  • Difficult to locate specific functionality

Refactoring Steps

  1. Identify Problems: Use code analysis tools and reviews
  2. Plan Changes: Create refactoring plan with minimal risk
  3. Extract Modules: Break large files into smaller modules
  4. Reorganize Dependencies: Fix dependency direction issues
  5. Update Tests: Ensure all tests pass after refactoring
  6. Document Changes: Update documentation and README files

🔗 Language-Specific Organization