Khi nào chúng ta thực sự sử dụng lập trình hướng đối tượng? [đóng cửa]


35

Tôi đang viết một chương trình bằng Python, về cơ bản điều khiển các chuỗi và tôi đã tự hỏi liệu tôi có nên làm điều đó bằng cách sử dụng các nguyên tắc OOP hay không. Khách hàng nói với tôi rằng anh ta không quan tâm đến mã, anh ta chỉ muốn việc đó được thực hiện .

Tôi biết rằng mã hướng đối tượng không theo định nghĩa sạch hơn và ngược lại, mã không OO không theo định nghĩa crappy. Câu hỏi tôi đang hỏi có thể ít nhiều dựa trên ý kiến ​​nhưng có thể có một số quy tắc mà tôi không biết.

Một số thông tin thêm về những gì sẽ được thực hiện:

  • phân tích một .csvtệp và xử lý dữ liệu dựa trên tệp cấu hình (các cột có thể khác nhau - như về số lượng cột hoặc dữ liệu họ giữ)
  • sử dụng dữ liệu đã xử lý ở trên để tạo dữ liệu được định dạng tùy chỉnh mới (hoặc nhiều tệp dựa trên một số giá trị ở trên)
  • sử dụng dữ liệu được định dạng cuối cùng để tạo tệp XML.
  • chia tệp XML thành nhiều phần XMLdựa trên nội dung của chúng
  • ứng dụng nên dựa trên CLI
  • tất nhiên có những thứ khác như: ghi nhật ký một số sự kiện, phân tích các đối số CLI, v.v.

Bây giờ, đây hoàn toàn không phải là một ứng dụng lớn / cứng và nó cũng sắp hoàn thành nhưng trong toàn bộ quá trình phát triển, tôi đã tự hỏi liệu điều này có nên được thực hiện bằng OOP hay không.

Vì vậy, câu hỏi của tôi sẽ là: làm thế nào để các bạn, biết / quyết định khi nào nên sử dụng OOP trong một ứng dụng?


12
Re, "Khách hàng ... không quan tâm đến mã, anh ta chỉ muốn mọi thứ được thực hiện." OK, sau đó làm điều. Nhưng điều này phức tạp đến mức nào? Làm thế nào để bạn thực sự hiểu các yêu cầu? Làm thế nào có khả năng khách hàng sau đó sẽ yêu cầu bạn thay đổi điều này? Đôi khi, một bản hack nhanh và bẩn là tất cả những gì bạn cần, nhưng bạn càng đầu tư nhiều thời gian và sức lực vào nó, thì một cách tiếp cận có cấu trúc để giải quyết vấn đề (ví dụ, thiết kế OO) sẽ có lợi cho bạn.
Solomon chậm

5
Không sử dụng "EDIT" hoặc các biệt danh tương tự khác trong bài viết của bạn. Mỗi bài đăng Stack Stack có một lịch sử chỉnh sửa chi tiết mà bất cứ ai cũng có thể xem lại. Thông tin như "Tôi không hỏi OOP là gì" thích hợp hơn trong một bình luận, không phải câu hỏi của bạn.
Robert Harvey

@RobertHarvey ok, hiểu rồi. Tôi sẽ làm điều này vào lần tới.
Grajdeanu Alex.

Câu trả lời:


60

Python là một ngôn ngữ đa mô hình, có nghĩa là bạn có thể chọn mô hình phù hợp nhất cho nhiệm vụ. Một số ngôn ngữ như Java là mô hình đơn OO, điều đó có nghĩa là bạn sẽ bị đau đầu nếu bạn cố gắng sử dụng bất kỳ mô hình nào khác. Những áp phích có nội dung "luôn luôn sử dụng OO" có lẽ đến từ một nền tảng trong ngôn ngữ như vậy. Nhưng may mắn thay, bạn có một sự lựa chọn!

Tôi lưu ý rằng chương trình của bạn là một ứng dụng CLI đọc một số đầu vào (tệp csv và cấu hình) và tạo ra một số đầu ra (tệp xml), nhưng không tương tác và do đó không có GUI hoặc API trạng thái. Một chương trình như vậy được biểu diễn một cách tự nhiên như một hàm từ đầu vào đến đầu ra, ủy nhiệm cho các chức năng khác cho các nhiệm vụ.

Mặt khác, OO là về việc đóng gói trạng thái có thể thay đổi và do đó thích hợp hơn cho các ứng dụng tương tác, GUI và trạng thái có thể thay đổi của API. Không phải ngẫu nhiên mà OO được phát triển song song với GUI đầu tiên.

OO có một lợi thế khác là tính đa hình cho phép bạn có một kiến ​​trúc ghép lỏng lẻo hơn, trong đó các triển khai khác nhau của cùng một giao diện có thể dễ dàng được thay thế. Kết hợp với tiêm phụ thuộc, điều này có thể cho phép tải phụ thuộc dựa trên cấu hình và các nội dung thú vị khác. Điều này chủ yếu là thích hợp cho các ứng dụng rất lớn mặc dù. Đối với một chương trình có kích thước của những gì bạn mô tả, nó sẽ vượt xa nhiều chi phí mà không có lợi ích rõ ràng.

Ngoài các chức năng thực sự đọc và ghi các tệp, phần lớn logic của bạn có thể được viết dưới dạng các hàm miễn phí hiệu ứng phụ có một số đầu vào và trả về một số đầu ra khác. Điều này cực kỳ dễ kiểm tra, đơn giản hơn nhiều so với kiểm tra các đơn vị OO nơi bạn cần chế nhạo các phụ thuộc và không có gì.

Dòng dưới cùng: Tôi đề xuất một loạt các hàm được chia thành các mô-đun cho tổ chức, nhưng không có đối tượng.


8
Cuối cùng, một câu trả lời cân bằng không chỉ dành lời khen ngợi cho OOP :-)
cmaster

1
Đó là loại câu trả lời tôi mong đợi. Có thể mở rộng một chút câu trả lời của bạn? Nó trông tuyệt vời cho đến nay.
Grajdeanu Alex.

3
@ Dex'ter: Hơn bạn. Những loại thông tin bổ sung mà bạn tìm kiếm?
JacquesB

3
Tôi muốn nói thêm rằng Lập trình chức năng có thể là một mô hình để đọc tiếp.
Andrew nói Phục hồi lại

1
@Bergi: Vâng, đó là lợi ích của ngôn ngữ đa mô hình. Bạn có thể sử dụng các thư viện OO mà không phải viết chương trình của riêng bạn theo kiểu OO.
JacquesB

15

Hãy xem xét một nút trên GUI. Nó có trạng thái (kích thước, màu sắc, vị trí, nhãn, v.v.). Mọi thứ có thể xảy ra với nó (nó đã được nhấp, cần vẽ lại, v.v.). Trong những tình huống như vậy, mô hình hóa nó như một đối tượng có ý nghĩa. Là một đối tượng, nó có thể chứa trạng thái của nó, một tập hợp các hành động có thể được thực hiện trên nó (các phương thức) và nó có thể thông báo cho các phần khác của ứng dụng rằng mọi thứ đã xảy ra với nó bằng cách bắn các sự kiện.

OOP là một công cụ tuyệt vời để xử lý GUI và các tình huống khác trong đó các bộ phận của hệ thống có trạng thái không ổn định.

Các tình huống khác, chẳng hạn như tình huống bạn mô tả, trong đó dữ liệu được đọc từ nguồn, được xử lý và ghi ra đích được xử lý tốt bằng một cách tiếp cận khác: lập trình khai báo (hoặc hàm). Mã khai báo để xử lý dữ liệu có xu hướng dễ đọc và ngắn hơn các giải pháp OOP.

Giống như búa và cưa đều là những công cụ mạnh mẽ khi được sử dụng một cách chính xác, do đó, cũng là các kỹ thuật lập trình hướng đối tượng và khai báo. Bạn có thể có thể đóng đinh vào một miếng gỗ với tay cầm cưa. Tương tự như vậy, bạn có thể phá vỡ một mảnh gỗ làm đôi bằng búa. Tương tự như vậy, bạn có thể tạo một GUI chỉ với các chức năng và xử lý dữ liệu với các đối tượng. Khi các công cụ được sử dụng chính xác, kết quả sẽ sạch hơn và đơn giản hơn.

Nguyên tắc chung mà tôi sử dụng là nếu tôi có nhiều trạng thái, hoặc cần sự tương tác của người dùng, tôi sử dụng các đối tượng; mặt khác, tôi sử dụng các hàm (thuần túy và cao hơn, nếu có thể).


6

Lập trình hướng đối tượng thêm bốn công cụ mới vào kho vũ khí của bạn:

  1. Đóng gói
  2. Trừu tượng
  3. Di sản
  4. Đa hình

Bạn sẽ sử dụng OOP trong ứng dụng của mình khi nó đã phát triển đủ lớn và đủ phức tạp để hưởng lợi từ các công cụ này.


18
Trừu tượng hóa và đa hình là các công cụ được cung cấp bởi nhiều "định hướng" lập trình. OOP thực sự cung cấp một hình thức đóng gói yếu hơn so với các phương pháp khác bởi vì tính kế thừa khuyến khích các thiết kế trừu tượng bị rò rỉ. Điều duy nhất OOP thực sự bổ sung vào bộ công cụ là sự kế thừa, được xem là một điều xấu.
David Arno

4
@DavidArno: Về cơ bản bạn đang nói "Không bao giờ sử dụng OOP."
Robert Harvey

6
Đây là kết quả của một ngày cố gắng tại nơi làm việc để xem mã người khác, việc triển khai chương trình theo thủ tục thẳng tiến thường tốt hơn so với triển khai với hiểu biết kém về thiết kế OO. Kiến trúc OO có thể rất mạnh mẽ nhưng nên được sử dụng như một gia vị trong nấu ăn, với kiến ​​thức chuyên môn và số lượng vừa phải. Việc lạm dụng thiết kế OO cũng phổ biến như yêu cầu sốt cà chua trong một nhà hàng tồi.
Phill

6
Không có công cụ nào trong bốn công cụ (Đóng gói, Trừu tượng hóa, Kế thừa, Đa hình) là đặc trưng cho OOP. Có lẽ bạn nên giải thích OOP khác với các mô hình khác như thế nào với các chiều này.
Giorgio

4
@gardenhead cảm giác vượt trội kỳ lạ của bạn là không làm gì cho vị trí của bạn. Có lẽ bạn nên đặt ra một câu hỏi có tiêu đề 'Tại sao các ngôn ngữ dễ sử dụng nhất thường là OO?' Tốt hơn nữa, Ctrl + F và nhập 'GUI'.
Gusdor

1

Câu hỏi này có vẻ hơi khó hiểu với tôi. Nếu bạn đang viết nó bằng Python, bạn chắc chắn sẽ sử dụng các đối tượng. Khi bạn mở một tập tin, nó sẽ trả về một đối tượng. Khi bạn mang lại kết quả, nó sẽ trả về một đối tượng lặp. Mỗi chức năng bạn tạo là một đối tượng. Việc đặt câu hỏi về giá trị của OO trong các ứng dụng Python có vẻ kỳ lạ để nói rằng ít nhất.

Dựa trên các ý kiến ​​ở đây, vâng, Python hỗ trợ các mô hình chức năng nhưng chủ yếu dựa trên đối tượng. Bản thân ngôn ngữ và libs tích hợp được định hướng xung quanh các đối tượng. Có, nó hỗ trợ lambda (cũng như Java và bất kỳ số lượng langau khác thường được mô tả là OO) nhưng nó cố tình đơn giản so với một ngôn ngữ chức năng thực sự.

Có lẽ những khác biệt xung quanh thiết kế OO và thiết kế chức năng đang trở nên lỗi thời. Nếu tôi tạo lấy một hàm đa hình trên một đối tượng được thiết kế OO * và chuyển một con trỏ tới hàm đó trên một đối tượng làm tham số cho hàm được tạo kiểu chức năng *, đó có phải là OO không? Tôi nghĩ đó là cả hai và cũng là một cách tiếp cận thực sự hiệu quả để giải quyết vấn đề.

Tôi nghĩ câu hỏi thực sự là 'khi nào bạn nên bắt đầu thiết kế các lớp của riêng mình thay vì chỉ tạo một mô-đun với các hàm?' Tôi nghĩ rằng câu trả lời đúng cho điều đó là: khi nó giúp đơn giản hóa giải pháp. Tôi sẽ đưa ra cùng một câu trả lời cơ bản cho bất kỳ ngôn ngữ hướng đối tượng.

* dư thừa là có chủ ý: Tôi không muốn bị buộc tội ở đây vì cho rằng các đối tượng là OO hoặc các chức năng đó là chức năng.


5
yeah, các đối tượng không bằng OOP. có sự khác biệt giữa việc có một đối tượng và cấu trúc kiến ​​trúc của bạn xung quanh các đối tượng và các tương tác của chúng. đại loại như thế nào nếu bạn tạo một chức năng không có nghĩa là bạn đang lập trình chức năng.
sara

bạn hoàn toàn có thể dễ dàng coi đối tượng Python / JavaScript là Bản ghi, khá chức năng. Ngôn ngữ chức năng có đối tượng. Chìa khóa nằm trong từ thứ hai: định hướng. Các ngôn ngữ OOP được định hướng hoàn toàn xung quanh bằng cách sử dụng các đối tượng, trong khi một số ngôn ngữ khác chỉ có vẻ như chúng là một phần khác của hộp công cụ của bạn.
Dan Pantry

0

Một trong những điều lớn nhất về lập trình hướng đối tượng là thay vì suy luận về luồng chương trình, bạn bắt đầu suy luận về trạng thái.

Rất nhiều lần tôi nhìn thấy đối tượng, tôi thấy các phương thức nhưng điều tôi cũng thấy là ý nghĩ lái xe đằng sau mã là dòng chảy thay vì trạng thái.

Và một khi bạn suy luận về trạng thái, thật dễ dàng để xây dựng mã OOP tốt bởi vì ngay khi mã của bạn trở nên quá phức tạp, bạn nhận thấy rằng bạn không thể lý luận về trạng thái của mình nữa và biết rằng bạn cần phải cấu trúc lại.

Xem xét ví dụ của bạn: Bạn muốn phân tích tệp csv. Nó đến từ đâu: một tập tin trên đĩa. Bạn tải nó và đặt nó vào bộ nhớ và phân tích nó. Bây giờ khách hàng của bạn đến: hey tôi cũng muốn phân tích các tệp từ web. Vì vậy, bạn rất vui vì bạn đã tạo một giao diện đẹp để tải tệp của mình và chỉ phải tạo mã lấy nó từ web và phần còn lại của chương trình của bạn vẫn giữ nguyên.

Và điều tốt đẹp là: bạn có thể kiểm tra điều đó.


3
Ví dụ của bạn với việc đọc một tệp từ đĩa so với đọc một tệp từ web cũng có thể được thực hiện với các chức năng khác nhau. Bạn không cần OO cho điều đó.
JacquesB

0

Trong điều khoản của Giáo dân:

  • Bạn có thể sử dụng OOP hoặc không OOP trong bất kỳ loại dự án nào bạn muốn.
  • OOP không phải là thuốc chữa bách bệnh nhưng nó giúp quản lý sự phức tạp.
  • Nó vượt xa mô-đun, đó là về sự ngăn cách. Hãy nghĩ về các khoang khác nhau mà một con tàu có để giữ lại độ nổi nếu thân tàu bị hư hại.
  • OOP là một cách quản lý các phụ thuộc để các lỗi có thể dễ dàng theo dõi hơn vì chỉ có một tập hợp các cách xác định mà các thành phần khác nhau của chương trình có thể giao tiếp với nhau.
  • Trong một chương trình có nhiều thứ hoạt động: biến, hằng, phương thức, tệp, tham số, hàm, mô-đun, v.v ... Chúng có thể tương tác với nhau theo những cách đôi khi không thể đoán trước được. OOP là một tập hợp các nguyên tắc làm giảm số cách mà mọi thứ có thể tương tác với nhau. Bạn không bị buộc phải sử dụng OOP để làm điều đó, nhưng nó giúp.

Điều đó nói rằng, có những yếu tố khác cần tính đến:

  • Các lập trình viên của bạn có thành thạo OOP / OOD không?
  • Các lập trình viên của bạn có thành thạo một ngôn ngữ OOP không?
  • Bạn có nghĩ rằng phần mềm sẽ phát triển phức tạp theo thời gian?
  • Bạn có kế hoạch mở rộng hoặc tái sử dụng mã trong tương lai?
  • Bạn có nghĩ rằng "thiết kế" của bạn có thể trở thành một tài sản? tức là bạn sẽ có thể tận dụng nó để phát triển hay làm nền tảng cho các dự án trong tương lai?

Đừng hiểu lầm tôi: Bạn có thể đạt được tất cả những điều đó mà không cần sử dụng OOP nhưng với OOP thì mọi chuyện sẽ dễ dàng hơn.

Nhưng...

Nếu nhóm của bạn không thành thạo OOP / OOD và không có chuyên môn trong lĩnh vực đó, hãy đi với các tài nguyên bạn có.


-2

Vì vậy, câu hỏi của tôi sẽ là: làm thế nào để các bạn, biết / quyết định khi nào nên sử dụng OOP trong một ứng dụng?

Luôn luôn sử dụng nó. Khi bạn đã quen sử dụng nó, bạn sẽ sử dụng nó cho mọi thứ. Đó là một cách tuyệt vời để đảm bảo sự trừu tượng tốt giữa các khả năng và việc sử dụng chúng, đó là một lợi ích đáng kể để bảo trì. Chúng tôi sử dụng nó, ví dụ, cho

  • Các đối tượng cấu trúc dữ liệu nhỏ vì chúng thường rất đa hình, ví dụ và cấu trúc dữ liệu trung gian sau khi phân tích cú pháp một cái gì đó thường có nhiều thực thể nhỏ, có hành vi chung và cũng chuyên biệt. Đây là một trường hợp sử dụng tuyệt vời cho một lớp cơ sở hoặc giao diện chung, với các triển khai & hành vi chuyên biệt, tức là một hệ thống phân cấp lớp (đa hình).

  • đăng nhập, là một ví dụ, bởi vì nó giúp dễ dàng thay thế một logger khác

  • phần lớn cấu trúc chương trình, bởi vì bạn gợi lên nhiều cái đồng thời và có thể tận dụng bộ xử lý đa cpu. Ví dụ, một máy chủ web có thể sử dụng tầm thường nhiều trình xử lý yêu cầu đồng thời, do các đối tượng.

Nó làm cho việc tái cấu trúc và tái sử dụng dễ dàng hơn, như tôi đã đề cập, khuyến khích sự trừu tượng hóa tốt, tất cả đều dễ dàng bảo trì. OOP nên được chấp nhận và sử dụng mọi lúc. Lập trình OOP tốt tránh các phương thức tĩnh và / hoặc dữ liệu tĩnh và sử dụng các đối tượng cho mọi thứ.


6
Tôi đã không downvote (mặc dù tôi đã ở gần nó), nhưng tôi nghĩ rằng đây là lý do cho các downvote bạn nhận được: "Luôn luôn sử dụng nó, bởi vì nó rất tốt" hiếm khi là một lời khuyên tốt. Luôn có ngoại lệ. Không có công cụ nào đi kèm mà không có nhược điểm, và OOP cũng không ngoại lệ. Nói với mọi người rằng nó tốt, nói cho mọi người biết nó tốt cho cái gì, nói với mọi người tại sao nó tốt, nói với mọi người để tránh những lựa chọn thay thế nếu họ có thể, nhưng đừng bao giờ nói với mọi người đừng nghĩ về những lựa chọn thay thế.
cmaster

@cmaster, tôi ổn nếu mọi người downvote, đó là lựa chọn của họ và tôi cũng đã làm điều đó. Về vấn đề này, tôi vẫn nghĩ đây là câu trả lời đúng cho người đặt câu hỏi; IMHO, OP cần phải nhảy vào và sử dụng OOP, thay vì cố gắng quyết định khi nào nên sử dụng OOP và đôi khi chọn tạo một lớp nhưng nếu không thì viết mã thủ tục.
Erik Eidt

2
@cmaster Tôi có thể đánh giá cao lời khuyên của Erik. Thông thường, loại câu trả lời "phụ thuộc" có thể là cách chính xác để đi, hãy đối mặt với mọi người, OO đã trở thành cơ sở cho các môi trường lập trình hỗ trợ nó. Vì vậy, đừng tự đùa, bạn khó có thể sai với OO. Kịch bản được mô tả là, mặc dù tuyến tính, đủ phức tạp để các đối tượng mang lại cho bạn một số lợi ích.
Martin Maat

2
@ErikEidt "OP cần phải nhảy vào và sử dụng OOP" Bạn có thể diễn giải rằng "OP cần ngừng suy nghĩ về cách tốt nhất để giải quyết vấn đề của khách hàng và chỉ cần đi theo một con đường thực sự để giác ngộ." Đáng buồn thay, tôi đã phải đối phó với rất nhiều cái gọi là chuyên gia máy tính người làm theo mà phương pháp thiết kế phần mềm. Phim hoạt hình Dilbert bắt buộc: Dilbert.com/strip/1996-02-27
alephzero

1
dễ dàng như việc vẫy nó đi như "một người nhiệt tình OOP vô tâm" khác, tôi nghĩ có điều gì đó được nói để thực sự chuyển 100% vào một cái gì đó để thực sự nội tâm hóa và hấp thụ nó. không phải vì vậy bạn có thể sử dụng nó mỗi ngày trong suốt quãng đời còn lại, nhưng vì vậy bạn thực sự TÌM HIỂU những điểm mạnh và điểm yếu và không chỉ đọc về chúng. Tôi muốn giới thiệu bất cứ ai dành vài tháng để làm OOP khó tính và một vài tháng khó tính FP (á la haskell) và một vài tháng thủ tục C, v.v. chỉ cần vào trong đó và nhận được và bẩn với nó.
sara

-2

Lập trình hướng đối tượng cung cấp các công cụ để tạo khung. Những công cụ này là Đóng gói, Trừu tượng, Kế thừa và Đa hình. Những ý tưởng này sẽ giúp bạn chia chương trình của bạn thành hai phần.

Cách thực hiện - Đây là phần hoạt động của khung trong mã của bạn, nơi bạn tạo ra một loại trừu tượng, quyết định cách các khối của bạn hoạt động nói chung và cách nó tương tác với các khối khác.

Phải làm gì - Phần này là nơi các khối thực hiện công việc thực tế. Ở đây, lớp được lấy từ các lớp cơ sở tạo ra trong phần "Cách thức".

Một người có thể hưởng lợi rất nhiều từ OOPS

  1. nếu bạn có thể sử dụng lại một khung hiện có và chỉ phải thực hiện các chi tiết cụ thể trong phần "phải làm gì".
  2. Chức năng đang được triển khai cho dự án hiện tại là một dự án chung / thường được sử dụng và các dự án / dự án tương lai khác có thể thu được lợi ích từ khung được tạo trong khi phát triển dự án hiện tại.
  3. Chia các dự án lớn thành các mô hình thường biết để giải quyết một vấn đề lớn.
  4. Sử dụng OOPS cho dự án nhỏ ngay cả để có thói quen sử dụng nó và sẵn sàng khi 1 - 3 loại vấn đề xuất hiện

Vì vậy, về cơ bản bạn đang nói rằng bạn nên luôn luôn sử dụng OOP, bất kể nhiệm vụ thực tế bạn muốn giải quyết là gì?
JacquesB

Không :), có rất nhiều chương trình chương trình ngoài kia và một số cho vay để giải quyết một vấn đề cụ thể tốt hơn những vấn đề khác. OOPS không phải là giải pháp tốt nhất cho tất cả, nhưng OOPS là một giải pháp khá phổ biến. sẽ mất thời gian và thực hành để xây dựng lớp và cấu trúc tốt trong OOPS, vì vậy nếu bạn muốn sử dụng OOPS hiệu quả hơn hãy bắt đầu với các dự án nhỏ hơn. Một khi bạn thành thạo nó, nó hoàn toàn phụ thuộc vào bạn. Tôi thấy các khái niệm OOPS là một công cụ để xây dựng khung chủ yếu.
Rahul Menon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.