Ray.Di Study: Practical Object-Oriented Design Patterns

This study teaches which pattern solves which problem. Using Ray.Di, you will deepen your practical understanding of SOLID principles and design patterns, and build the judgement to create maintainable and extensible architectures.

Learning focus

  • From problem to pattern: Solve problems such as tight coupling, bloated controllers, and mixed data access with the right pattern
  • Decision criteria: Learn when to use a Factory, when to use a Strategy, and when to use a Repository
  • Practical SOLID: Understand single responsibility, open/closed, and dependency inversion through real code
  • Architecture design: Layer separation, separation of concerns, and module design
  • Compile-time decisions: Replace runtime if statements ($_ENV checks, type checks) with DI bindings to reduce code paths and achieve the open/closed principle

This tutorial focuses on learning design patterns. For the Ray.Di feature reference, see the manual.

Tutorial structure

Part 1: Foundations - Why DI matters

Problem: Tight coupling, hard to test, fragile to change What you learn: How dependency injection and SOLID principles solve these problems

Part 2: Object creation patterns

Problem: Bloated constructors, runtime parameters, optional dependencies What you learn: Decision criteria for separating object creation responsibilities

Part 3: Behavioral patterns

Problem: Exploding conditionals, scattered cross-cutting concerns What you learn: How to make behavior switchable and separate concerns

Part 4: Architecture patterns

Problem: Mixed data access, bloated controllers, bloated DI configuration What you learn: Architecture design that separates layers and clarifies responsibilities

Learning approach

Each section follows a consistent structure:

  1. Problem - A concrete issue in real code (10-20 lines)
  2. Why it matters - Impact on maintainability, testability, and extensibility
  3. Solution - The core implementation of the pattern (30-50 lines)
  4. The essence of the pattern - Visual understanding through diagrams
  5. Decision criteria - When to use this pattern and when not to
  6. Anti-patterns - Common mistakes and why they happen
  7. Relation to SOLID - The principles this pattern realizes

Where to start

For OOP beginners Recommended order: Dependency Injection Principles → SOLID Principles → Factory Pattern

For experienced developers You can start anywhere. Each section is independent.

For architects Recommended: SOLID Principles → Architecture patterns

Key patterns covered

Pattern Problem it solves When to use it
Factory Mixing runtime parameters with DI dependencies When object creation needs runtime values
Provider Bloated constructors When complex initialization logic is needed
Null Object Scattered null and environment checks When optional dependencies vary by environment
Strategy Exploding conditionals When switching algorithms at runtime
Decorator/AOP Scattered cross-cutting concerns When separating logging, transactions, and similar concerns
Adapter Mismatch between an external API and the application When adapting an external service to the application
Repository Mixed data access When separating data access from business logic
Service Layer Bloated controllers When coordinating business logic
Module Design Bloated DI configuration When there are more than 50 bindings

Prerequisites

  • A basic understanding of OOP
  • Knowledge of interfaces

Additional resources


Start: Dependency Injection Principles

Design patterns are not something to memorize - understanding the decision criteria is what matters. This tutorial will help you develop the judgement to choose the right pattern for each situation.