2009-04-04 29 views
56

Có một số bài viết về vấn đề này, nhưng tôi đã không nhận được rõ ràng khi sử dụng mã hóa hướng đối tượng và khi nào sử dụng các hàm lập trình trong một bao gồm. Ai đó cũng đã đề cập với tôi rằng OOP rất nặng để chạy, và tạo ra nhiều khối lượng công việc hơn. Thê nay đung không?Tại sao sử dụng PHP OOP trên các chức năng cơ bản và khi nào?

Giả sử tôi có một tệp lớn với 50 chức năng. Tại sao tôi muốn gọi những thứ này trong một lớp học? Và không phải bởi function_name()? Tôi có nên chuyển đổi và tạo một đối tượng chứa tất cả các chức năng của tôi không? Điều gì sẽ là lợi thế hoặc sự khác biệt cụ thể? Những lợi ích gì mà nó mang lại để mã OOP trong PHP? Modularity?

+1

Tôi đã viết một bài đăng trên blog cách đây một thời gian có thể giúp bạn hiểu sự khác biệt: [Thủ tục so với OOP Explained] (http://www.virtuosimedia.com/tutorials/procedural-vs-oop-explained) – VirtuosiMedia

Trả lời

40

Trong nhiều trường hợp, lập trình thủ tục chỉ là tốt.Sử dụng OO vì lợi ích của việc sử dụng nó là vô ích, đặc biệt nếu bạn chỉ muốn kết thúc với các đối tượng POD (dữ liệu thuần cũ).

Sức mạnh của OO chủ yếu đến từ thừa kế và đa hình. Nếu bạn sử dụng các lớp, nhưng không bao giờ sử dụng một trong hai khái niệm đó, bạn có thể không cần phải sử dụng một lớp ở nơi đầu tiên.

Một trong những nơi đẹp nhất IMO mà OO tỏa sáng, cho phép bạn loại bỏ mã chuyển đổi. Xem xét:

function drive($the_car){ 

    switch($the_car){ 

     case 'ferrari': 
      $all_cars->run_ferrari_code(); 
      break; 

     case 'mazerati': 
      $all_cars->run_mazerati_code(); 
      break; 

     case 'bentley': 
      $all_cars->run_bentley_code(); 
      break; 
    } 
} 

với thay thế OO của nó:

function drive($the_car){ 

    $the_car->drive(); 
} 

Polymorphism sẽ cho phép loại thích hợp của "lái xe" xảy ra, dựa trên thông tin thời gian chạy.


Ghi chú về đa hình:

Ví dụ thứ hai ở đây có một số tiền đề: Đó là tất cả các lớp học xe hoặc sẽ mở rộng một lớp abstract hoặc thực hiện một interface.

Cả hai đều cho phép bạn buộc mở rộng hoặc triển khai các lớp học để xác định một chức năng cụ thể, chẳng hạn như drive(). Điều này là rất mạnh mẽ vì nó cho phép bạn drive() tất cả các xe mà không cần phải biết bạn đang lái xe nào; đó là vì chúng đang mở rộng một lớp trừu tượng có chứa phương thức drive() hoặc triển khai giao diện buộc phương thức drive() được xác định.

Vì vậy, miễn là bạn chắc chắn rằng tất cả các xe cụ thể của bạn, hoặc mở rộng các lớp trừu tượng car hoặc thực hiện một giao diện như canBeDriven (cả hai đều phải tuyên bố phương pháp drive()) bạn chỉ có thể gọi phương thức drive() trên đối tượng mà bạn biết là một chiếc xe (nhưng không phải loại xe) mà không sợ nó không được xác định, vì PHP sẽ ném các lỗi nghiêm trọng vào bạn cho đến khi bạn xác định các phương pháp đó trong các lớp xe cụ thể của bạn.

+10

không hoàn toàn có được ví dụ thay thế của bạn. – Codex73

+2

nếu bạn sử dụng OOP thích hợp, thì $ the_car có thể trỏ vào bất kỳ loại xe nào. Bởi vì tất cả các loại xe khác nhau đều có phương thức drive() trong đó, bạn có thể an toàn chỉ cần gọi nó, bất kể loại xe nào. Khi chạy, nó biết loại xe đó là gì, và nó tự động gọi là loại xe nào. –

+10

chỉ cần đi qua điều này và không nhận được ví dụ thay thế hoặc. Bạn chỉ cần truyền một đối tượng vào một hàm và gọi drive(). Đoán bạn xác định đối tượng trong quá trình instantiation nhưng nó không được hiển thị?Điều này có ý nghĩa hơn như một ví dụ OOP $ car_object = new carClass ("$ the_car"); sau đó chỉ cần chạy $ car_object-> drive(); – Taylor

2

Nếu bạn có 50 hàm thay vì 50 phương thức tĩnh vào lớp Tiện ích, bạn "gây ô nhiễm" không gian tên chung.

Sử dụng lớp có 50 phương pháp tĩnh, tên phương thức là địa phương cho lớp học của bạn.

+0

5.3 có không gian tên ... –

+0

Đồng ý! Nhưng Codex không đề cập đến phiên bản nào anh ta đang sử dụng. Cá nhân, tôi vẫn còn với 5.2.6 –

+2

Đó không phải là một đối số ủng hộ lập trình hướng đối tượng thực tế, đó là câu hỏi này là gì; thay vào đó, điều này liên quan đến mô hình được sử dụng của việc sử dụng các lớp để không gian tên các phương thức miễn phí khác. – Rob

12

Sử dụng phương pháp lập trình hướng đối tượng thay vì phương pháp lập trình thủ tục trong chương trình không thực sự phụ thuộc vào ngôn ngữ (có thể là PHP hay không), nhưng về loại sự cố bạn đang cố giải quyết.

(Tôi chỉ sẽ sử dụng mã giả trong các ví dụ của tôi như tôi không quá quen thuộc với PHP.)

Ví dụ, nếu bạn có một chương trình mà bạn chỉ thực hiện một loạt các chức năng theo thứ tự, thì thủ tục sẽ ổn thôi. Ví dụ, nếu đó là một chương trình chuỗi thao tác đơn giản, một cách tiếp cận thủ tục sẽ đủ:

perform_truncation(my_string, 10) 
to_upper(my_string) 
perform_magic(my_string, hat, rabbit) 

Tuy nhiên, nếu bạn đang đi để đối phó với nhiều mặt hàng khác nhau (chẳng hạn như các file, hoặc bất kỳ đại diện khác, tốt, các đối tượng) thì cách tiếp cận hướng đối tượng sẽ tốt hơn.

Ví dụ, nếu bạn đã có một loạt các Car s và muốn họ drive, sau đó trong thủ tục, bạn có thể làm điều gì đó dọc theo dòng:

drive_car(first_car) 
drive_car(second_car) 

Trong trường hợp như, trong OOP, các Car lon tự lái xe:

RedCar myRedCar(); 
BlueCar myBlueCar(); 

myRedCar.drive(); 
myBlueCar.drive(); 

Và vì mỗi chiếc xe là một lớp khác nhau, hành vi của chúng có thể được xác định khác nhau. Hơn nữa, chúng có thể là cả hai lớp con hoặc Car chúng có thể có chức năng chung.

Nó thực sự đi xuống đến loại vấn đề mà làm cho một trong hai cách tiếp cận thủ tục tốt hơn so với hướng đối tượng và ngược lại.

Ngoài vấn đề về thủ tục hoặc hướng đối tượng, nó có thể là một loại "mã ngửi" để có một tệp nguồn với nhiều chức năng. Điều này cũng có thể nói về các lớp có chứa nhiều chức năng có thể được thực hiện tốt hơn như các hàm riêng biệt trong các lớp riêng biệt.

Sự cố ở đây có thể là tổ chức mã thay vì quyết định chọn lập trình thủ tục hoặc hướng đối tượng. Việc tổ chức các hàm thành các tệp nguồn riêng biệt có thể là những gì cần thiết ở đây hơn là từ bỏ phương thức thủ tục để viết chương trình.

Sau khi tất cả, có rất nhiều chương trình được viết bằng phương pháp lập trình thủ tục được viết tốt và dễ bảo trì.

2

Tôi không thể nói cái nào tốt hơn. nhưng theo kinh nghiệm của tôi, bạn có thể quản lý mã tốt hơn bằng OOP. bạn biết mã nào là ở đâu, chức năng nào được định nghĩa trong tập tin, vv về chi phí thời gian chạy cho OOP Tôi đọc ở đâu đó (và tôi nghĩ điều đó đúng) là nếu bạn viết mã xấu trong các chức năng cổ điển và trong OOP, phiên bản chức năng hoạt động tốt hơn. vì vậy nếu mã của bạn không được viết xấu, không có bằng chứng cho thấy OOP đang giữ ứng dụng của bạn chậm. cũng nhớ rằng những thứ "chậm" và "trên cao" này đều được tính bằng mili giây. vì vậy nếu ứng dụng của bạn không phục vụ nhiều người dùng (như hơn 100 người dùng trong một phút), bạn có thể không cảm thấy bất kỳ sự khác biệt nào.

12

Tôi sẽ cố gắng giữ cho câu trả lời của tôi như một sự bổ sung vì câu trả lời của Majd Taby và Coobird thực sự tốt. Tôi đã hầu như là một lập trình viên thủ tục trong nhiều năm và không chiến đấu chống lại lập trình OOP, nhưng không bao giờ thực sự thấy sự liên quan ... cho đến khi tôi bắt đầu làm việc cho một nhóm và xây dựng các dự án quan trọng và phức tạp hơn.

OOP thực sự tỏa sáng, theo ý kiến ​​của tôi, khi bạn cần viết mã gọn gàng, dễ bảo trì cho các ứng dụng phức tạp hơn. Và tâm trí bạn, không phải trong mọi tình huống, nhưng có một số nơi mà thủ tục sẽ không hoạt động tốt.

Hầu hết các ví dụ về triển khai OOP tuyệt vời của tôi là dành cho các dự án mà tôi có nhiều thứ liên quan nhưng tất cả đều hơi khác nhau. Các trang web có nhiều biểu mẫu, nhiều người dùng, nhiều sản phẩm, v.v.

Tất cả đều có tên hành vi tương tự như print(), update(), v.v ... nhưng bằng cách đóng gói chúng làm đối tượng và thay đổi triển khai phương pháp trong các lớp, tôi có thể làm cho mã của tôi trong thời gian chạy rất đơn giản và sạch sẽ trong toàn bộ trang web. Ngoài ra, và điều này là quan trọng, mặc dù có hành vi khác nhau, tôi có thể làm việc với các đối tượng khác nhau bằng cách sử dụng cùng một cuộc gọi phương thức trong toàn bộ ứng dụng. Nó cho phép một nhà phát triển thứ hai làm việc trên thực tế thực tế trong khi tôi làm việc trên mã sâu hơn.

Tôi không biết liệu điều đó có giúp được gì ngoài việc nói chuyện với ai đó trong tình huống của bạn cách đây không lâu, tôi yêu OOP.

2

OOP cho phép bạn tạo các thùng chứa mã có cấu trúc, được gọi là các lớp, có thể là cha mẹ/con của nhau. Điều này có thể giúp xây dựng một ứng dụng vì nó dễ dàng hơn để duy trì và có thể, nếu được thực hiện đúng cách giảm sự dư thừa mã. OOP không thêm một chút chi phí nhưng nó không thực sự đáng chú ý và được nhiều hơn bởi sự unmaintainablity của mã thủ tục. Nếu bạn viết một ứng dụng lớn, hãy xóa OO, đặc biệt là nếu nó được nhiều người làm việc.

Ví dụ: giả sử bạn đang thiết kế một trang web đơn giản. Bạn có thể tạo một đối tượng Trang. Đối tượng trang có trách nhiệm truy cập cơ sở dữ liệu và nhận các cài đặt khác nhau cho trang, chẳng hạn như dữ liệu meta, thẻ tiêu đề hoặc thậm chí số lượng "thành phần" nhất định trên trang và loại của chúng (chẳng hạn như điều khiển lịch) , v.v.)

Sau đó, bạn có thể tạo một lớp khác, nói rằng chỉ mục, mở rộng Trang. Chỉ mục sẽ là chỉ mục hoặc trang chủ. Nếu bạn có một danh mục sản phẩm, bạn có thể mở rộng trang Catalog. Vì cả phần danh mục và trang chủ của bạn cần lấy dữ liệu từ cơ sở dữ liệu liên quan đến siêu dữ liệu của trang và xây dựng cơ bản của trang, có 1 đối tượng đã làm cho bạn đã giúp. Trong cả hai tình huống này, trang thực hiện tất cả công việc và lấy dữ liệu trang từ cơ sở dữ liệu, tải nó vào các biến, sau đó có thể truy cập được trong cả lớp chỉ mục của bạn và lớp danh mục của bạn. Bạn không cần phải viết mã để đi vào cơ sở dữ liệu và lấy lại nó trong mỗi trang bạn viết.

Bây giờ có nhiều cách khác để thực hiện việc này theo cách thủ tục, chẳng hạn như bao gồm. Tuy nhiên, bạn sẽ thấy mình làm ít sai sót và lỗi hơn. Ví dụ, bạn có thể định nghĩa một phương thức trừu tượng trong lớp Page của bạn. Điều này có nghĩa là phương thức này PHẢI được định nghĩa trong bất kỳ đối tượng nào mở rộng nó. Vì vậy, nói rằng bạn đã tạo một hàm setPageAttributes() làm trừu tượng trong lớp Page của bạn. Khi bạn làm điều này, bạn tạo ra một hàm rỗng. Khi bạn tạo lớp chỉ mục, bạn phải tạo một hàm setPageAttributes() (với ý định điền vào nó, chẳng hạn như truy cập các biến được định nghĩa trong lớp Page và sử dụng nó để đặt các phần tử thực tế trên trang, mẫu hoặc xem bạn đang sử dụng) hoặc bạn gặp lỗi PHP.

Nếu bạn đang làm việc với những người khác để có được dự án của bạn bằng văn bản, phương pháp trừu tượng sẽ nói với người đó, "Này, bạn cần phải xác định các chức năng này trong bất kỳ mã nào bạn viết". Điều này buộc ứng dụng phải nhất quán.

Cuối cùng, bạn không thể chuyển sang các khung công tác như định dạng MVC nếu bạn không thực hiện OOP. Mặc dù không cần đến MVC và có một số tranh luận, nó tách biệt tất cả các thành phần của ứng dụng và cần thiết trong môi trường mà nhiều người (nhà thiết kế, lập trình viên, nhân viên tiếp thị) làm việc trên cùng một mã.

4

phép nói rằng tôi có một tập tin lớn với 50 chức năng, tại sao tôi sẽ muốn gọi này trong một lớp học?và không phải bởi function_name(). Tôi có nên chuyển đổi và tạo đối tượng chứa tất cả các chức năng của tôi không?

Di chuyển đến OOP không được xem là một 'chuyển đổi' đơn giản theo cách bạn mô tả ở trên.

OOP yêu cầu cách suy nghĩ hoàn toàn khác về lập trình liên quan đến việc lặp lại bộ não của bạn. Như việc hồi âm một bộ não không xảy ra qua đêm nhiều người không muốn phơi bày bản thân với quá trình lặp lại yêu cầu. Thật không may việc rewiring sẽ mất một sự đầu tư về thời gian và công sức: nghiên cứu, hướng dẫn, thử và sai.

Nó thực sự liên quan đến việc lùi lại một bước và tìm hiểu về các khái niệm đằng sau OOP nhưng hoàn vốn sẽ rất đáng để nói như một người đã trải qua quá trình này trong các ngày trước www.

Sau khi bạn 'nhận được' và thực hiện theo các phương pháp hay nhất OOP hàng ngày, bạn sẽ nói cho người khác biết cuộc sống lập trình của bạn đã thay đổi tốt hơn như thế nào.

Khi bạn thực sự hiểu OOP, bạn sẽ trả lời câu hỏi của riêng bạn.

+0

OOP chỉ là một trong những cách để viết MVC không sử dụng oop và được coi là điều tốt hơn nhiều –

0

Câu trả lời được chấp nhận dường như đã bị lãng quên để nói rằng chúng ta có thể gọi chức năng dựa trên một tên biến như trong ví dụ herew:

function drive($the_car){ 
    $the_car(); 
} 

Phải thừa nhận rằng có sẽ cần phải là một chức năng cho mỗi xe trong trường hợp này nhưng hiệu quả hơn rất nhiều so với câu lệnh chuyển đổi được đề xuất.


biến bổ sung có thể được cung cấp một cách dễ dàng như vậy:

function operate($the_car,$action){ 
    $the_car($action); 
} 

function ferrari($action){ 
    switch($action){ 
     case 'drive': 
      echo 'Driving'; 
      break; 

     case 'stop': 
      echo 'Stopped'; 
      break; 

     default: return; 
    } 
} 


operate('ferrari','drive'); 

Có một câu lệnh switch ở đây nhưng nó cung cấp các chức năng bổ sung mà không phải là trong ví dụ ban đầu do đó, nó không có cách nào một mâu thuẫn.

-1

Khái niệm OOP được sử dụng trong PHP, để đảm bảo mã. Vì tất cả các truy vấn được viết trong tệp chức năng thay vì tệp mã nên không ai có thể dễ dàng tấn công mã của chúng tôi. Vì vậy, tốt hơn là sử dụng các lớp trong PHP thay vì viết trực tiếp các truy vấn.

Các vấn đề liên quan