Solution Architecture Practice

Comprehensive guide to software architecture frameworks, patterns, and best practices

View project on GitHub

Reuse and Standardization Principle

Overview

Principle: Maximize reuse of proven solutions and enforce standards across the organization.

Standardization reduces cognitive load, improves quality, and speeds development. Reuse avoids reinventing solutions.

Rationale

  • Every team shouldn’t solve same problems
  • Standards reduce decision paralysis
  • Reusable components accelerate delivery
  • Inconsistency creates confusion and bugs
  • Organizational knowledge should be shared

Core Implications

1. Reuse Levels

Code Reuse:

Level 1 (Copy-Paste)
❌ Worse: Duplicated code, bugs in multiple places

Level 2 (Shared Library)
✅ Better: One implementation, multiple consumers
   All teams use logging-library v1.2.3

Level 3 (Platform Service)
✅ Best: Service abstracts complexity
   All teams use Auth Service API
   Auth Service owns authentication logic and updates

Level 4 (Inner Source)
✅ Excellent: Internal open source
   Teams contribute improvements
   Shared ownership across organization

2. Standardization Categories

Technical Standards:

Code Style:
- Language-specific conventions
- Linting rules
- Formatting requirements

Example (TypeScript):

// GOOD - follows standard const getUserName = (userId: string): string => { return user.displayName; }

// BAD - doesn’t follow standard function get_user_name(userID){ return user.display_name }


Naming Conventions:
- Packages: lowercase with hyphens (my-package)
- Classes: PascalCase (UserService)
- Functions/variables: camelCase (getUserName)
- Constants: UPPER_SNAKE_CASE (MAX_RETRIES)

Database Naming:
- Tables: plural, lowercase (users, orders, order_items)
- Columns: lowercase with underscores (created_at, user_id)
- Primary keys: id (not user_id)
- Foreign keys: {entity}_id (user_id, order_id)

API Standards:

RESTful Convention:
- GET /api/v1/users - List users
- POST /api/v1/users - Create user
- GET /api/v1/users/{id} - Get specific user
- PUT /api/v1/users/{id} - Update user
- DELETE /api/v1/users/{id} - Delete user

Response Format:
{
  "status": "success|error",
  "data": {...},
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable message",
    "details": {...}
  }
}

Error Codes:
- 400: Bad Request (validation)
- 401: Unauthorized (auth needed)
- 403: Forbidden (permission denied)
- 404: Not Found
- 409: Conflict (duplicate)
- 500: Internal Server Error

Architectural Standards:

Deployment Pipeline:
Code → Build → Unit Test → Integration Test → Deploy to Staging → E2E Test → Deploy to Production

Configuration Management:
- Environment variables in .env
- Secrets in secure vault
- No secrets in code

Logging Format:
- JSON structured logging
- Standard fields: timestamp, level, message, context

Database Migration:
- Version control migrations
- Forward-only migrations (no rollbacks)
- Test migrations locally first

3. Reusable Component Patterns

Shared Library Example:

my-company/logging-library (npm package)
├─ Logger class
├─ Structured logging formatters
├─ Integration with ELK stack
└─ Metrics collection

Usage:
import { Logger } from "@my-company/logging-library"

const logger = new Logger("OrderService")
logger.info("Order created", {
  orderId: order.id,
  customerId: order.customerId,
  total: order.total
})

Shared Component Example:

my-company/auth-service (API service)
Provides:
- User authentication
- Token generation
- Permission checking
- OAuth integration

All services use:
GET /auth/v1/validate-token
POST /auth/v1/generate-token
GET /auth/v1/permissions/{userId}

Platform Template Example:

my-company/microservice-template (repository template)
New service creation: "Use this template"

Includes:
├─ Base service structure
├─ Logging configured
├─ Metrics collection
├─ CI/CD pipeline
├─ Docker configuration
├─ Documentation template
└─ Testing setup

Result: New service ready in 5 minutes instead of 2 hours

4. Architecture Decision Records (ADRs)

ADR Structure:

# ADR 0001: Use PostgreSQL for Primary Database

## Status
ACCEPTED

## Context
We need a database for user and order data. Options: PostgreSQL, MySQL, MongoDB

## Decision
Use PostgreSQL because:
- ACID compliance for financial transactions
- JSON support for flexible schema
- Strong community and tooling
- Proven at scale

## Consequences
- Must handle complex migrations
- Requires SQL expertise
- Licenses: Open source
- Infrastructure: Self-managed or RDS

## Alternatives Considered
- MySQL: Simpler but less flexible
- MongoDB: Too flexible, harder to maintain data integrity

## Related Decisions
- ADR 0002: Use Redis for caching
- ADR 0003: Event sourcing for audit trail

ADR Benefits:

  • Documents why decisions made
  • Prevents re-debating decisions
  • Onboards new team members
  • Guides similar decisions

Implementation Practices

1. Pattern Library

Organization Pattern Library:

Patterns: https://patterns.my-company.com

Patterns Documented:
├─ Authentication
│  ├─ OAuth2 integration
│  ├─ JWT token management
│  └─ Permission checking
│
├─ Data Access
│  ├─ Repository pattern
│  ├─ Query optimization
│  └─ Caching strategies
│
├─ API Design
│  ├─ Error handling
│  ├─ Pagination
│  └─ Versioning
│
├─ Resilience
│  ├─ Retry strategies
│  ├─ Circuit breaker
│  └─ Fallback handling
│
└─ Testing
   ├─ Unit test structure
   ├─ Mock strategies
   └─ Contract testing

Each pattern includes:
- Problem statement
- Solution
- Code example
- When to use
- Anti-patterns

2. Component Registry

Internal Component Registry: https://registry.my-company.com

Registered Components:
├─ @my-company/auth-service (v2.1.3)
│  Owner: Platform Team
│  Status: Stable
│  Usage: 14 services
│  Documentation: https://...
│
├─ @my-company/logging-library (v1.5.0)
│  Owner: Platform Team
│  Status: Stable
│  Usage: 42 services
│
├─ @my-company/message-queue (v3.0.0)
│  Owner: Platform Team
│  Status: Deprecated (use event-bus instead)
│
└─ @my-company/event-bus (v1.2.0)
   Owner: Platform Team
   Status: Recommended
   Usage: 8 services

3. Standardization Governance

Standards Committee:
├─ Meets monthly
├─ Proposes new standards
├─ Reviews deviations
├─ Makes exceptions

Standard Lifecycle:
Proposed → Draft (team feedback) → Approved (committee) → Enforced (tooling)

Exception Process:
1. Team documents why standard doesn't apply
2. Committee reviews and votes
3. If approved: document exception and monitor
4. Review exceptions quarterly

4. Tooling for Standards

Code Quality Enforcement:
- Linters (ESLint, Checkstyle): Enforce coding standards
- Formatters (Prettier, Black): Consistent formatting
- Static analysis (SonarQube): Code smell detection
- Dependency check: Vulnerable dependency detection

CI/CD Enforcement:
- Code review (GitHub): Changes reviewed by peers
- Status checks: Linting, tests, security scans pass
- Branch protection: Can't merge without approval

Documentation Requirements:
- All public APIs documented
- Examples provided
- Change logs maintained
- ADRs for major decisions

Common Scenarios

Scenario 1: Reducing Duplicate Work

Situation: Three teams implementing authentication differently.

Standardization Approach:

  1. Assess implementations
  2. Identify best approach
  3. Create shared auth-service
  4. Migrate teams incrementally
  5. Retire duplicates

Result: -500 lines of duplicate code, easier security updates

Scenario 2: Onboarding New Team Member

Situation: Engineer joins, needs to understand standards.

With Reuse and Standardization:

  1. Point to pattern library
  2. Show examples in codebase
  3. Review coding standards
  4. Start contributing immediately

Without Standards:

  1. Learn codebase conventions (scattered)
  2. Ask seniors about patterns
  3. Code reviews teach standards
  4. Slow ramp-up

Scenario 3: Technology Upgrade

Situation: Need to upgrade PostgreSQL versions.

With Standardization:

  1. Update shared library
  2. All services get upgrade
  3. One coordinated change

Without Standardization:

  1. Each service upgrades independently
  2. Different versions across company
  3. Support nightmare
  4. Duplicated testing effort

Risks of Ignoring This Principle

❌ Duplicate Effort: Every team reinvents solutions ❌ Inconsistency: Same problem solved differently each time ❌ Quality Issues: Some solutions better than others ❌ Onboarding Pain: New team members lost in inconsistency ❌ Maintenance Burden: Bugs fixed in multiple places ❌ Slow Development: Solving known problems over

Best Practices

✅ Start with shared libraries Extract common code early.

✅ Document patterns Make institutional knowledge explicit.

✅ Create templates Bootstrap new services quickly.

✅ Use ADRs Document why decisions made.

✅ Automate enforcement Don’t rely on humans to follow standards.

✅ Review and update standards Quarterly assessment of standard effectiveness.

✅ Make exceptions explicit Don’t hide deviations.

✅ Provide alternatives Standards should offer choices, not dictate.

✅ Celebrate reuse Recognize teams leveraging shared components.

References

  • Building Microservices (Sam Newman) - Standardization patterns
  • Architecture Decision Records (Nygard) - https://adr.github.io/
  • The Phoenix Project (Gene Kim) - Cross-team coordination

Last Updated: November 2025 Principle Category: Organization Applies To: Development, architecture, operations Related Documents: Standards Guide, Pattern Library, ADR Template