[Laravel Container] Resolve phương thức bạn dùng rất nhiều nhưng có thể chưa biết

Chào các bạn, hôm nay chúng ta sẽ "giải mã" một đoạn mã PHP khá thú vị, và tôi đảm bảo rằng sau khi đọc xong, bạn sẽ không còn cảm thấy sợ hãi khi nhìn thấy những thuật ngữ khó hiểu trong lập trình nữa! Đoạn mã này đến từ một hệ thống dependency injection container, nơi mà các đối tượng được "khởi tạo" (instantiate) một cách thông minh và tự động. Cùng tìm hiểu nhé!

1. Đặt vấn đề (Alias và Param)

Đầu tiên, khi bạn gọi hàm resolve(), nó nhận vào một tham số $abstract (mà thông thường có thể là tên của một lớp hoặc một alias nào đó). Đoạn mã bắt đầu bằng việc gọi $this->getAlias($abstract) để "đổi tên" nếu cần thiết. Nghĩa là, nếu bạn truyền vào một alias, hệ thống sẽ tìm ra tên thực tế của đối tượng bạn đang cần.

2. Kích hoạt sự kiện trước khi giải quyết (Firing Events)

Tiếp theo, chúng ta có một đoạn mã kiểm tra xem có cần kích hoạt sự kiện trước khi "giải quyết" (resolve) đối tượng không ($raiseEvents). Nếu có, phương thức $this->fireBeforeResolvingCallbacks() sẽ được gọi để thực thi những hàm xử lý trước khi đối tượng được tạo ra. Đây là một cơ chế cho phép hệ thống "chuẩn bị" trước khi chính thức tạo đối tượng, có thể là để thay đổi một số tham số hoặc thực hiện các thay đổi khác.

3. Tìm kiếm đối tượng thực tế (Concrete)

Bây giờ đến phần "tìm kiếm" đối tượng thực tế, hay còn gọi là $concrete. Nếu hệ thống chưa có thông tin về đối tượng này, nó sẽ gọi $this->getContextualConcrete($abstract) để lấy thông tin về cách "xây dựng" đối tượng đó. Nếu không có, nó sẽ kiểm tra thêm các tham số hoặc đối tượng đã có trước đó.

4. Kiểm tra Singleton (Single Instance)

Lúc này, ta có một câu hỏi quan trọng: Nếu đối tượng này đã được tạo ra trước đó, liệu chúng ta có cần tạo mới không? Để trả lời câu hỏi đó, hệ thống sẽ kiểm tra xem đối tượng có đang được lưu trữ dưới dạng singleton hay không. Nếu đúng, thay vì tạo mới, nó sẽ lấy lại đối tượng đã được lưu trữ trước đó từ mảng $this->instances.

5. Xử lý các tham số bổ sung (With Parameters)

Tiếp đến, phương thức sẽ ghi lại các tham số bổ sung vào biến $this->with[]. Cái này giống như bạn truyền thêm các "thông số" cho đối tượng, ví dụ như một số thiết lập đặc biệt cho đối tượng đó.

6. Xây dựng đối tượng thực tế (Building Object)

Khi tất cả đã sẵn sàng, hệ thống sẽ quyết định xem đối tượng có thể "xây dựng" được hay không (bằng cách gọi $this->isBuildable()). Nếu được, nó sẽ gọi phương thức $this->build($concrete) để khởi tạo đối tượng, nếu không thì sẽ gọi $this->make($concrete).

7. Extenders - Mở rộng đối tượng (Extensions)

Bây giờ, đến phần thú vị! Nếu đối tượng có những "extenders" (những phần mở rộng hoặc thay đổi thêm cho đối tượng), hệ thống sẽ áp dụng các "extenders" đó vào đối tượng đã xây dựng. Đây là nơi mà các kỹ thuật như decorator hoặc thay đổi cấu hình có thể xảy ra. Ví dụ, nếu bạn muốn thay đổi hành vi của đối tượng sau khi đã được tạo, "extenders" chính là cách làm.

8. Lưu trữ đối tượng nếu cần (Caching Object)

Nếu đối tượng này là một singleton (được tái sử dụng nhiều lần), hệ thống sẽ "lưu" đối tượng vào $this->instances để lần sau chỉ cần lấy lại mà không cần khởi tạo lại.

9. Kích hoạt sự kiện sau khi giải quyết (After Resolution Event)

Trước khi trả về đối tượng, nếu có yêu cầu, phương thức sẽ kích hoạt các sự kiện sau khi đối tượng đã được tạo ra bằng $this->fireResolvingCallbacks().

10. Kết thúc và trả về đối tượng (Returning the Object)

Cuối cùng, trước khi trả về đối tượng, phương thức sẽ đánh dấu đối tượng này là "đã giải quyết" trong $this->resolved và loại bỏ các tham số tạm thời (array_pop($this->with)). Sau đó, đối tượng đã hoàn chỉnh sẽ được trả về cho bạn!


Tổng kết:

Đoạn mã trên là một "bộ não" phía sau một container dependency injection. Nó giúp quản lý các đối tượng một cách thông minh, từ việc tạo đối tượng mới, tái sử dụng đối tượng cũ (singleton), cho đến việc mở rộng các đối tượng với những thay đổi tùy ý. Nếu bạn chưa quen với Dependency Injection, thì đây là một ví dụ rất hay để thấy được cách hệ thống này hoạt động, giúp giảm thiểu sự phụ thuộc và dễ dàng quản lý các đối tượng trong ứng dụng của bạn.

Chúc các bạn có thêm một chút "vui vẻ" trong thế giới phức tạp của lập trình!

Nhận xét