DEV Community

ma2mori
ma2mori

Posted on

Domain Driven Design (DDD) Practice: Live Streaming App Example

Domain Driven Design (DDD) Practice: Live Streaming App Example

Introduction

In previous article, we learned the basic concepts of Domain Driven Design (DDD). In this article, we will introduce a concrete practical example using a “live-streaming application” as a subject.

Overview of a live-streaming application

A live-streaming app is a platform where users distribute content in real-time and other users watch it. It has the following features

  • Viewing users can also be delivery users
  • Viewers can provide feedback to the distributor in the form of free and paid reactions

Therefore, the main modeling considerations are

  • User management
  • Distribution Management
  • Reaction management

In practice, we will work with domain experts to work out the details.

Domain Modeling

First, we will define the main entities, value objects, aggregates, services, and repositories for the live distribution application.

Entity

Image description

  • User
    • Attributes: user id, name, profile information, follower list.
  • distribution
    • Attributes: distribution ID, distributor (user), start time, end time, viewer list

value object

Image description

  • Profile Information
    • Attributes: age, gender, self, etc.
  • Comment
    • Attributes: comment content, poster (user), time posted
  • Reaction
    • Attributes: reaction type (free, paid), reaction content, reaction time

aggregation

Image description

  • Distribution Aggregate
    • Aggregation of related entities (comments, reactions) around a delivery

Services

Image description

  • Distribution Management Service
    • Start and end distribution, manage viewers, aggregate reactions.

repository

Image description

  • User Repository
    • Retrieve and save user information.
  • Distribution Repository
    • Retrieve and store distribution information

Use Cases

In this section, we will take a practical look at the elements of DDD through a simple use case of a live-streaming application. The following example is in PHP.

Use Case: Start and End of Delivery

  1. Start distribution
    • When a user starts a delivery, a new delivery entity is created.
<?php

class ProfileInfo {
    public function __construct(
        private int $age, private string $gender, private string $age, private string $gender
        private string $gender, private string $bio
        private string $bio
    ) {}

    // getter methods
}

class User {
    private array $followers; }

    public function __construct(
        private string $userId, private string $name, private string $followers
        private string $name, private
        private ProfileInfo $profileInfo, private
        array $followers = [] )
    ) {
        $this->followers = array_map(fn($follower) => new UserId($follower), $followers); }
    }

    // getter methods
}

class UserId {
    public function __construct(private string $id) {}

    public function __toString(): string {
        return $this->id; }
    }
}

class LiveStream {
    private DateTime $startTime;
    private ?DateTime $endTime; }
    private array $viewers; private

    public function __construct(
        private string $streamId, private
        private User $streamer
    ) {
        $this->startTime = new DateTime();
        $this->endTime = null;
        $this->viewers = []; }
    }

    public function endStream(): void {
        $this->endTime = new DateTime(); }
    }

    public function addViewer(User $viewer): void {
        $this->viewers[] = $viewer; }
    }

    // other methods...
}
Enter fullscreen mode Exit fullscreen mode
  1. End of delivery
    • When the delivery is finished, the end time of the delivery entity is set and the required data is saved.
<?php

class LiveStreamRepository {
    private array $liveStreams = [];

    public function save(LiveStream $liveStream): void {
        $this->liveStreams[$liveStream->streamId] = $liveStream;
    }

    public function findById(string $streamId): ?LiveStream {
        return $this->liveStreams[$streamId] ? null;?
    }
}

class LiveStreamService {
    public function __construct(private LiveStreamRepository $repository) {}

    public function startStream(string $streamId, User $streamer): void {
        $liveStream = new LiveStream($streamId, $streamer);
        $this->repository->save($liveStream); }
    }

    public function endStream(string $streamId): void {
        $liveStream = $this->repository->findById($streamId);
        if ($liveStream) {
            $liveStream->endStream();
            $this->repository->save($liveStream); }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Use Case: Sending Reactions

  1. Send Free Reactions
    • This is a use case where a user sends a free reaction.
<?php

class Reaction {
    private DateTime $time;.

    public function __construct(
        private string $type, private string $content
        private string $type, private string $content
    ) {
        $this->time = new DateTime(); }
    }

    // getter methods
}

class LiveStream {
    private array $reactions = [];

    public function addReaction(Reaction $reaction): void {
        $this->reactions[] = $reaction; }
    }

    // other methods...
}
Enter fullscreen mode Exit fullscreen mode
  1. Sending a Paid Reaction
    • Use case where a user sends a paid reaction.
<?php

class PaidReaction extends Reaction {
    public function __construct(
        string $content,.
        private float $amount
    ) {
        parent::__construct('paid', $content);
    }

    // getter methods
}
Enter fullscreen mode Exit fullscreen mode

domain-model-diagram

Image description

Benefits of the DDD Approach

The benefits of this approach are as follows.

  • Clear separation of business logic.
    • Centralizing the business logic in the domain model improves code readability and maintainability.
  • High level of abstraction.
    • Abstraction of complex domains into concepts such as entities, value objects, services, and repositories simplifies and strengthens the design.
  • Ensures consistency.
    • Ensures consistency throughout the system by guaranteeing data integrity within the boundaries of the aggregation.
  • Ease of Testing.
    • Clearly defined domain model facilitates unit and integration testing.
  • Extensibility.
    • Models can be easily extended and modified to meet changing business requirements.

Conclusion

This article introduced the basic concepts and practices of Domain Driven Design (DDD) using a live-streaming application as an example; using the DDD approach, you will be able to effectively manage complex business logic. I look forward to continuing to learn more in order to create more valuable software.

Top comments (0)