Liệu lập trình hướng đối tượng có thực sự mô hình hóa thế giới thực? [đóng cửa]


52

Tôi đã thấy nó thường lặp đi lặp lại việc lập trình hướng đối tượng dựa trên mô hình thế giới thực nhưng phải không?

Dường như với tôi điều đó không đúng với bất cứ điều gì ngoài lớp kinh doanh. Các lớp GUI / lớp truy cập dữ liệu của tôi không mô hình hóa bất cứ điều gì trong thế giới thực. Ngay cả trong tầng lớp kinh doanh của tôi, tôi đã có các lớp như quan sát viên, nhà quản lý, nhà máy, v.v. không phải là đối tượng trong thế giới thực. Tôi cố gắng thiết kế các lớp học của mình để tận dụng những thứ như đóng gói nhưng thế giới thực có được gói gọn không?

Trong khi một số đối tượng tôi tạo đang mô hình hóa các đối tượng trong thế giới thực, thì mã OOP trước có làm như vậy không? Tôi nghi ngờ rằng OO là người đầu tiên đưa các khái niệm như Khách hàng vào các cơ sở mã của họ. Nhưng OO thực sự là về cách mô hình hóa mọi thứ và phương pháp mô hình hóa đó dường như không được truyền cảm hứng từ thế giới thực đối với tôi.

Vậy: lập trình hướng đối tượng có thực sự mô hình hóa thế giới thực không?


85
Ý tưởng sử dụng sự tương tự của các đối tượng OOP đại diện cho các đối tượng trong thế giới thực là một ví dụ điển hình của khái niệm "lời nói dối với trẻ em". Chúng tôi nói với những người mới bắt đầu học OOP lời nói dối này vì đây là một cách trực quan để có được những điều cơ bản. Ngay khi họ học được những điều cơ bản đó, họ sẵn sàng tiếp thu thực tế rằng tất cả những gì họ biết là sai; mọi thứ thực sự phức tạp hơn thế. Nó giống như vật lý ở trường học: những thứ nắm tay rơi xuống, sau đó mọi thứ bị cuốn hút vào những thứ lớn hơn, rồi những thứ lớn bẻ cong không gian, rồi cuối cùng chúng ta được bảo rằng chúng ta thực sự không biết gì về cách mọi thứ hoạt động.
evilcandybag

4
Sự tranh chấp thực sự ở đây là gì? Có phải có một số thực thể trong thế giới thực không bao giờ được mô hình hóa được mô hình hóa đầy đủ bằng các kỹ thuật OO không? hoặc là mô hình hóa tức là sử dụng một sự hiểu biết đơn giản hóa không phù hợp với thế giới đầy đủ là một ý tưởng tồi không hoạt động?
Dipan Mehta

1
@DipanMehta, sự tranh cãi là việc mô tả OO như mô hình hóa thế giới thực bỏ lỡ trái tim của lập trình hướng đối tượng. Tất cả các kỹ thuật lập trình mô hình hóa thế giới thực (ở mức độ này hay mức độ khác), đó không phải là điều làm cho OO trở nên độc đáo.
Winston Ewert

@WinstonEwert Vâng, modeling the real worldcó thể không phải là điều thực sự làm nên sự khác biệt của OO. Có lẽ. Nhưng tôi chắc chắn sẽ không tin rằng bạn sẽ thất bại trong việc này trong OO. Mô hình hoặc kỹ thuật nào bạn nghĩ làm cho nó tốt hơn OO?
Dipan Mehta

14
Tất cả các chương trình cố gắng để mô hình một cái gì đó trong thế giới thực. Một số mô hình chỉ mô hình các phần khác nhau tốt hơn so với những người khác. Quy trình mô hình mã thủ tục, Mô hình mã chức năng giải quyết vấn đề logic, Mô hình mã hướng đối tượng mô hình mối quan hệ phân cấp. Mô hình mã ngôn ngữ hội tuyệt vời .
Jesse C. Choper

Câu trả lời:


50

Không hoàn toàn không.

Tuy nhiên, đó là một phương pháp cho phép tạo ra một sự trừu tượng tốt đẹp để giữ các cấu trúc dữ liệu phức tạp cùng với một số phương thức hoạt động trên các cấu trúc dữ liệu.


Câu trả lời ngắn gọn tuyệt vời. Theo định nghĩa, bạn mất một số chi tiết trong mô hình.
MathAttack

Xin lỗi, tôi không thích câu trả lời này. Với OOP, bạn có thể mô hình hóa (một số khía cạnh) thế giới thực rất nhiều.
clime

33

Mô hình, dưới bất kỳ hình thức nào, không mô hình thế giới thực, không hoàn toàn.

Họ mô hình các phần được chọn , những phần có liên quan đến ứng dụng.

Những gì bạn đang nói (nhà quan sát, nhà quản lý, nhà máy, v.v.) là cơ sở hạ tầng sẵn có để giúp bạn có được sự trừu tượng đúng và hỗ trợ các chức năng cần thiết như sự kiên trì.


15
Tôi sẽ lập luận rằng "mô hình hóa" đã có nghĩa là bắt chước các khía cạnh nhất định (trong khi bỏ qua các khía cạnh khác). Theo nghĩa đó, OO cho phép mô hình hóa thế giới thực.
Tamás Szelei

Những phần nào trong vấn đề của bạn được OO mô hình hóa tốt? Một số vấn đề không phù hợp với mô hình OO, các mô hình khí hậu xuất hiện trong tâm trí. Nhiều vấn đề kinh doanh làm ánh xạ tốt đến OO, đó là lý do tại sao mô hình được sử dụng rộng rãi.
Michael Storesin

@MichaelShopsin - Ý của bạn là bình luận của bạn về câu hỏi chứ không phải câu trả lời của tôi?
Oded

@Oded Tôi thích câu trả lời của bạn; bình luận của tôi là một bản mở rộng của "các phần được chọn theo mô hình". Mô hình OO mô hình rất nhiều vấn đề, đó là vấn đề đảm bảo rằng chúng phù hợp với vấn đề trong tay.
Michael Storesin

31

Mô hình là gì, dù sao đi nữa:
Mô hình là một biểu diễn đơn giản được sử dụng để giải thích hoạt động của hệ thống hoặc sự kiện trong thế giới thực

Có lập trình hướng đối tượng cho phép bạn mô hình hóa thế giới thực?

Chắc chắn là có

Hầu như không thể mô hình hóa hệ thống để khớp chính xác với thế giới thực.

Tôi có luôn phải mô hình hóa phần mềm chính xác sau thế giới thực không?

KHÔNG

Đã nói rằng bạn có thể mô hình hóa mọi thứ không có nghĩa là bạn phải mô hình hóa mọi thứ. Trong thực tế, bản chất của mô hình hữu ích là trình bày một biểu diễn đơn giản hóa. Bao nhiêu đơn giản hóa là đủ để thể hiện nhu cầu kinh doanh hiện tại và những gì cần phải bỏ qua, là một sự cân bằng tốt giữa việc sử dụng kỹ thuật thành công so với việc bị mất với nó hoặc hoàn toàn không sử dụng nó.

Tất nhiên có những thực thể không tồn tại thực sự, nhưng chỉ thông qua mô hình, chúng ta thực sự có thể khái niệm tốt.


9
" Mô hình là gì? " Một đống tư nhân nhỏ bé khốn khổ. Nhưng đủ mã, có tại bạn!
Ben Brocka

Tôi nghĩ rằng điểm cuối cùng của bạn nắm bắt các mối quan hệ vô hình. Đôi khi các vật thể tồn tại trong thế giới thực, chúng ta không nhìn thấy chúng.
MathAttack

19

Tôi nghĩ rằng việc dạy rằng có một mối quan hệ giữa các danh từ và các lớp gây ra các thói quen xấu khó chịu để phát triển mà phải bị nghiền nát bởi một kiến ​​trúc sư thiếu kiên nhẫn hoặc kỹ sư cao cấp.

Điều nên được dạy là các lớp mô hình các đối tượng trừu tượng, giống như bộ não của bạn. Bạn có một khái niệm trừu tượng về "chiếc xe" trong đầu mà không ánh xạ tới bất kỳ chiếc xe vật lý cụ thể nào, nó có thể tái sử dụng, việc triển khai xe cụ thể có thể kế thừa từ nó. Bộ não của bạn thậm chí các khái niệm siêu mô hình cho bạn. Bạn có một mô hình tinh thần về suy nghĩ là gì, khái niệm là gì.

Nếu chúng tôi dạy mọi người xác định các mô hình mà họ đã tạo trong đầu, họ sẽ chuẩn bị tốt hơn rất nhiều để xây dựng phần mềm thực sự.


+1 Một quan điểm tuyệt vời và khác thường như vậy. Cảm ơn đã chia sẻ nó! Tôi đang tự hỏi liệu bạn có nhặt được một cuốn sách hay không? Tôi chắc chắn rất thích đọc cuốn sách đó.
Mahdi

8

... Thế giới phong phú hơn những gì có thể được thể hiện bằng cú pháp hướng đối tượng.

Hãy xem xét một vài khái niệm phổ biến mà mọi người thường sử dụng để hiểu và mô tả tất cả các hệ thống - các khái niệm không phù hợp với khuôn đối tượng. Mô hình 'trước / sau', cũng như 'nguyên nhân / kết quả' và khái niệm 'trạng thái của hệ thống' là một trong những ví dụ sinh động nhất. Thật vậy, quá trình 'pha cà phê', hoặc 'lắp ráp một chiếc xe', hoặc 'hạ cánh một chiếc máy bay trên sao Hỏa' không thể bị phân hủy thành các vật thể đơn giản. Vâng, họ đang được đối xử theo cách đó trong các ngôn ngữ OO, nhưng đó là giả tạo và phản trực giác. Trình tự của thói quen - trước những gì trong điều kiện dựa trên nguyên nhân nào - đơn giản là không có đại diện có ý nghĩa trong OO , bởi vì OO không có khái niệm về trình tự, hoặc trạng thái hoặc nguyên nhân.

Các quy trình là cực kỳ phổ biến trong thế giới thực và trong lập trình. Các cơ chế xây dựng đã được nghĩ ra trong nhiều năm để xử lý các giao dịch, quy trình làm việc, điều phối, chủ đề, giao thức và các khái niệm 'thủ tục' vốn có khác. Những cơ chế này tạo ra sự phức tạp khi chúng cố gắng bù đắp cho sự thiếu hụt bất biến theo thời gian vốn có trong lập trình OO. Thay vào đó, vấn đề nên được giải quyết tận gốc bằng cách cho phép các cấu trúc cụ thể theo quy trình, như 'trước / sau', 'nguyên nhân / hiệu ứng', và, có lẽ, 'trạng thái hệ thống' là một phần cốt lõi của ngôn ngữ ...

nguồn trích dẫn: Victoria Livschitz, Bước tiếp theo trong lập trình


2
Đó là một cảm giác kỳ lạ khi bạn thấy một trường hợp hấp dẫn như vậy được làm cho một cái gì đó bạn vẫn không đồng ý. Tôi có được động lực cho trích dẫn, và thật khó để nói từ đó tốt hơn. Tôi chỉ không biết rằng đó là một sai lầm khi mô hình hóa các vấn đề của chúng ta giống như cách mà các quá trình suy nghĩ hướng đến mối quan hệ mang tính biểu tượng của chúng ta làm.
đe dọa

Thú vị tôi đoán là nhưng tôi chưa bao giờ muốn viết một chương trình pha cà phê. Vấn đề được xác định một cách mơ hồ. Chương trình có quyền truy cập vào bộ truyền động phần cứng không, hay đây là một mô phỏng thuần túy? Trong cả hai trường hợp, có vẻ như cách tiếp cận đối tượng sẽ cung cấp một nơi tốt để bắt đầu, hoặc là mô hình hóa các bộ truyền động có liên quan hoặc mô hình hóa trạng thái bên trong của các tác nhân và công cụ liên quan.
Đánh dấu E. Haase

13
this.MoveTo(Environment.Find<Bathroom>().OrderBy(b=>b.Distance(this)).First()); this.SitOn(Environment.Find<Toilet>().Where(t=>!t.IsOccupied).OrderBy(t=>t.Distance(this)).First().Component<Seat>()); this.DiscardWaste(HumanWasteType.All);
Adam Robinson

1
Khó có thể tin rằng cô là một người đề xướng Java khi đưa ra rất nhiều điểm chỉ trích chính xác chống lại mô hình OO quá hẹp của nó. Và hơi nực cười, cô ấy không đề cập đến bất kỳ ngôn ngữ nào làm cho nó tốt hơn (ngoại trừ "Đó là một cải tiến lớn so với người tiền nhiệm của nó, C ++." ...).
leftaroundabout

1
OO không có khái niệm về trình tự, hoặc trạng thái . Thật là vô nghĩa. Không có khái niệm về trình tự và trạng thái trong OOP? OO
clime

5

Có, OO thường có thể được sử dụng để mô hình hóa các thực thể trong thế giới thực.

Ngay cả trong tầng lớp kinh doanh của tôi, tôi đã có các lớp như người quan sát, người quản lý, nhà máy, v.v. không phải là đối tượng trong thế giới thực.

Đừng nhầm lẫn giữa phát triển hướng đối tượng với các mẫu thiết kế. Phân tích và thiết kế OO là một phương tiện để tiếp cận lập trình mã duy trì. Kết hợp với ngôn ngữ OO, các lập trình viên được trao quyền tạo mã có thể sử dụng lại thông qua các trụ cột của OO: đóng gói, đa hình và kế thừa.

Để gói gọn một thực thể, chúng ta có thể mô hình hóa thực thể đó sau bản sao thế giới thực của nó. Ví dụ, nếu chúng ta có một cây đàn guitar thì một lớp đàn guitar sẽ gói gọn các hành vi và tính chất của một cây đàn guitar trong thế giới thực. Chúng ta có thể trừu tượng hóa cây đàn guitar như, nói, IInventoryItemđể tận dụng tiềm năng tái sử dụng mã thông qua đa hình và kế thừa.

Mặt khác, chúng ta có thể thấy rằng một nhà máy sản xuất đàn guitar có thể hỗ trợ chúng ta duy trì một bộ các loại đàn guitar khác nhau. Đây không phải là vì OO. Thay vào đó, một nhà máy là một mẫu thiết kế đã đứng trước thử thách của thời gian như là một phương tiện đã được chứng minh để tạo thành công mã bảo trì cho mục đích như vậy. Nói cách khác, chúng tôi lập trình viên thường giải quyết các vấn đề tương tự. Vì vậy, chúng tôi đã đưa ra một giải pháp chung để giải quyết chúng (không phát minh lại bánh xe).

Điều đó không có nghĩa là OO phải mô hình hóa thế giới thực, cũng không phải luôn luôn là giải pháp tối ưu nhất để làm điều đó. Đơn giản, đó là một quy tắc của ngón tay cái OO mô hình hóa thế giới thực có nghĩa là hoàn hảo.


5

Nó phụ thuộc vào thế giới thực mà bạn đang nói về.

Jorge Luis Borges đã viết một câu chuyện "Tlön, Uqbar, Orbis Tertius", nơi một trong những người dân dường như cảm nhận thế giới thực của họ hoàn toàn khác:

[...] người dân Tlôn tưởng tượng [...] nắm giữ một hình thức cực đoan của chủ nghĩa duy tâm Berkeleian, phủ nhận thực tế của thế giới. Thế giới của họ được hiểu "không phải là sự đồng nhất của các vật thể trong không gian, mà là một chuỗi các hành vi độc lập không đồng nhất". Một trong những ngôn ngữ tưởng tượng của Tlôn thiếu danh từ. Đơn vị trung tâm của nó là "động từ vô danh đủ điều kiện bởi các hậu tố đơn âm hoặc tiền tố có lực của trạng từ." Borges liệt kê một Tlönic tương đương với "Mặt trăng mọc trên mặt nước": hlor u fang axaxaxas mlö, có nghĩa đen là "Hướng lên phía sau dòng chảy trên mặt trăng". [...] Trong một ngôn ngữ khác của Tlôn, "đơn vị cơ bản không phải là động từ, mà là tính từ đơn âm tiết", trong đó, kết hợp hai hoặc nhiều hơn, tạo thành danh từ: "moon" trở thành "ánh sáng tròn tối "hoặc"

(được sao chép từ tài liệu wikipedia về cuốn sách)

Đối với tôi, vấn đề không phải là nhiều đến mức thế giới có thể được cảm nhận khác với chúng ta, đó là sự sáo rỗng, nhưng nhận thức về cấu trúc của thực tế phụ thuộc vào ngôn ngữ chúng ta nói, có thể là ngôn ngữ tự nhiên hoặc ngôn ngữ lập trình. Người Tlönese có thể rất hài lòng với Lisp và có thể thấy Java (AKA The Kingdom Of Nouns ) là rất không tự nhiên, trong khi hầu hết các lập trình viên người Thổ Nhĩ Kỳ có xu hướng thiên về đối tượng hơn các ngôn ngữ chức năng. Tôi thích cả hai phong cách, vì tôi nghĩ nó chủ yếu là vấn đề quan điểm. Một số vấn đề được tấn công tốt nhất với chức năng, một số vấn đề khác với các kỹ thuật lập trình hướng đối tượng. Một lập trình viên giỏi luôn nhìn vào một vấn đề khó khăn từ các góc độ khác nhau, trước khi anh ta thử một giải pháp. Hoặc, như Alan Kay đã nói: Quan điểm đáng giá 80 điểm IQ .

Vì vậy, câu trả lời của tôi cho câu hỏi của bạn là: Bạn đang nói về thế giới thực nào? Và làm thế nào?


"Nhận thức về cấu trúc của thực tế phụ thuộc vào ngôn ngữ chúng ta nói, có thể là ngôn ngữ tự nhiên hoặc lập trình". Điều đó thật đúng!
clime

4

Trong khi một số đối tượng tôi tạo đang mô hình hóa các đối tượng trong thế giới thực, thì mã OOP trước có làm như vậy không?

Tôi sẽ nói không. OOP ràng buộc mối quan hệ giữa các thứ (thuộc tính / đối tượng) và những gì chúng có thể làm / có thể được thực hiện với chúng (phương thức), trong khi lập trình thủ tục không làm điều này (ngoài một mức độ nhỏ, khi sử dụng kiểu gõ nghiêm ngặt). Một mô hình không chỉ là về việc xác định các phần và quy trình riêng biệt, mà còn về việc xác định cách chúng khớp với nhau và OOP đặc biệt tốt trong việc này.


Tôi nghĩ bạn có nghĩa là thủ tục không chức năng.
Winston Ewert

vâng, đúng. Tôi sẽ thay đổi nó
từ đó

3

Tôi đã thấy nó thường lặp đi lặp lại lập trình hướng đối tượng dựa trên mô hình thế giới thực, nhưng phải không?

Đúng. Sự nhấn mạnh ở đây dựa trên . OOP không mô hình hóa thế giới thực (nếu có, sau đó là tình cờ) và nó không được phép. Những gì OOP làm là cho phép chúng ta mô hình hóa các vấn đề lập trình theo cách chúng ta mô hình hóa thế giới thực: như một hệ thống các thực thể được xác định thông qua sự trừu tượng hóa hành vi của chúng.


3
Vâng - vậy nó không dựa trên mô hình thế giới thực, phải không?
leftaroundabout

3

Mã OO thường không mô hình hóa thế giới thực - ít nhất đó không phải là mục tiêu, nó đơn giản cho phép bạn suy nghĩ về mã của mình theo cách tự nhiên hơn, giống như cách bạn nghĩ về mọi thứ trong thế giới thực-- đây là những gì trích dẫn đang cố gắng nói


3

Nó không mô hình hóa thế giới của chúng ta, nhưng nó mô hình hóa sự giải thích của con người về thế giới của chúng ta. Con người tự nhiên ngăn cách mọi thứ như đồ vật. OO có hiệu quả vì nó cho phép con người lập trình theo cách họ nghĩ.


2

OOP có thể không phải là một mô hình hoàn hảo của thế giới thực và các đối tượng chứa trong đó, nhưng nó là một phương pháp giúp đối phó với sự phức tạp ngày càng tăng của phần mềm đời thực. Nó cũng giúp viết mã tốt hơn, bằng cách chia nhỏ nó thành các đoạn có liên quan logic.

Mặc dù các phương pháp định hướng thủ tục cũ hơn chắc chắn cũng sẽ cung cấp kết quả, OOP giúp bạn đến đó nhanh hơn và dễ dàng hơn, ngay cả khi xử lý các dự án lớn & phức tạp.

Trừu tượng hóa và đóng gói giúp tập trung vào cốt lõi của vấn đề trong khi che giấu tất cả các hệ thống ống nước thực sự làm cho công cụ xảy ra. Kế thừa và cho phép bạn thiết lập một mối quan hệ hợp lý và có ý nghĩa giữa các khía cạnh khác nhau của mã của bạn. Đa hình thúc đẩy việc tái sử dụng mã và cho phép bạn dễ dàng xử lý các biến thể (những vấn đề " gần giống như một đối tượng hiện có" xảy ra rất thường xuyên) và mở rộng mã bằng cách mở rộng ngữ nghĩa liên quan đến một đối tượng.

Tôi cảm thấy OOP giống như một sự trợ giúp đã được chứng minh cho phép bạn giải quyết tất cả những phức tạp của một hệ thống thực tế một cách hiệu quả. Vì vậy, mặc dù nó có thể không phải là một mô hình rất kỹ lưỡng về thế giới thực, nhưng nó đủ gần và giúp bạn hoàn thành công việc, mà IMHO là tất cả những gì quan trọng cuối cùng.


2

Tôi đã thấy nó thường lặp đi lặp lại lập trình hướng đối tượng dựa trên mô hình thế giới thực, nhưng phải không?

Dường như với tôi điều đó không đúng với bất cứ điều gì ngoài lớp kinh doanh.

Không. Như bạn đã chỉ ra, nhiều thứ được "mô hình hóa" bằng ngôn ngữ OOP là các khái niệm trừu tượng như hàng đợi tin nhắn và bộ điều khiển và ngăn xếp.

Ngay cả trong lớp doanh nghiệp của bạn, bạn vẫn không mô hình hóa "thế giới thực". Giả sử bạn có một lớp nhân viên. Nhân viên cũng là Người, cũng là Động vật có vú, cũng là Động vật, cũng là người (ngáp) Nhân viên có màu sắc yêu thích, và họ mặc quần áo nhất định và tin vào những điều nhất định. Nói tóm lại, có một phạm vi phức tạp rất lớn trong thế giới thực mà chúng ta thậm chí không cố gắng nắm bắt trong hầu hết các chương trình.

Trong mô hình hóa, chúng tôi chỉ tập trung vào các khía cạnh của mô hình có ý nghĩa đối với nhiệm vụ trong tay. Nếu chúng ta đang thiết kế một hệ thống nhập thời gian, thì có lẽ chúng ta muốn một số loại Nhân viên, nhưng lớp đó không cần một đặc tính để thể hiện màu sắc yêu thích của nhân viên.

Do đó, các người mẫu không nên cố gắng (hoặc giả vờ) để thể hiện hoàn toàn "Thế giới thực".

Trong khi một số đối tượng tôi tạo đang mô hình hóa các đối tượng trong thế giới thực, thì mã OOP trước có làm như vậy không? Tôi nghi ngờ rằng OO là người đầu tiên đưa các khái niệm như Khách hàng vào các cơ sở mã của họ.

Bạn nói đúng. Nếu bạn xem các chương trình lớn không phải là OOP, chúng thường vẫn được tổ chức xung quanh các cấu trúc dữ liệu. Một cấu trúc dữ liệu và tất cả các chức năng thao tác được xác định gần nhau, vì lý do rõ ràng. ( Dự án lật đổ là một ví dụ tốt về điều này. Các cấu trúc và hàm dữ liệu được thêm tiền tố với tên mô-đun để rõ ràng cấu trúc và chức năng nào được sử dụng cho nhau.)

Tôi không phải là chuyên gia về lịch sử của ngôn ngữ lập trình, nhưng tôi tưởng tượng rằng OOP phát triển từ sự quan sát thông thường rằng mã rõ ràng và dễ hiểu hơn khi được tổ chức theo cách này, vì vậy các nhà thiết kế ngôn ngữ bắt đầu thiết kế ngôn ngữ theo kiểu tổ chức đó. thực thi nghiêm ngặt hơn.

Sự khác biệt lớn nhất giữa OOP và không OOP là OOP liên kết mã với dữ liệu. Vì vậy, thay vì gọi mã như thế này:

verb(noun);

chúng tôi làm điều này thay vào đó:

noun->verb();

Mặc dù điều này có vẻ như là một sự khác biệt về ngữ pháp, sự khác biệt thực sự là trong suy nghĩ. Chúng tôi nói cho các đối tượng biết phải làm gì và thường không quan tâm trạng thái bên trong hoặc hoạt động của đối tượng là gì. Khi mô tả một đối tượng, chúng ta chỉ cần mô tả giao diện công khai của nó để làm việc với nó.


2

Liệu lập trình hướng đối tượng có thực sự mô hình hóa thế giới thực?

Không hoàn toàn.

Trong thế giới thực, chúng ta phải đối mặt với những vấn đề thực sự. Chúng tôi muốn giải quyết vấn đề này bằng cách sử dụng một mô hình sao chép hệ thống mà chúng tôi muốn xây dựng để trở thành mô hình.

Ví dụ: nếu ứng dụng Giỏ hàng gặp sự cố, chúng tôi có các thực thể khác nhau như

  1. Sản phẩm là một thuật ngữ trừu tượng có thể có nhiều thành viên như Sách, Tiện ích, Xe hơi có thể được chia lại.

  2. Tiêu chí thuế như (Thuế bán hàng) sẽ phụ thuộc vào vị trí mà phần mềm được triển khai vì nó có thể thay đổi dựa trên chính sách của chính phủ.

  3. Thuế được xem xét dựa trên việc sản phẩm đã được nhập khẩu cùng với các tiêu chí thuế.

  4. Người dùng có thể có một giỏ hàng trong đó có một danh sách các sản phẩm, vv

Vì vậy, như bạn có thể thấy, có những vấn đề thực sự mà chúng tôi đang cố gắng giải quyết nhưng được mô đun hóa theo mô hình OOP để làm cho nó càng gần với hệ thống thực càng tốt.


1
Tôi thích câu trả lời này. OO nên mô hình hóa miền vấn đề của bạn, vì vậy trong khi có rất nhiều khái niệm trong thế giới thực, một số trong số chúng sẽ không liên quan đến vấn đề bạn đang cố gắng giải quyết và bạn sẽ có các cấu trúc OO không ánh xạ chính xác vào một cái gì đó trong thế giới thực, nhưng nó đáp ứng nhu cầu trong lĩnh vực vấn đề.
Andy

2

Tôi nghĩ rằng bạn đang đọc quá nhiều vào những gì được dự định là một tuyên bố rất lịch sử, lịch sử. Nhiều ý tưởng về lập trình OO, các lớp, đa hình, các hàm ảo, v.v. đã được giới thiệu bằng ngôn ngữ Simula, vào những năm 1960 (http://en.wikipedia.org/wiki/Simula). Như tên cho thấy, Simula được thiết kế để trở thành một ngôn ngữ để viết mô phỏng. Vì vậy, trong lịch sử, vâng, các ý tưởng OO đã được giới thiệu trong một nỗ lực để mô hình hóa "thế giới thực". Cho dù họ thành công hơn các phong cách khác là một vấn đề tranh luận.


2

Trong khi một số đối tượng tôi tạo đang mô hình hóa các đối tượng trong thế giới thực, thì mã OOP trước có làm như vậy không?

Sự khác biệt lớn nhất giữa mã OOP và mã trước OOP là các mô hình trước đây là một tình huống trong thế giới thực khi một nhóm các thực thể riêng biệt tương tác với nhau, mỗi "sức mạnh" hạn chế về những gì nó có thể làm và cũng có khả năng "phản ứng" với sự kiện bên ngoài với hành động của riêng mình. Cái sau mô hình mọi thứ như một khối dữ liệu lớn không tự làm được gì, trong khi tính toán đại diện cho "những điều xảy ra" và có thể ảnh hưởng đến bất kỳ hoặc tất cả chúng.

Cho dù nó có mô hình tốt hơn thế giới thực hay không, điều đó thực sự phụ thuộc vào khía cạnh nào của thế giới mà bạn đang tạo mô hình. Một mô phỏng vật lý, ví dụ, nơi bạn muốn mô tả các hiệu ứng mà nói, một ngọn lửa được thắp lên trong các vật thể bao trùm, sẽ được thể hiện tốt hơn bằng cách tiếp cận "truyền thống", vì cả ánh sáng và nhiệt đều tốt xác định các quá trình ảnh hưởng đến cả trạng thái bên ngoài và bên trong của các đối tượng khác và không thay đổi theo hành vi của từng đối tượng cụ thể, chỉ bị ảnh hưởng bởi các thuộc tính của chúng.

Mặt khác, nếu bạn mô hình hóa các thành phần khác nhau tương tác để tạo ra hành vi mong muốn, coi chúng là tác nhân thay vì những thứ thụ động có thể giúp bạn thực hiện chính xác dễ dàng hơn mà không bỏ sót điều gì. Nếu tôi muốn bật TV, tôi chỉ cần nhấn nút, nếu rút dây nguồn, nó TV.turnOnsẽ kiểm tra xem có giúp tôi không. Vì vậy, không có nguy cơ biến một cái răng cưa và quên biến cái khác chạm vào nó, vì bản thân cái răng cưa (nếu được lập trình chính xác) sẽ quan tâm đến các tương tác thứ cấp do hậu quả của cái tương tác chính.

Nhưng OO thực sự là về cách mô hình hóa mọi thứ và phương pháp mô hình hóa đó dường như không được truyền cảm hứng từ thế giới thực đối với tôi.

Tôi tin rằng nó có liên quan nhiều đến cách chúng ta nhìn nhận thế giới hơn là thế giới thực sự như thế nào. Người ta có thể lập luận rằng mọi thứ chỉ là một loạt các nguyên tử (hoặc năng lượng, hoặc sóng, bất cứ thứ gì), nhưng điều đó không giúp chúng ta xử lý nhiệm vụ xử lý các vấn đề chúng ta gặp phải, với việc hiểu môi trường xung quanh chúng ta và dự đoán các sự kiện trong tương lai ( hoặc mô tả quá khứ). Vì vậy, chúng tôi tạo ra "mô hình tinh thần" của thế giới và thường những mô hình tinh thần đó tìm thấy sự tương ứng tốt hơn với OO so với dữ liệu + xử lý một mô hình - được cho là mô hình "tốt hơn" cách thế giới thực thực sự vận hành.

Một điều thú vị nữa là hầu hết mọi người đều nghĩ OOP là từ đồng nghĩa với "OOP cổ điển", nơi chúng ta tạo ra các tập hợp và tập hợp con của sự vật, và đặt các đối tượng một cách rõ ràng vào một bộ rất cụ thể. Điều đó rất hữu ích để tạo các loại mới có thể tái sử dụng , nhưng không tuyệt vời lắm khi thực thể mà bạn tạo mô hình khá khép kín và trong khi nó bắt đầu tương tác với các đối tượng khác, thì hiếm khi, nó là mục tiêu của sự tương tác. Hoặc tệ hơn, khi có một vài (có thể chỉ một) trường hợp của entiy đó, hoặc các trường hợp khác nhau rất nhiều về thành phần, hành vi hoặc cả hai.

Tuy nhiên, cũng có "OOP nguyên mẫu", trong đó một đối tượng được mô tả bằng cách chọn một đối tượng tương tự và liệt kê các khía cạnh mà chúng khác nhau. Tôi muốn đề xuất bài luận này cho một lời giải thích tốt và không quá kỹ thuật về quá trình suy nghĩ (toàn bộ bài viết quá lớn, ngay cả đối với các tiêu chuẩn của Steve Yegge, vì vậy tôi chỉ vào phần có liên quan: P). Một lần nữa, đây là một kết hợp tốt cho các mô hình tinh thần của chúng ta khi tưởng tượng các trường hợp chưa biết bằng cách so sánh với một mô hình đã biết, nhưng không nhất thiết là cách thế giới thực "hoạt động" ... (hai con bò thực sự hoàn toàn phân biệt các thực thể, ngay cả khi chúng ta cảm nhận được chúng như "giống nhau" theo nhiều cách)


1

Tôi nghĩ "Có" là phần quan trọng của câu hỏi này. Tôi nghĩ lập trình hướng đối tượng chắc chắn có thể mô hình hóa các "đối tượng" trong thế giới thực, nhưng đây là lập trình . Không phương pháp nào không thể bị lạm dụng, vì vậy tôi không công bằng khi nói "OOP không mô hình hóa thế giới thực" chỉ vì bạn có thể làm những điều ngu ngốc với các Đối tượng. Điều đó không công bằng hơn khi nói rằng Con trỏ không an toàn vì bạn có thể làm những điều ngu ngốc với con trỏ.

Bài viết của Wikipedia về vấn đề này tổng hợp rất tốt:

Mô hình hóa và các mối quan hệ trong thế giới thực
OOP có thể được sử dụng để liên kết các đối tượng và quy trình trong thế giới thực với các đối tác kỹ thuật số. Tuy nhiên, không phải ai cũng đồng ý rằng OOP tạo điều kiện lập bản đồ thế giới thực trực tiếp (xem phần Phê bình tiêu cực) hoặc lập bản đồ thế giới thực thậm chí là một mục tiêu xứng đáng; Bertrand Meyer lập luận trong Xây dựng phần mềm hướng đối tượng [21] rằng một chương trình không phải là mô hình của thế giới mà là mô hình của một số nơi trên thế giới; "Thực tế là anh em họ hai lần bị loại bỏ".

Vấn đề là trừ khi chương trình của bạn là mô phỏng vũ trụ, bạn chỉ quan tâm đến các phần của thế giới thực - do đó là "mô hình". Đó là những gì mô hình dành cho, chúng cung cấp cho bạn cấu trúc và chức năng mà bạn cần hiển thị.

Trong thế giới thực, chúng ta có những thứ (Đối tượng) và mọi thứ có thể thực hiện các hành động (phương thức). Chúng ta có thể định lượng các khía cạnh của sự vật (Thuộc tính). OOP có mọi tiềm năng để mô hình hóa mọi thứ trong thế giới thực khi được sử dụng theo cách giản lược; mọi thứ phức tạp đều có các lớp con nhỏ hơn hoặc cụ thể hơn và tất cả những thứ này có tương tác tự nhiên thông qua các phương thức.

OOP là một phương pháp trừu tượng, do đó, điều thực tế là liệu OOP thực sự hợp lý mô hình các đối tượng trong thế giới thực, đó là ít quan trọng mà bạn không mô hình hóa mọi thứ có thể tất cả mọi thứ đơn bao giờ có thể làm được . Nếu bạn cần làm mọi điều có thể, bạn không thực sự làm người mẫu .


1

Để suy nghĩ về hướng đối tượng trong ngữ cảnh phù hợp của nó, chúng ta hãy tiến lên một mức độ trừu tượng và nói về lập trình nói chung, ok?

Bất kể bạn thực hiện OO hay các phương pháp tiếp cận chức năng, chương trình của bạn phải làm gì đó, phải không? Toàn bộ quan điểm của chương trình là thể hiện những hành vi nhất định với một loạt các kích thích nhất định. Vì vậy, lý do mà các chương trình tồn tại là vì họ làm một cái gì đó. Từ khóa ở đây là hành vi .

Ngoài việc xem xét những hành vi mà một chương trình phải thực hiện, chương trình của bạn thường cần thể hiện những phẩm chất nhất định. Ví dụ, không đủ để chương trình theo dõi nhịp tim có các hành vi cần thiết của nó - nó cũng thường cần phải thực hiện đủ nhanh để hoạt động trong thời gian gần như thật. Các "phẩm chất" khác mà một chương trình có thể cần thể hiện là: bảo mật, linh hoạt, mô đun hóa, khả năng mở rộng, khả năng đọc, v.v. Chúng tôi gọi những thuộc tính chất lượng kiến ​​trúc này . Vì vậy, chúng tôi có thể nói rằng chương trình của chúng tôi cần phải đáp ứng các mục tiêu hành vi (chức năng) nhất định cũng như thể hiện những phẩm chất nhất định (không chức năng).

Cho đến nay, không ai trong số này đã nói về OO, phải không? Hãy làm điều đó ngay bây giờ.

Khi một kỹ sư hiểu các yêu cầu (hành vi, AQAs, các ràng buộc, v.v.), câu hỏi đặt ra: làm thế nào để tôi tổ chức mã của mình để nó thực hiện tất cả những điều cần làm trong khi cũng thể hiện các phẩm chất cần thiết để trở thành một chương trình hữu ích? Lập trình hướng đối tượng là một chiến lược để tổ chức chức năng của chương trình của bạn thành các mô đun gắn kết của các đối tượng hợp tác. Lập trình chức năng chỉ là một chiến lược khác để tổ chức chức năng của chương trình của bạn và nó thực hiện theo một cách khác. Cả hai chiến lược đều có điểm mạnh và điểm yếu.

Chúng tôi đã chứng kiến ​​sự hồi sinh gần đây trong các khái niệm chức năng bởi vì nó có những điểm mạnh rất hấp dẫn để xử lý phân tán mạnh mẽ, trong số những lý do khác.

Nhưng khi quay trở lại OO, bạn có thể thấy rằng nó không nhất thiết phải mô hình hóa "thế giới thực"; những gì nó làm là tổ chức hành vi của chương trình của bạn để chương trình của bạn có thể thể hiện những phẩm chất cần thiết để đáp ứng bất kỳ mục tiêu kinh doanh nào. Các kỹ thuật như TDD, DDD và BDD là những cách chúng tôi khám phá cách tốt nhất để tổ chức các đối tượng của mình. Các cuốn sách như Nguyên tắc, Mô hình và Thực tiễn , Phát triển phần mềm hướng đối tượng được hướng dẫn bởi các thử nghiệm , Đặc tả bằng ví dụThiết kế hướng tên miền đưa ra lý thuyết và thực hành hướng đối tượng với trọng tâm là thiết kế hướng hành vi.

Khi bạn đọc về những thứ như "người quan sát, người quản lý, nhà máy, v.v.", bạn đang áp dụng các mẫu OO giúp chương trình của bạn thể hiện những phẩm chất nhất định có thể cần thiết để nó hữu ích. Chúng là "những người nhận đã được chứng minh" rằng "có xu hướng hoạt động", cho rằng nhu cầu của bạn phù hợp với vấn đề mà mô hình giải quyết.

Tôi hy vọng điều đó giúp bạn hiểu OO là gì mà không xuất hiện quá sai lệch giữa OO và các mô hình chức năng.


1

OOP tạo ra một mô hình đẹp từ quan điểm lập trình, nó không phản ánh thế giới thực.

Tuy nhiên, có nhiều xấp xỉ tốt hơn nhiều về thế giới thực, được biết đến bởi thuật ngữ ngôn ngữ cụ thể miền ( DSL ). Ví dụ Boo cung cấp cho bạn khả năng viết mã người có thể đọc được bằng tiếng Anh gần như đơn giản (mẫu từ bài viết ).

apply_discount_of 5.percent:
         when order.Total > 1000 and customer.IsPreferred
         when order.Total > 10000

suggest_registered_to_preferred:
         when order.Total  > 100 and not customer.IsPreferred

Một ví dụ khác là các khung kiểm tra chấp nhận người dùng tự động dựa trên ngôn ngữ Gherkin .

Feature: Some terse yet descriptive text of what is desired
    In order to realize a named business value
    As an explicit system actor
    I want to gain some beneficial outcome which furthers the goal

Scenario: Some determinable business situation
    Given some precondition
        And some other precondition
    When some action by the actor
        And some other action
        And yet another action
    Then some testable outcome is achieved
        And something else we can check happens too

0

Cuối cùng, tùy bạn. Nhưng OOP là một cách chính xác để làm như vậy hơn các phương pháp khác như lập trình hướng theo cấu trúc hoặc theo thủ tục. Chiến thuật thủ tục có thể có thể giải quyết vấn đề của bạn nhưng bằng cách làm theo OOP có thể giúp bạn sống dễ dàng hơn.

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.