ALD Implementation Standards

Standards for code quality, testing, and refactoring when implementing ALD systems.

Code Quality Standards

Clean implementations

  • Readable: Code should be self-documenting; names reveal intent
  • Simple: Prefer straightforward solutions over clever ones
  • Focused: Each class/method has one clear purpose
  • Testable: Easy to test without complex setup

Dependency management

  • All dependencies injected via constructor
  • No hidden dependencies (statics, globals, service locators)
  • Interfaces over concrete classes
  • Dependencies flow inward (core has no knowledge of edges)

Error handling

  • Fail fast for programming errors (null checks, preconditions)
  • Return result objects for expected errors
  • Document what exceptions can be thrown
  • Don't swallow exceptions without logging

Framework isolation

  • Core domain has zero framework imports
  • No database annotations in domain entities
  • No HTTP request/response objects in business logic
  • Adapters translate between frameworks and domain

Testing Standards

Contract tests (must-have)

Tests that define and validate the interface contract.

  • Coverage: Happy paths, edge cases, error conditions
  • Naming: Test names read like specifications
  • Stability: Tests should survive refactoring of implementation
  • Documentation: Tests explain assumptions and invariants

Test structure (Arrange-Act-Assert)

  • Arrange: Set up test data and dependencies
  • Act: Execute the behavior being tested
  • Assert: Verify the outcome
  • Keep each section clear and focused

Test independence

  • Tests run in any order
  • No shared mutable state between tests
  • Each test creates its own fixtures
  • Tests clean up after themselves

What to test

  • Happy paths: Normal, expected behavior
  • Edge cases: Boundary conditions, empty inputs, large inputs
  • Error cases: Invalid inputs, precondition violations
  • Invariants: Things that must always be true
  • NOT implementation details: Test behavior, not internal structure

Test fakes and mocks

  • Use in-memory fakes for fast tests
  • Mock only external dependencies (I/O, time, randomness)
  • Don't mock domain logic
  • Avoid over-mocking (it couples tests to implementation)

Refactoring Guidelines

When to refactor

  • After getting tests passing
  • When you spot SOLID violations
  • When patterns don't fit the problem
  • When code is hard to understand

Refactoring rules

  • Keep tests green: Tests pass before and after
  • Small steps: One change at a time
  • Contracts stay stable: Don't change public interfaces
  • Commit frequently: Small, working commits

What can change during refactoring

  • Internal class structure
  • Method implementations
  • Private methods
  • Variable names and organization

What cannot change during refactoring

  • Public interfaces
  • DTO structures used by contracts
  • Test expectations
  • Observable behavior
Golden rule: If you need to change the contract, that's not refactoring—that's a new feature or breaking change.

Working with AI in ALD

What AI does well

  • Generate implementations from interfaces
  • Write boilerplate test scaffolding
  • Suggest refactoring improvements
  • Produce clean, repetitive code quickly

What humans must own

  • Define interfaces and DTOs
  • Approve behavioral contracts (tests)
  • Make architectural decisions
  • Validate correctness and SOLID adherence

Review checklist for AI-generated code

  • ✓ Does it implement the contract correctly?
  • ✓ Do all tests pass?
  • ✓ Does it follow SOLID principles?
  • ✓ Are dependencies properly injected?
  • ✓ Is core logic framework-agnostic?
  • ✓ Are edge cases handled?
  • ✓ Is the code readable and maintainable?
  • ✓ Can you describe what pattern it uses?

Non-Negotiables

These standards are mandatory in ALD:

  • Follow SOLID principles
  • Use GoF patterns where appropriate
  • Keep core logic framework-agnostic
  • No hidden behavior—tests define contracts
  • Prefer composition over inheritance
  • Produce clean, refactor-friendly code
  • All dependencies injectable
  • No global state
  • I/O at the edges only