Những điều bạn có thể chưa biết về lập trình hướng đối tượng trong PHP

Ngoài kiến thức cơ bản và sự kế thừa trong hướng đối tượng ở môn ngôn ngữ lập trình PHP thì bài viết này đưa tới cho bạn đọc những góc cạnh riêng biệt buộc lập trình viên phải tuân thủ khi làm việc theo mô hình nhóm.

Ghi chú mã lệnh với DocBlocks

Tuy là một phần không chính thức của Lập Trình Hướng Đối Tượng, nhưng các kiểu mẫu DocBlock comment được chấp nhận rộng rãi như một phương pháp chú thích trong các class. Ngoài việc cung cấp một chuẩn comment cho các lập trình viên sử dụng khi lập trình, nó còn được sự chấp thuận và hỗ trợ bởi nhiều nhà phát triển công cụ hỗ trợ lập trình phổ biến như Eclipse và NetBeans, và sẽ được sử dụng để tạo ra các đoạn code hint (gợi ý mã lệnh).

Chúng ta sử dụng block comment để định nghĩa một DocBlock:

<?php 
/** 
 * This is a very basic DocBlock 
 */  
?>

Sức mạnh thật sự của DocBlocks đi kèm với khả năng sử dụng các tags, được bắt đầu với một ký tự @, tiếp theo sau đó là tên tag và giá trị của tag.DocBlock tags cho phép các lập trình viên định nghĩa tác giả của một file, bản quyền cho một class, thông tin của một phương thức hay thuộc tính, và các thông tin hữu ích khác.

 Dưới đây là các tag được sử dụng phổ biến nhất:
  • @author:Tác giả của phần tử hiện hành (có thể là một class, file, phương thức, hoặc bất ký thành phần nào của mã lệnh) đều được liệt vào nhóm sử dụng tag này. Có thể sử dụng nhiều hơn 1 tag author trong cùng 1 DocBlock nếu có nhiều hơn một tác giả cần khai báo. Định dạng cho tên author thường như sau: John Doe <john.doe@email.com>.
  • @copyright:tag này nói lên giá trị năm và tên của người dữ bản quyền cho phần tử hiện hành. Định dạng như sau: 2010 Copyright Holder.
  • @license:tag này liên kết đến các giấy phép cho phần tử hiện hành. Định dạng cho thông tin license như sau:
  • http://www.example.com/path/to/license.txt License Name.
  • @var:tag này giữ kiểu và mô ta của một biến hoặc một thuộc tính class. Định dạng như sau: type element description.
  • @param:tag này hiển thị kiểu và miêu tả tham số của một hàm hoặc một phương thức. Định dạng như sau: type $element_name element description.
  • @return:tag này là kiểu và mô tả giá trị trả về của một hàm hoặc một phương thức. Định dạng như sau: type return element description.
<?php 

/** 
 * A simple class 
 * 
 * This is the long description for this class, 
 * which can span as many lines as needed. It is 
 * not required, whereas the short description is 
 * necessary. 
 * 
 * It can also span multiple paragraphs if the 
 * description merits that much verbiage. 
 * 
 * @author Jason Lengstorf <jason.lengstorf@ennuidesign.com> 
 * @copyright 2010 Ennui Design 
 * @license http://www.php.net/license/3_01.txt PHP License 3.01 
 */ 
class SimpleClass 
{ 
    /** 
     * A public variable 
     * 
     * @var string stores data for the class 
     */ 
    public $foo; 

    /** 
     * Sets $foo to a new value upon class instantiation 
     * 
     * @param string $val a value required for the class 
     * @return void 
     */ 
    public function __construct($val) 
    { 
        $this->foo = $val; 
    } 

    /** 
     * Multiplies two integers 
     * 
     * Accepts a pair of integers and returns the 
     * product of the two. 
     * 
     * @param int $bat a number to be multiplied 
     * @param int $baz a number to be multiplied 
     * @return int the product of the two parameters 
     */ 
    public function bar($bat, $baz) 
    { 
        return $bat * $baz; 
    } 
} 

?>
Khi nhìn vào đoạn mã trên, rõ ràng những người phát triển chúng sau bạn sẽ dễ dàng tìm hiểu và làm quen với chúng một cách nhanh chóng hơn rất nhiều. Ngoài ra, với sự hỗ trợ của các IDE, các DocBlock comment càng được tận dụng triệt để một cách hết sức có lợi cho lập trình viên.
So sánh Hướng Đối Tượng và Hướng Thủ Tục

Với hai khái niệm này, không thực sự có khái niệm cách viết nào đúng, cách viết nào sai. Do đó,phần này sẽ chủ yếu trình bày lý lẽ thiên về công dụng của việc áp dụng Hướng Đối Tượng trong phát triển phần mềm, đặc biệt là trong các ứng dụng lớn.

Lý do 1: Dễ thực thi

Tuy rằng có thể khá khó khăn trong việc tiếp cận ban đầu, nhưng Lập Trình Hướng Đối Tượng thực sự cung cấp một phương pháp tiếp cận dễ dàng hơn để xử lý dữ liệu. Bởi vì một object có thể lưu trữ dữ liệu nội bộ, các biến mà không cần phải thông qua các hàm để có thể hoạt động đúng chức năng.

Ngoài ra, vì có nhiều trường hợp sử dụng cùng một class tại cùng một thời điểm, do đó việc xử lý dữ liệu lớn trở nên dễ dàng hơn rất nhiều. Cho ví dụ, bạn hãy tưởng tượng bạn có thông tin hai người đang được xử lý trong một file. Họ cần tên, nghệ nghiệp, và tuổi tác.

Đối với Lập Trình Hướng Thủ Tục

Dưới đây áp dụng lập trình hướng thủ tục cho ví dụ của chúng ta:

<?php 

function changeJob($person, $newjob) 
{ 
    $person['job'] = $newjob; // Change the person's job 
    return $person; 
} 

function happyBirthday($person) 
{ 
    ++$person['age']; // Add 1 to the person's age 
    return $person; 
} 

$person1 = array( 
    'name' => 'Tom', 
    'job' => 'Button-Pusher', 
    'age' => 34 
); 

$person2 = array( 
    'name' => 'John', 
    'job' => 'Lever-Puller', 
    'age' => 41 
); 

// Xuất giá trị khởi đầu của 2 người 
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; 
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; 

// Tom nhận được việc mới và thêm 1 tuổi 
$person1 = changeJob($person1, 'Box-Mover'); 
$person1 = happyBirthday($person1); 

// John chỉ thêm 1 tuổi 
$person2 = happyBirthday($person2); 

// Xuất giá trị mới của 2 người 
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; 
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; 

?>

Khi thực thi, mã lệnh sẽ xuất ra như sau:

Person 1: Array 
( 
         [name] => Tom 
         [job] => Button-Pusher 
         [age] => 34 
) 
Person 2: Array 
( 
          [name] => John 
          [job] => Lever-Puller 
          [age] => 41 
) 
Person 1: Array 
( 
          [name] => Tom 
          [job] => Box-Mover 
          [age] => 35 
) 
Person 2: Array 
( 
          [name] => John 
          [job] => Lever-Puller 
          [age] => 42 
)

Mặc dù đoạn mã trên không phải là tệ, nhưng chúng ta vẫn phải chú ý đến nhiều vấn đề.Các giá trị của mảng trên sẽ được xử lý và trả về từ mỗi hàm riêng lẻ, do vậy dễ phát sinh lỗi.

Để giải quyết vấn đề này, chúng ta phải tối ưu việc sử dụng càng ít mã lệnh cho lập trình viên càng tốt. Chỉ những thông tin thật sự cần thiết cho các thao tác hiện hành mới nên đưa vào xử lý trong các hàm.

Đây chính là lúc Lập Trình Hướng Đối Tượng giúp đỡ bạn giải quyết vấn đề.

Áp Dụng Lập Trình Hướng Đối Tượng

Dưới đây áp dụng lập trình hướng đối tượng cho ví dụ của chúng ta:

<?php 

class Person 
{ 
    private $_name; 
    private $_job; 
    private $_age; 

    public function __construct($name, $job, $age) 
    { 
        $this->_name = $name; 
        $this->_job = $job; 
        $this->_age = $age; 
    } 

    public function changeJob($newjob) 
    { 
        $this->_job = $newjob; 
    } 

    public function happyBirthday() 
    { 
        ++$this->_age; 
    } 
} 

// Tạo 2 người 
$person1 = new Person("Tom", "Button-Pusher", 34); 
$person2 = new Person("John", "Lever Puller", 41); 

// Xuất ra thông tin đầu tiên của 2 người 
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; 
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; 

// Cho Tom 1 công việc mới và tăng thêm 1 tuổi 
$person1->changeJob("Box-Mover"); 
$person1->happyBirthday(); 

// John chỉ được tăng thêm 1 tuổi 
$person2->happyBirthday(); 

// Xuất ra giá trị cuối cùng (sau khi đã xử lý) của 2 người 
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>"; 
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>"; 

?>

Kết quả xuất ra trên trình duyệt như sau:

Person 1: Person Object
(
    [_name:private] => Tom
    [_job:private] => Button-Pusher
    [_age:private] => 34
)
Person 2: Person Object
(
    [_name:private] => John
    [_job:private] => Lever Puller
    [_age:private] => 41
)
Person 1: Person Object
(
    [_name:private] => Tom
    [_job:private] => Box-Mover
    [_age:private] => 35
)
Person 2: Person Object
(
    [_name:private] => John
    [_job:private] => Lever Puller
    [_age:private] => 42
)

Mặc dù có 1 chút rườm rà ở khâu thiết lặp để tiếp cận Hướng Đối Tượng, nhưng sau khi class được định nghĩa, thì việc tạo và tùy chỉnh people trở nên nhanh gọn hơn rất nhiều;thông tin chi tiết của từng người không cần truyền đến hoặc trả về từ nhiều phương thức, mà chỉ những thông tin thực sự cần thiết được truyền đến cho từng phương thức.

Trên quy mô nhỏ, sự khác biệt này có thể sẽ không nhiều, nhưng nếu như ứng dụng của bạn ngày càng phát triển lớn hơn, Lập Trình Hướng Đối Tượng sẽ giúp giảm đáng kể khối lượng công việc của bạn, nếu nó được thực thi đúng.

Chú ý: Không phải mọi thứ đều cần Hướng Đối Tượng. Một hàm xử lý vài thứ nhỏ trong ứng dụng thì không cần thiết phải đưa vào trong một class. Vận dụng khả năng phân tích, nhìn nhận vấn đề của bạn để quyết định giữa Hướng Đối Tượng và Hướng Thủ Tục.

Lý Do 2: Có tổ chức tốt hơn

Một lợi ích khác của Hướng Đối Tượng là khả năng dễ dàng đóng gói và phân loại. Mỗi class nói chung có thể được giữ trong 1 tập tin riêng biệt của chính nó, và nếu một quy ước đặt tên thông nhất được sử dụng, việc truy cập vào các class sẽ vô cùng đơn giản.

Giả sử bạn có một ứng dụng với 150 class, các class này sẽ được gọi 1 cách tự động thông qua 1 file controller đặt tại thư mục gốc của ứng dụng. Toàn bộ 150 class đều được đặt tên theo quy ướcclass.classname.inc.php và cư trú tại thư mục cin của ứng dụng.

Controller có thể thực thi hàm__autoload()để tự động triệu gọi các class cần thiết, chứ không include toàn bộ 150 class vào trong file controller:

<?php 
    function __autoload($class_name) 
    { 
        include_once 'inc/class.' . $class_name . '.inc.php'; 
    } 
?>

Mỗi class đươc đặt tại 1 file riêng biệt đã làm mã lệnh trở nên di động hơn và dễ dàng để tái sử dụng hơn trong các ứng dụng mới.

Lý Do 3: Dễ bảo trì

Do cấu trúc mã lệnh tuy liên kết chặt chẽ nhưng vẫn tách biệt và rời rạc thành từng phần nênsự thay đổi mã lệnh trong lập trình Hướng Đối Tượng thường dễ dàng hơn là trong lập trình Hướng Thủ Tục.

Nếu một mảng thông tin cụ thể nào đó nhận được một giá trị mới, một phần thủ tục của phần mềm có thể sẽ yêu cầu (trong trường hợp xấu nhất) thêm thuộc tính mới này vào trong từng hàm xử lý cái mảng này.

Nếu ứng dụng của bạn là một ứng dụng Hướng Đối Tượng, điều này sẽ dễ dàng thực hiện hơn như: thêm thuộc tính mới, sau đó thêm các phương thức xử lý các thuộc tính đó.

Tổng Kết

Nếu đọc đến đây, có lẽ bạn đã bắt đầu cảm thấy thoải mái với tác phong Lập Trình Hướng Đối Tượng. Học Hướng Đối Tượng là một cách tuyệt vời để nâng cao trình độ lập trình của bạn. Khi thực thi đúng, Hướng Đối Tượng sẽ giúp bạn tạo ra những mã lệnh dễ đọc, dễ bảo trì và mang tính di động cao, giúp cho bạn tiết kiệm được rất nhiều thời gian làm việc.