Trong lập trình hướng đối tượng, đa hình là một công cụ cơ bản và mạnh mẽ. Nó có thể được sử dụng để tạo ra một luồng hữu cơ hơn trong ứng dụng của bạn. Hướng dẫn này sẽ mô tả khái niệm chung về tính đa hình và cách triển khai nó dễ dàng trong PHP
Đa hình là gì?
Đa hình là một từ dài cho một khái niệm rất đơn giản
Tính đa hình mô tả một mẫu trong lập trình hướng đối tượng, trong đó các lớp có chức năng khác nhau trong khi chia sẻ một giao diện chung
Cái hay của tính đa hình là mã làm việc với các lớp khác nhau không cần biết nó đang sử dụng lớp nào vì tất cả chúng đều được sử dụng theo cùng một cách
Một sự tương tự trong thế giới thực cho tính đa hình là một nút. Mọi người đều biết cách sử dụng một nút. bạn chỉ cần áp dụng áp lực cho nó. Tuy nhiên, chức năng của một nút phụ thuộc vào những gì nó được kết nối và ngữ cảnh mà nó được sử dụng -- nhưng kết quả không ảnh hưởng đến cách nó được sử dụng. Nếu sếp của bạn yêu cầu bạn nhấn một nút, bạn đã có tất cả thông tin cần thiết để thực hiện nhiệm vụ
Trong thế giới lập trình, tính đa hình được sử dụng để làm cho các ứng dụng trở nên mô-đun hơn và có thể mở rộng hơn. Thay vì các câu lệnh điều kiện lộn xộn mô tả các hướng hành động khác nhau, bạn tạo các đối tượng có thể hoán đổi cho nhau mà bạn chọn dựa trên nhu cầu của mình. Đó là mục tiêu cơ bản của đa hình
giao diện
Một phần không thể thiếu của tính đa hình là giao diện chung. Có hai cách để định nghĩa một giao diện trong PHP. giao diện và lớp trừu tượng. Cả hai đều có công dụng của chúng và bạn có thể trộn và kết hợp chúng khi bạn thấy phù hợp với hệ thống phân cấp lớp học của mình
giao diện
Một giao diện tương tự như một lớp ngoại trừ việc nó không thể chứa mã. Một giao diện có thể xác định tên phương thức và đối số, nhưng không phải nội dung của phương thức. Bất kỳ lớp nào triển khai giao diện phải triển khai tất cả các phương thức được xác định bởi giao diện. Một lớp có thể thực hiện nhiều giao diện
Một giao diện được khai báo bằng từ khóa '
class MyClass implements MyInterface { // methods }5'
interface MyInterface { // methods }
và được gắn vào một lớp bằng cách sử dụng từ khóa '
class MyClass implements MyInterface { // methods }6' [có thể triển khai nhiều giao diện bằng cách liệt kê chúng được phân tách bằng dấu phẩy]
class MyClass implements MyInterface { // methods }
Các phương thức có thể được định nghĩa trong giao diện giống như trong một lớp, ngoại trừ không có phần thân [phần giữa các dấu ngoặc nhọn]
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }
Tất cả các phương thức được định nghĩa ở đây sẽ cần được đưa vào bất kỳ lớp triển khai nào chính xác như được mô tả. [đọc các bình luận mã bên dưới]
// VALID class MyClass implements MyInterface { protected $name; public function doThis[] { // code that does this } public function doThat[] { // code that does that } public function setName[$name] { $this->name = $name; } } // INVALID class MyClass implements MyInterface { // missing doThis[]! private function doThat[] { // this should be public! } public function setName[] { // missing the name argument! } }
lớp trừu tượng
Một lớp trừu tượng là sự pha trộn giữa một giao diện và một lớp. Nó có thể định nghĩa chức năng cũng như giao diện [ở dạng phương thức trừu tượng]. Các lớp mở rộng một lớp trừu tượng phải thực hiện tất cả các phương thức trừu tượng được định nghĩa trong lớp trừu tượng
Một lớp trừu tượng được khai báo giống như các lớp có thêm từ khóa '
class MyClass implements MyInterface { // methods }7'
abstract class MyAbstract { // methods }
và được gắn vào một lớp bằng từ khóa '
class MyClass implements MyInterface { // methods }8'
class MyClass extends MyAbstract { // class methods }
Các phương thức thông thường có thể được định nghĩa trong một lớp trừu tượng giống như trong một lớp thông thường, cũng như bất kỳ phương thức trừu tượng nào [sử dụng từ khóa '
class MyClass implements MyInterface { // methods }7']. Các phương thức trừu tượng hoạt động giống như các phương thức được định nghĩa trong một giao diện và phải được triển khai chính xác như được xác định bằng cách mở rộng các lớp
interface MyInterface { // methods }1
Bước 1. Xác định vấn đề
Hãy tưởng tượng rằng bạn có một lớp
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }0 chịu trách nhiệm quản lý các bài viết trên trang web của bạn. Nó chứa thông tin về một bài báo, bao gồm tiêu đề, tác giả, ngày tháng và thể loại. Đây là những gì nó trông giống như
interface MyInterface { // methods }3
Ghi chú. Các lớp ví dụ trong hướng dẫn này sử dụng quy ước đặt tên là "package_component_Class. " Đây là cách phổ biến để phân tách các lớp thành các không gian tên ảo để tránh xung đột tên
Bây giờ bạn muốn thêm một phương thức để xuất thông tin sang các định dạng khác nhau, chẳng hạn như XML và JSON. Bạn có thể bị cám dỗ để làm một cái gì đó như thế này
interface MyInterface { // methods }4
Đây là một giải pháp xấu xí, nhưng nó hiệu quả -- hiện tại. Tuy nhiên, hãy tự hỏi điều gì sẽ xảy ra trong tương lai khi chúng tôi muốn thêm nhiều định dạng hơn?
Một nguyên tắc quan trọng của OOP là một lớp nên làm một việc và nó sẽ làm tốt việc đó.
Với suy nghĩ này, các câu điều kiện phải là một lá cờ đỏ cho biết rằng lớp của bạn đang cố gắng làm quá nhiều việc khác nhau. Đây là nơi tính đa hình xuất hiện
Trong ví dụ của chúng tôi, rõ ràng là có hai nhiệm vụ được trình bày. quản lý bài viết và định dạng dữ liệu của họ. Trong hướng dẫn này, chúng ta sẽ cấu trúc lại mã định dạng của mình thành một tập hợp các lớp mới và khám phá cách sử dụng tính đa hình dễ dàng như thế nào
Bước 2. Xác định giao diện của bạn
Điều đầu tiên chúng ta nên làm là xác định giao diện. Điều quan trọng là phải suy nghĩ kỹ về giao diện của bạn, bởi vì bất kỳ thay đổi nào đối với nó có thể yêu cầu thay đổi mã gọi. Trong ví dụ của chúng tôi, chúng tôi sẽ sử dụng một giao diện đơn giản để xác định một phương thức của chúng tôi
interface MyInterface { // methods }5
Nó đơn giản mà; . Bất kỳ lớp nào triển khai giao diện Writer chắc chắn sẽ có phương thức này
Mẹo. Nếu bạn muốn hạn chế loại đối số có thể được chuyển đến các hàm và phương thức của mình, bạn có thể sử dụng gợi ý loại, như chúng ta đã thực hiện trong phương thức
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }1; . Thật không may, gợi ý kiểu trả về không được hỗ trợ trong các phiên bản PHP hiện tại, do đó, việc xử lý các giá trị trả về tùy thuộc vào bạn
Bước 3. Tạo triển khai của bạn
Với giao diện của bạn đã được xác định, đã đến lúc tạo các lớp thực sự làm công việc. Trong ví dụ của chúng tôi, chúng tôi có hai định dạng mà chúng tôi muốn xuất ra. Như vậy chúng ta có hai lớp Writer. XMLWriter và JSONWriter. Việc trích xuất dữ liệu từ đối tượng Bài viết đã truyền và định dạng thông tin phụ thuộc vào những điều này
Đây là giao diện của XMLWriter
class MyClass implements MyInterface { // methods }0
Như bạn có thể thấy từ phần khai báo lớp, chúng tôi sử dụng từ khóa
class MyClass implements MyInterface { // methods }6 để triển khai giao diện của mình. Phương thức
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }1 chứa chức năng cụ thể để định dạng XML
Bây giờ đây là lớp JSONWriter của chúng ta
class MyClass implements MyInterface { // methods }1
Tất cả mã của chúng tôi dành riêng cho từng định dạng hiện được chứa trong các lớp riêng lẻ. Mỗi lớp này có trách nhiệm duy nhất là xử lý một định dạng cụ thể và không có gì khác. Không có phần nào khác trong ứng dụng của bạn cần quan tâm đến cách chúng hoạt động để sử dụng nó, nhờ vào giao diện của chúng tôi
Bước 4. Sử dụng triển khai của bạn
Với các lớp mới của chúng ta đã được định nghĩa, đã đến lúc xem lại lớp Article của chúng ta. Tất cả mã tồn tại trong phương thức
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }1 ban đầu đã được đưa vào tập hợp các lớp mới của chúng tôi. Tất cả phương pháp của chúng tôi phải làm bây giờ là sử dụng các lớp mới, như thế này
class MyClass implements MyInterface { // methods }2
Tất cả những gì phương thức này làm bây giờ là chấp nhận một đối tượng của lớp Writer [đó là bất kỳ lớp nào triển khai giao diện Writer], gọi phương thức
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }1 của nó, chuyển chính nó [
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }8] làm đối số, sau đó chuyển tiếp giá trị trả về của nó thẳng tới mã máy khách. Nó không còn phải lo lắng về các chi tiết định dạng dữ liệu và nó có thể tập trung vào nhiệm vụ chính của nó
Có được một nhà văn
Bạn có thể tự hỏi mình lấy đối tượng Writer ở đâu để bắt đầu, vì bạn cần truyền một đối tượng cho phương thức này. Điều đó tùy thuộc vào bạn và có nhiều chiến lược. Ví dụ: bạn có thể sử dụng lớp xuất xưởng để lấy dữ liệu yêu cầu và tạo một đối tượng
class MyClass implements MyInterface { // methods }3
Như tôi đã nói, có nhiều chiến lược khác để sử dụng tùy thuộc vào yêu cầu của bạn. Trong ví dụ này, một biến yêu cầu chọn định dạng sẽ sử dụng. Nó xây dựng một tên lớp từ biến yêu cầu, kiểm tra xem nó có tồn tại không, sau đó trả về một đối tượng Writer mới. Nếu không tồn tại dưới tên đó, một ngoại lệ sẽ được đưa ra để mã máy khách tìm ra việc cần làm
Bước 5. Đặt nó tất cả cùng nhau
Với mọi thứ đã sẵn sàng, đây là cách mã máy khách của chúng tôi sẽ kết hợp tất cả lại với nhau
class MyClass implements MyInterface { // methods }4
Đầu tiên chúng ta tạo một đối tượng Article mẫu để làm việc với. Sau đó, chúng tôi cố gắng lấy một đối tượng Nhà văn từ Nhà máy, quay trở lại mặc định [XMLWriter] nếu một ngoại lệ được đưa ra. Cuối cùng, chúng ta truyền đối tượng Writer vào phương thức
interface MyInterface { public function doThis[]; public function doThat[]; public function setName[$name]; }1 của Article, in kết quả
Sự kết luận
Trong hướng dẫn này, tôi đã giới thiệu cho bạn về tính đa hình và giải thích về các giao diện trong PHP. Tôi hy vọng bạn nhận ra rằng tôi chỉ cho bạn thấy một trường hợp sử dụng tiềm năng cho tính đa hình. Còn nhiều, rất nhiều ứng dụng nữa. Đa hình là một cách tao nhã để thoát khỏi các câu lệnh điều kiện xấu xí trong mã OOP của bạn. Nó tuân theo nguyên tắc giữ các thành phần của bạn tách biệt và là một phần không thể thiếu trong nhiều mẫu thiết kế. Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại hỏi trong phần bình luận