Kiến trúc: Mẫu Model-View-Presenter (MVP)

Tags:
Architecture
Design Pattern
UI
MVP

C# Code

using UnityEngine;
using UnityEngine.UI;

// 1. Model: Chứa dữ liệu và logic cốt lõi, không biết gì về UI.
public class PlayerStatsModel
{
    public int Health { get; private set; }
    public int MaxHealth { get; private set; }
    public event System.Action OnHealthChanged;

    public PlayerStatsModel(int initialHealth) {
        MaxHealth = initialHealth;
        Health = initialHealth;
    }

    public void TakeDamage(int amount) {
        Health = Mathf.Max(0, Health - amount);
        OnHealthChanged?.Invoke();
    }
}

// 2. View: Chỉ chịu trách nhiệm hiển thị và nhận input từ người dùng.
public interface IHealthView
{
    void UpdateHealth(int currentHealth, int maxHealth);
    event System.Action OnHealButtonClicked;
}

public class HealthView : MonoBehaviour, IHealthView
{
    public Slider healthSlider;
    public Text healthText;
    public Button healButton;

    public event System.Action OnHealButtonClicked;

    void Awake() {
        healButton.onClick.AddListener(() => OnHealButtonClicked?.Invoke());
    }

    public void UpdateHealth(int current, int max) {
        healthSlider.value = (float)current / max;
        healthText.text = $"{current} / {max}";
    }
}

// 3. Presenter: Lắng nghe input từ View, cập nhật Model, và ra lệnh cho View hiển thị.
public class HealthPresenter
{
    private PlayerStatsModel _model;
    private IHealthView _view;

    public HealthPresenter(PlayerStatsModel model, IHealthView view) {
        _model = model;
        _view = view;

        // Đăng ký lắng nghe sự kiện từ cả Model và View
        _model.OnHealthChanged += OnModelHealthChanged;
        _view.OnHealButtonClicked += OnViewHealRequest;

        // Cập nhật View lần đầu
        OnModelHealthChanged();
    }

    private void OnModelHealthChanged() {
        _view.UpdateHealth(_model.Health, _model.MaxHealth);
    }

    private void OnViewHealRequest() {
        // Người dùng nhấn nút Heal, Presenter ra lệnh cho Model
        _model.TakeDamage(-10); // Hồi 10 máu
    }
}

// 4. Khởi tạo trong một Bootstrap hoặc Manager class
public class GameBootstrap : MonoBehaviour {
    public HealthView view;
    void Start() {
        var model = new PlayerStatsModel(100);
        var presenter = new HealthPresenter(model, view);

        // Để test, thử gây sát thương cho model
        model.TakeDamage(20);
    }
}

Áp dụng mẫu MVP để tách biệt logic game (Model), UI (View), và phần điều khiển trung gian (Presenter). Giúp code dễ dàng unit test và quản lý các luồng dữ liệu phức tạp trong UI.

Bình luận (0)

Bạn cần đăng nhập để có thể bình luận.

Chưa có bình luận nào. Hãy là người đầu tiên!

Bài viết liên quan

Giới thiệu về mẫu thiết kế Dependency Injection (DI) và tại sao nó giúp code của bạn dễ bảo trì, dễ test và giảm sự phụ thuộc cứng (hard dependencies).

Architecture
Design Pattern
Optimization

Hướng dẫn cài đặt và sử dụng Zenject, một framework Dependency Injection phổ biến cho Unity, để quản lý các phụ thuộc trong dự án một cách hiệu quả.

Architecture
Design Pattern
DI
Zenject
Optimization

Một mẫu Singleton cơ bản trong Unity để đảm bảo chỉ có một thực thể của một lớp tồn tại trong game. Hữu ích cho các hệ thống toàn cục như GameManager, AudioManager.

Design Pattern
Singleton
Architecture

Một hệ thống kho đồ cơ bản sử dụng ScriptableObject cho dữ liệu vật phẩm và quản lý các ô chứa trong UI.

UI
Gameplay
Inventory
ScriptableObject
Architecture

Một cấu trúc Finite State Machine (FSM) đơn giản sử dụng enum và switch-case để quản lý các trạng thái khác nhau của AI, như đi tuần, truy đuổi và tấn công.

AI
Architecture
Design Pattern
Gameplay

Một hệ thống linh hoạt cho phép người chơi tương tác với nhiều loại đối tượng (cửa, vật phẩm, NPC, công tắc) chỉ bằng một nút bấm (E) khi ở trong tầm, kèm hiển thị gợi ý trên màn hình.

Interaction
Gameplay
Player
Architecture
Interface
UI

Giới thiệu về Clean Architecture, một triết lý thiết kế phần mềm giúp tách biệt các mối quan tâm thành các lớp riêng biệt (Entities, Use Cases, Adapters, Frameworks), tạo ra một hệ thống độc lập, dễ kiểm thử và bảo trì.

Architecture
Design Pattern
DI
Optimization

Sử dụng mẫu Observer với C# events, Actions và UnityEvents để tạo ra các hệ thống giao tiếp với nhau mà không cần biết về sự tồn tại của nhau (decoupling), giúp code linh hoạt và dễ bảo trì.

Architecture
Design Pattern
Event
Optimization

Triển khai mẫu Service Locator, một cách đơn giản để các phần khác nhau của game có thể truy cập vào các hệ thống toàn cục (services) như AudioManager, GameManager mà không cần tham chiếu trực tiếp.

Architecture
Design Pattern
Singleton
DI

Hiểu rõ về kiến trúc Monolithic - mô hình truyền thống nơi tất cả các thành phần của ứng dụng được xây dựng và triển khai như một đơn vị duy nhất. Đây là kiến trúc mặc định cho hầu hết các game Unity.

Architecture
Design Pattern
Build