Hướng đối tượng và lập trình PHP phần 3
Bài đăng này đã không được cập nhật trong 3 năm
Giới thiệu
Ở phần trước chúng ta đã có được khá nhiều kiến thức bổ ích về Trait
, Namespaces
, magic functions
và các quy tắc trong PSR2
. Phần này chúng ta tiếp tục đi tìm hiểu về SOLID và các phương pháp thiết kế hướng đối tượng(SOLID).
Vấn đề
- Các phương pháp thiết kế hướng đối tượng (SOLID).
- PSR va PSR4 là gì?
Nội dung
1. Các phương pháp thiết kế hướng đối tượng (SOLID)?
Ở phần 1, chúng ta đã phần nào nắm được các kiến thức của hướng đối tượng (OOP) link phần 1: https://goo.gl/MeEJhv. Hầu hết chúng ta đều học được các khái niệm, tính chất cơ bản của hướng đối tượng
- Tính trừu tượng (Abstraction)
- Tính đóng gói (Encapsulation)
- Tính kế thừa (Inheritance)
- Tính đa hình (Polymorphism)
SOLID là gì?
Những nguyên lý mình giới thiệu hôm nay là những nguyên lý thiết kế trong OOP
. Đây là những nguyên lý được đúc kết bởi máu xương vô số developer, rút ra từ hàng ngàn dự án thành công và thất bại. Một project áp dụng những nguyên lý này sẽ có code dễ đọc, dễ test, rõ ràng hơn. Và việc quan trọng nhất là việc maintainace code sẽ dễ hơn rất nhiều. Nắm rõ được những nguyên lý của SOLID
, bạn sẽ thành 1 lập trình viên thực thụ.
SOLID dựa trên 5 nguyên tắc sau:
- Single responsibility principle
- Open/closed principle
- Liskov substitution principle
- Interface segregation principle
- Dependency inversion principle
Single responsibility principle Nguyên lý đầu tiên, tương ứng với chữ S trong SOLID. Nội dung nguyên lý:
Một class chỉ nên giữ 1 trách nhiệm duy nhất (Chỉ có thể sửa đổi class với 1 lý do duy nhất)
class Employee
{
public function developSoftware(){};
public function testSoftware(){};
public function saleSoftware(){};
}
Giả sử một công ty có đợt tuyển nhân viên với 3 chức năng khác nhau. Developer sẽ vào developSoftware(), Tester sẽ vào testSoftware(), nhân viên sale sẽ vào saleSoftware(). Mỗi nhân viên sẽ được xếp vào đúng phòng ban và thực hiện đúng chức năng của mình. Ví dụ: developer sẽ không testSoftware(), ngược lại Tester sẽ chỉ thực hiện testSoftware(). Khi số lượng nhân viên có lớn thêm thì việc quản lý cũng dễ dàng hơn và điều quan trọng nhất là các nhân viên sẽ làm việc có hiệu quả hơn.
Open/closed principle Nguyên lý thứ hai, tương ứng với chữ O trong SOLID. Nội dung nguyên lý:
Có thể thoải mái mở rộng 1 class, nhưng không được sửa đổi bên trong class đó (open for extension but closed for modification).
Theo nguyên lý này, mỗi khi ta muốn thêm chức năng,.. cho chương trình, chúng ta nên viết class mới mở rộng class cũ ( bằng cách kế thừa hoặc sở hữu class cũ) không nên sửa đổi class cũ.
abstract class root
{
abstract public function sum($x);
}
class banchFirst extends root
{
public function sum($x)
{
return $x * 2;
}
}
class branchSecond extends root
{
public function sum($x)
{
return $x * 3;
}
}
Liskov Substitution Principle Nguyên lý thứ ba, tương ứng với chữ L trong SOLID. Nội dung nguyên lý:
Trong một chương trình, các object của class con có thể thay thế class cha mà không làm thay đổi tính đúng đắn của chương trình.
Nhìn vào ảnh trên, chúng ta có thể thấy:"chúng ta có thể ăn hết tất cả những chiêc Hăm-Bơ-Gơ, việc chúng ta ăn là cùng 1 hành động và nó là đúng". Đúng như nguyên lý: Hãy coi chiếc bánh lớn là class cha và 2 chiêc bánh nhỏ là 2 class con. Hai chiếc bánh con có thể khác loại thịt, rau,... Nhưng chúng là 2 chiếc Hăm-Bơ-Gơ và cùng được hành động "ăn" tác động vào. Một ví dụ nữa về Programer và Person
// Lớp Cha
class Person
{
// Thuộc Tính
var $mat = '';
var $mui = '';
var $mieng = '';
// Hàm, phương thức
function eat(){
// lệnh
}
function sleep(){
// lệnh
}
function playGame(){
// lệnh
}
}
// Lớp Con
class Programmer extends Person {
// Tất cả các thuộc tính khác đều kế thừa từ cha
// nên không cần viết lại
// chỉ riêng thuộc tính này là cha ko có nên ta phải khai báo
var $qualifications = '';
var $certificate = '';
// Tất cả các hàm, phương thức đều kế thừa từ cha
// nên không cần viết lại
}
Interface Segregation Principle Nguyên lý thứ tư, tương ứng với chữ I trong SOLID. Nội dung nguyên lý:
Thay vì dùng 1 interface lớn, ta nên tách thành nhiều interface nhỏ, với nhiều mục đích cụ thể
Nguyên lý này khá dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 methods. Việc implements sẽ khá cực khổ, ngoài ra còn có thể dư thừa vì 1 class không cần dùng hết 100 method. Khi tách interface ra thành nhiều interface nhỏ, gồm các method liên quan tới nhau, việc implement và quản lý sẽ dễ hơn.
Dependency inversion principle Nguyên lý cuối cùng, tương ứng với chữ D trong SOLID. Nội dung nguyên lý:
- Các module cấp cao không nên phụ thuộc vào các modules cấp thấp. Cả 2 nên phụ thuộc vào abstraction.
- Interface (abstraction) không nên phụ thuộc vào chi tiết, mà ngược lại. ( Các class giao tiếp với nhau thông qua interface, không phải thông qua implementation.)
2. PSR va PSR4 là gì?
PSR là gì? PSR là viết tắt của PHP Special Request, là những tiêu chuẩn khi code PHP, nó được cộng đồng PHP xây dựng và áp dụng theo.
Trong quá trình làm việc, các hệ thống sử dụng các framework khác nhau ví dụ như Phalcon hay Laravel có thể phải kết hợp với nhau để thực hiện những bài toán cụ thể.
Tuy nhiên đối với mỗi framework của mỗi team lại code theo những chuẩn khác nhau, do đó nảy sinh ra vấn đề là cần có một bộ quy tắc chuẩn để giải quyết việc các code không chuẩn này, và PSR ra đời nhắm chuẩn hóa coding convention cho tất cả các framework, các framework chỉ việc tuân theo các chuẩn này thì các hệ thống framework khác nhau vẫn sẽ dùng chung một quy tắc, do đó sẽ thuận lợi cho việc phát triển sau này.
Thông tin chính thức và chuẩn mực về PSR các bạn có thể tìm thấy tại trang chủ của PSR http://www.php-fig.org/.
PSR4 là gì? PSR-4: Tiêu chuẩn viết Autoloader trong PHP.
Tiêu chuẩn kỹ thuật viết các lớp tự động nạp vào khi cần sử dụng đến. Các lớp có thể được load tự động khi dùng đến bằng cách sử dụng cơ chế autoload của PHP (http://php.net/autoload). Ví dụ: Tự đông load các lớp MyClass1 và MyClass2 từ các tệp MyClass1.php và MyClass2.php.
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
Lời kết
Hết rồi
All rights reserved