Hướng dẫn php trait implement interface - giao diện triển khai đặc điểm php
Mở đầu
Traits là gì?Traits hiểu đơn giản là một nhóm các methods mà bạn muốn include nó trong một class khác. Một Trait giống với abstract class không thể khởi tạo trên chính nó. Show Một ví dụ của Trait có thể là:
Bạn có thể include Trait này trong các class khác như sau:
Bây giờ, nếu bạn tạo một đối tượng từ một trong hai class ở trên, bạn sẽ thấy được chúng đều có một method
Traits hoạt động như thế nào?Như những gì bạn thấy ở ví dụ bên trên, cả hai đối tượng 0 và 1 đều có sẵn method share() mặc dù nó không được định nghĩa.Một Trait đơn giản chỉ là cách 3 code trong thời gian chạy.Điều này có nghĩa là một Trait được sao chép vào class 0 và 5 bởi vậy khi khởi tạo một đối tượng mới từ class đó, method share() đã có sẵn.Traits khác Abstract classes như thế nào?Traits khác với Abstract class bởi vì chúng không phụ thuộc vào sự kế thừa. Thử tưởng tượng nếu 0 và 1 class kế thừa từ một Abstract class 9. Chúng ta có thể muốn nhiều hơn việc chỉ share các posts hay comments trên web mạng xã hội, bởi vậy có lẽ chúng ta có lẽ sẽ sử dụng cây kế thừa phức tạp như sau:
Việc kế thừa phức tạp như trên là khá khó chịu, nhưng nó cũng thêm sự phiền phức khi một đối tượng đơn giản không có cấu trúc kế thừa tương tự. Ví dụ, nếu chúng ta có một đối tượng message không muốn share trên mạng xã hội vì đó đối tượng này sẽ đòi hỏi một cấu trúc thừa kế hơi khác. Traits khác với Interfaces ra sao?Traits có đặc điểm khá giống với Interfaces. Cả Traits và Interfaces đều luôn luôn đơn giản, ngắn gọn và không sử dụng nhiều nếu không có một class thực tế được implements. Tuy nhiên sự khác biệt giữa chúng là điểm quan trọng. Một Interface là một giao ước rằng 0, trong khi Trait cho phép một đối tượng có khả năng thực hiện cái gì đó. Ví dụ:
Trong ví dụ này chúng ta có một Interface 1 tuyên bố rằng một đối tượng 0 có thể 3 và 4. Trait 5 triển khai (implements) phương thức share() phương thức 7 được triển khai trong lớp 0.Vì vậy bạn có thể thấy chúng ta có thể gõ gợi ý đối tượng 0 để thấy rằng nếu nó là sociable (nó được implements 1 interface), trong khi các Trait định nghĩa một phương pháp tái sử dụng mà chúng ta có thể kết hợp trong các classes tương tự khác:
Vậy Traits có những lợi ích nào?Lợi ích của việc sử dụng Trait đó là bạn giảm việc trùng lặp code trong khi không phải sử dụng đa kế thừa phức tạp mà không có ý nghĩa trong bối cảnh ứng dụng của bạn. Điều này cho phép bạn xác định Traits đơn giản rõ ràng xúc tích và kết hợp nó trong những chức năng thích hợp. Nhược điểm của TraitsTraits tạo ra việc bạn có thể dễ viết các classes cồng kềnh và có quá nhiều chức năng. Một Trait bản chất là một cách để 3 code giữa các classes. Bởi có một cách đơn giản để thêm một nhóm các methods vào một class. Nó rất dễ dàng xa rời single responsibility principle .Một điểm trừ khác nữa khi sử dụng Traits đó là không thể xem xét tất cả methods của một class khi nhìn vào source code cũng như method bị xung đột hay lặp logic. Tôi nghĩ rằng khi Traits được sử dụng đúng cách thì nó sẽ là một công cụ tuyệt vời cho việc xử lý của chúng ta. Tuy vậy, Traits cũng có thể trở thành vật chống lưng cho lập trình lười biếng (lazy programming). Bạn có thể giải quyết vấn đề ngay lập tức chỉ với việc thêm một trait. Thường thì Composition là cách tiếp cận tốt hơn kế thừa hoặc sử dụng một Trait. Các tình huống điển hình nên dùng TraitsVâng, tôi nghĩ rằng Traits là một cách tuyệt vời để tái sử dụng một đoạn code giữa một tập các class tương tự mà không cần kế thừa từ cùng một abstract class. Sử dụng ví dụ về 2trước đó, tưởng tượng rằng chúng ta có các đối tượng 0, 4, 5, 6 và 7. Hầu hết, các đối tượng trên có thể hoán đổi trong hệ thống như chúng được tạo ra và tương tác giữa các users với nhau.Tuy vậy, 0, 4, 5 và 7 là các đối tượng công khai, có thể chia sẻ giữa các users. Trong khi đối tượng 6 là tin nhắn riêng không được công khai. Do vậy, 0, 4, 5 và 7 được implements bởi 7 interface:
Liệu việc lặp lại method 7 interface?Liệu việc sử dụng 0 class extend mà các đối tượng được implements bởi 7 interface có ý nghĩa?Liệu việc chúng ta có method 3 nhưng sau đó lại chặn method đó với đối tượng 6 là có ý nghĩa?Câu trả lời đều là không. Liệu nó có ý nghĩa để implements một 5 thỏa mãn các interfaces contract và có thể dễ dàng thêm vào các đối tượng chỉ cần nó?Câu trả lời là có. Ví dụ thực tế của việc sử dụng TraitsViệc xác định khi nào cần sử dụng Traits hoặc xác định một trong những phương án giải quyết vấn đề của bạn đôi khi rất khó khăn. Khi bạn đối mặt với vấn đề này, ý tưởng không tồi là xem xét các open source trên thế giới để biết được cách mà họ áp dụng kỹ thuật này như thế nào. Theo ý kiến cá nhân của tôi, một Open Source project tận dụng tốt các đặc điểm của Traits là Laravel package Cashier. Cashier package thêm chức năng cho Eloquent model giúp nó thực sự dễ dàng trong việc quản lý subscriptions trong các ứng dụng Saas (Software as a service). Tuy nhiên để thêm chức năng cho các models đã tồn tại, bạn sẽ đối mặt với một số khó khăn. Lựa chọn đầu tiên là chỉ cần implement đơn giản trong các methods của bạn bằng cách copy các method ví dụ từ tài liệu của Cashier. Đây không phải là giải pháp tốt vì bạn có thể gặp các lỗi như copy code sai (sad) hay bất cứ khi nào Cashier update bạn phải duyệt qua tât cả các models và cập nhật lại code (dead). Lựa chọn thứ hai là extend đối tượng Cashier để kế thừa các methods mà bạn cần. Đây cũng là giải pháp tồi bởi vì điều gì sẽ xảy ra khi ban muốn thêm các methods từ một package để validate cho models của bạn? Bạn sẽ phải viết code một dòng kế thừa phức tạp và khó hiểu. Để rồi một ngày kia đồng nghiệp của bạn hoặc chính bạn khi đọc lại đoạn code này phải thốt lên một câu 6.Thay vào đó, Cashier package cung cấp một trait cho phép bạn thêm chức năng cho bất kỳ models nào mà không làm lặp code của chính nó hoặc có một dòng kế thừa khó chịu:
Kết luận
Bài viết gốcWhat are PHP Traits? |