Tại sao nhiều ngôn ngữ lập trình động gõ vịt sử dụng cách tiếp cận dựa trên lớp thay vì OOP dựa trên nguyên mẫu?


23

Vì khá nhiều ngôn ngữ lập trình động có tính năng gõ vịt và chúng cũng có thể mở và sửa đổi các phương thức lớp hoặc cá thể bất cứ lúc nào (như RubyPython ), sau đó

Câu hỏi 1) Điều gì cần cho một lớp học trong một ngôn ngữ động? Tại sao ngôn ngữ được thiết kế theo cách đó để sử dụng một lớp như một loại mẫu của bản thân Thay vì làm theo kiểu nguyên mẫu và chỉ sử dụng một đối tượng?

Ngoài ra JavaScript là dựa trên nguyên mẫu, nhưng CoffeeScript (phiên bản nâng cao của JavaScript) chọn cách dựa trên lớp. Và nó cũng tương tự đối với Lua (dựa trên nguyên mẫu) và MoonScript (dựa trên lớp). Ngoài ra, còn có lớp ES.

Câu hỏi 2) Có gợi ý rằng nếu bạn cố gắng cải thiện ngôn ngữ dựa trên nguyên mẫu, trong số những thứ khác, bạn nên thay đổi nó thành dựa trên lớp không? Nếu không, tại sao nó được thiết kế theo cách đó?


9
Nhiều lập trình viên không muốn bị làm phiền khi học một cái gì đó mới. (Nó quá xa lạ và "khó khăn"). Do đó tất cả các thư viện và ngôn ngữ dựa trên lớp biên dịch cho chúng.
Thomas Eding

1
Tôi đồng ý với Thomas, nhưng điều buồn cười là sau khi bạn học cách tiếp cận năng động, nó thực sự dễ dàng hơn (không khó hơn). Khái niệm về các đối tượng vẫn còn đó, chỉ là các đối tượng có thể được thay đổi mà không cần biên dịch lại một số "bản thiết kế" ngu ngốc trước. Nếu tôi muốn đặt chân thứ 5 lên ghế, tôi không muốn phải thay đổi bản thiết kế trước, tôi chỉ muốn thêm chân. Ngôn ngữ động mô hình chặt chẽ hơn thực tế theo ý kiến ​​của tôi.
Lonnie hay nhất

1
OOP được phát minh trong bối cảnh gõ tĩnh, trong đó các kiểu phải được khai báo. Ở đó, các lớp là một bước tiến hợp lý từ các bản ghi và mô-đun. OOP dựa trên nguyên mẫu chỉ là một chủ đề nghiên cứu thú vị cho ngôn ngữ Tự, và bằng cách nào đó đã biến nó thành JavaScript như là cách đơn giản nhất để đánh dấu từ thông dụng OOP của một ngôn ngữ cơ bản. Điều tuyệt vời là bạn có thể thực hiện các lớp trên đầu các nguyên mẫu. Mặc dù tôi thích các metaobject, việc tách các lớp khỏi các thể hiện của chúng giúp cho việc viết mã được ghép tốt, đơn giản, lỏng lẻo dễ dàng hơn.
amon

3
Điều đầu tiên trước tiên: JavaScript tự hỗ trợ classtừ khóa theo tiêu chuẩn ECMAScript tiếp theo (ECMAScript 6). Hỗ trợ cho các lớp trong JavaScript đã được lên kế hoạch từ lâu. Bây giờ với những gì nó là - các lớp chỉ là đường cú pháp, một lý do dễ dàng hơn về mô hình cho các đối tượng cùng loại. Đó là cách này trong JS và nó là cách này trong Python và các ngôn ngữ động khác.
Benjamin Gruenbaum

1
@BenjaminGruenbaum "... các lớp chỉ là cú pháp cú pháp ..." wow, đây là một ý tưởng khá mới lạ đối với tôi, thực sự, đối với các ngôn ngữ như ruby ​​và python, có vẻ như không quan trọng việc sử dụng một đối tượng hay dù là lớp mẫu- cả hai đều có thể được sửa đổi nhanh chóng. Và nó cũng không thực sự quan trọng như thế nào họ xử lý tài sản thừa kế. Vì vậy, có lẽ không cần phân biệt giữa cách tiếp cận dựa trên lớp và cách tiếp cận dựa trên nguyên mẫu cho một ngôn ngữ động :)
iceX

Câu trả lời:


12

Câu hỏi 1) Nhu cầu về Lớp học trong ngôn ngữ động là gì? Tại sao ngôn ngữ được thiết kế theo cách đó để sử dụng một lớp như một loại mẫu khuôn mẫu Thay vì làm theo kiểu nguyên mẫu và chỉ sử dụng một đối tượng?

Ngôn ngữ OO đầu tiên (mặc dù nó không được gọi là "OO"), Simula, không có sự kế thừa. Kế thừa đã được thêm vào trong Simula-67, và nó dựa trên các lớp.

Cùng thời gian đó, Alan Kay bắt đầu thực hiện ý tưởng của mình về một mô hình lập trình mới, mà sau này ông đặt tên là "Định hướng đối tượng". Anh ấy thực sự thích sự kế thừa và muốn có nó trong ngôn ngữ của mình, nhưng anh ấy cũng thực sự không thích các lớp học. Tuy nhiên, anh ta không thể nghĩ ra cách thừa kế mà không có lớp, và vì vậy anh ta quyết định rằng anh ta không thích các lớp hơn là anh ta thích thừa kế và thiết kế phiên bản đầu tiên của Smalltalk, Smalltalk-72 mà không có lớp kế thừa.

Vài tháng sau, Dan Ingalls đã đưa ra một thiết kế các lớp, trong đó chính các lớp là các đối tượng, cụ thể là các ví dụ của siêu dữ liệu. Alan Kay nhận thấy thiết kế này hơi kém hấp dẫn so với những cái cũ, vì vậy Smalltalk-74 được thiết kế với các lớp và với sự kế thừa dựa trên các lớp.

Sau Smalltalk-74, Alan Kay cảm thấy rằng Smalltalk đang đi sai hướng và không thực sự đại diện cho những gì OO là tất cả, và anh ấy đề xuất rằng nhóm từ bỏ Smalltalk và bắt đầu mới, nhưng anh ấy đã bị trục xuất. Do đó, theo sau Smalltalk-76, Smalltalk-80 (phiên bản đầu tiên của Smalltalk được phát hành cho các nhà nghiên cứu), và cuối cùng là Smalltalk-80 V2.0 (phiên bản đầu tiên được phát hành thương mại và phiên bản trở thành nền tảng cho ANSI Smalltalk) .

Vì Simula-67 và Smalltalk-80 được coi là ông bà của tất cả các ngôn ngữ OO, nên hầu như tất cả các ngôn ngữ theo sau, sao chép một cách mù quáng thiết kế các lớp và kế thừa dựa trên các lớp. Một vài năm sau, khi các ý tưởng khác như thừa kế dựa trên mixin thay vì các lớp và ủy quyền dựa trên các đối tượng thay vì thừa kế dựa trên các lớp nổi lên, sự kế thừa dựa trên lớp đã trở nên quá cố chấp.

Thật thú vị, ngôn ngữ hiện tại của Alan Kay dựa trên phái đoàn nguyên mẫu.


"... Ngôn ngữ hiện tại của Alan Kay ..." đó là ...?
Javier

@Javier: Tôi không nghĩ nó có tên và tên của hệ thống liên tục thay đổi.
Jörg W Mittag

Đây phải là một câu trả lời hay để chỉ ra lần tới khi ai đó liệt kê quyền thừa kế là một yêu cầu cho OO :)
Hey

1
@iceX: Alan Kay thành lập Viện nghiên cứu quan điểm để thực hiện ý tưởng của mình. Thật không may, thông tin thực sự rải rác trên trang web.
Jörg W Mittag

3
Alan Kay trích dẫn trên OO: "OOP với tôi có nghĩa là chỉ nhắn tin, duy trì và bảo vệ cục bộ và che giấu quá trình nhà nước, và ràng buộc cực kỳ muộn của tất cả mọi thứ. Nó có thể được thực hiện trong Smalltalk và LISP. Có thể có các hệ thống khác trong điều này là có thể, nhưng tôi không biết về chúng. "
Joeri Sebrechts

23

Nhiều lập trình viên thích làm việc với các lớp. Đó là một khái niệm rất dễ hiểu, là một mô hình tốt về quá trình suy nghĩ của con người về thế giới (nghĩa là, chúng ta liên kết theo bản năng các đối tượng thực với nhóm vật phẩm trừu tượng mà chúng ta coi chúng thuộc về, đó là thứ mà một lớp học là) . Ngoài ra, các lớp làm cho lý luận về các loại đối tượng dễ dàng hơn: trong ngôn ngữ dựa trên lớp, việc áp dụng các nguyên tắc như thay thế Liskov đơn giản hơn so với ngôn ngữ mà chúng ta chỉ có các đối tượng có thể có các phương thức khác nhau hoặc loại có thể thay đổi trong thời gian chạy , như trường hợp trong JavaScript.

Lưu ý rằng ngay cả trong JavaScript, rất nhiều mã chỉ đơn giản là sử dụng tiện ích nguyên mẫu để mô phỏng các lớp. Điều này chủ yếu là vì rất nhiều lập trình viên thích suy nghĩ theo cách đó.

Ngoài ra còn có một lý do khác khiến các ngôn ngữ dựa trên lớp được ưa thích: việc biên dịch chúng thành mã hiệu quả sẽ dễ dàng hơn. Các máy ảo JavaScript hiệu quả nhất tạo động các lớp một cách hiệu quả để biểu diễn các loại đối tượng JavaScript khi các phương thức và nguyên mẫu của chúng thay đổi. Xem mô tả về việc triển khai V8 để biết lý do tại sao việc này được thực hiện.


4
Đoạn cuối của bạn thực sự hỗ trợ hoàn toàn ngược lại với những gì bạn đang nói: V8 chứng minh rằng bạn không cần các lớp trong ngôn ngữ để biên dịch thành mã dựa trên lớp hiệu quả.
Jörg W Mittag

4
Đúng, bạn không cần chúng - nhưng thực tế là V8 (và có lẽ là Tự, mặc dù tôi chưa đọc nhiều về thiết kế của hệ thống đó) tạo ra các lớp ảo có nghĩa là bắt đầu từ một ngôn ngữ sử dụng các lớp gần như chắc chắn dễ dàng hơn, và do đó có lẽ sẽ kết thúc với JIT cần dành ít thời gian hơn để biên dịch mã.
Jules

11
Chắc chắn, và thực tế là V8 tạo GOTOs và đăng ký một cách hiệu quả có nghĩa là chỉ cần từ bỏ tất cả các khái niệm trừu tượng và viết trực tiếp trong lắp ráp gần như chắc chắn dễ dàng hơn, và do đó có lẽ sẽ kết thúc với việc JIT cần tốn ít thời gian hơn để biên dịch mã. Đó là công việc của một trình biên dịch để hỗ trợ các bản tóm tắt cấp cao hơn.
Jörg W Mittag

1
Có, nhưng đó là một sự đánh đổi, vì sự trừu tượng ở cấp độ cao hơn trong hầu hết các trường hợp khó thực hiện hơn và thường có hình phạt hiệu năng trong thời gian chạy, đặc biệt là khi làm việc với JIT thay vì trình biên dịch AOT. Tôi nghi ngờ rằng nhiều nhà thiết kế ngôn ngữ chọn một cấu trúc dựa trên lớp vì một hoặc cả hai lý do đó; Tôi biết đó là lý do tại sao tôi chọn các lớp có thành viên cố định cho ngôn ngữ (nếu không năng động) mà tôi đang làm việc, nhưng chỉ có thể suy đoán về các ngôn ngữ khác.
Jules

1
Tôi cho rằng cách duy nhất để các lập trình viên thích "suy nghĩ trong lớp" là bởi vì đó là cách mà hầu hết chúng ta được dạy. Tôi chắc chắn có thể nhớ rất nhiều sinh viên đại học của tôi đã gặp khó khăn trong việc nắm bắt và hiểu một số khái niệm hướng đối tượng thực sự cơ bản trong vài năm, mặc dù. Nó chỉ có vẻ rõ ràng và dễ dàng trong nhận thức muộn màng.
KChaloux 2/2/2015

3

Tôi đã nghe nói rằng trong các dự án lớn, nơi các nhóm người làm việc cùng một mã, các ngôn ngữ linh hoạt (nơi bạn có thể sửa đổi các thuộc tính và phương thức của đối tượng trong thời gian chạy) là các quyền tự do mà các thành viên khác trong nhóm không muốn bạn có.

Họ muốn biết, khi họ đang làm việc với một đối tượng, đối tượng đó sẽ hành động giống như kế hoạch chi tiết nói, và không phải là một cách biến đổi mà một số nhà phát triển đầy tham vọng khác đã quyết định thay đổi nó để hoàn thành nhiệm vụ của mình.

Vì vậy, lý do duy nhất tôi có thể hình dung, rằng ai đó sẽ không muốn sự linh hoạt được cung cấp bởi các ngôn ngữ động tuyệt vời này, là họ muốn đơn giản hóa việc phát triển nhóm, gỡ lỗi và tự động tạo tài liệu.

Cá nhân, tôi đã phát triển các ứng dụng theo cả hai phương pháp và tôi hoàn thành công việc nhanh hơn với các ngôn ngữ động. Tôi không sử dụng bất kỳ khung công tác nào được thiết kế để biến ngôn ngữ động của mình trở lại thành ngôn ngữ cơ sở lớp. Những điều như vậy là một hồi quy cho thị hiếu của tôi.


1

OOP với tôi có nghĩa là chỉ nhắn tin, duy trì và bảo vệ cục bộ và che giấu quá trình nhà nước, và cực kỳ ràng buộc tất cả mọi thứ - Alan Kay

Vì vậy, những gì anh ấy đang nói ở đây là OO là tất cả về việc tạo ra các hộp đen trả lời tin nhắn. Theo một cách nào đó, REST là hệ thống OO cuối cùng ở chỗ nó sử dụng các động từ (tức là một thông điệp) và các tài nguyên (tức là một hộp mờ chứa một số dữ liệu).

Vì vậy, câu hỏi tại sao một số dựa trên lớp và những người khác dựa trên nguyên mẫu lại bỏ lỡ vấn đề thực sự không quan trọng, cả hai đều chỉ là triển khai. Một hệ thống chỉ sử dụng nhắn tin thay vì gọi phương thức cũng giống như OO như hai trường hợp bạn đề cập.

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.