JavaRush /Blog Java /Random-VI /Lập trình hướng đối tượng (bản dịch bài viết)
Exidnus
Mức độ
Санкт-Петербург

Lập trình hướng đối tượng (bản dịch bài viết)

Xuất bản trong nhóm
Từ người dịch: Thật không may, tôi không có kinh nghiệm đáng kể trong việc dịch từ tiếng Anh, mặc dù tôi đọc khá nhiều bằng tiếng Anh. Nhưng hóa ra đọc và dịch là hai việc khác nhau. Ngoài ra, thật không may, tôi không có nhiều kinh nghiệm lập trình (gần đây tôi mới tạo một ứng dụng web đơn giản trong Spring MVC và Hibernate). Vì vậy, bản dịch trở nên tồi tệ hơn nhiều so với những gì nó có thể xảy ra. Tôi đã tự nguyện sửa một chút các ví dụ mã được đưa ra trong bài viết vì chúng không tuân thủ các quy ước đặt tên trong Java. Có lẽ việc dịch tên của một số mẫu không đáng (cách dịch như vậy không mang lại nhiều hiểu biết), nhưng tôi nghĩ rằng đây là điều ít tệ hại hơn. Điều đáng nói riêng về “sự gắn kết cao” là cách dịch của “sự gắn kết cao”. Tôi đồng ý, đây không phải là bản dịch tốt nhất. Nhưng “kết nối mạnh mẽ” là “khả năng kết nối cao” (một khái niệm quan trọng khác) và “sự mạch lạc” khó có thể phù hợp ở đây. Tôi sẵn sàng đón nhận những lời chỉ trích và sẽ chấp nhận những bình luận về bài viết dưới mọi hình thức với lòng biết ơn. Lập trình hướng đối tượng là một kiểu lập trình trong đó chương trình được tạo thành từ các thành phần tương ứng với các đối tượng trong thế giới thực. Bất kỳ đối tượng thực nào cũng có một số thuộc tính (có thể thay đổi hoặc không thay đổi theo thời gian) và hành vi (có thể có hoặc không). thay đổi tùy thuộc vào người khác) điều kiện). Ví dụ: bút chì là một đối tượng trong thế giới thực có các thuộc tính sau:
  • Nó có màu đỏ (điều này không thay đổi theo thời gian).
  • Bây giờ nó dài 10 cm (điều này có thể thay đổi nếu bút chì được gọt nhọn).
Và nó có hành vi sau:
  • Nó để lại dấu vết nếu sử dụng đúng cách.
  • Dấu vết có thể khác nhau tùy thuộc vào áp suất (tùy thuộc vào yếu tố bên ngoài).
  • Chiều dài của nó ngắn lại khi nó được mài sắc (hành vi lâu dài).
Như trong ví dụ này, các đối tượng trong thế giới thực có thể có nhiều thuộc tính, nhưng khi viết chương trình, chúng ta chỉ tính đến những thuộc tính cần thiết. Lập trình hướng đối tượng có những ưu điểm của nó. Ví dụ: nó giúp việc thiết lập kết nối giữa một đối tượng trong thế giới thực và chương trình theo cách mong đợi trở nên dễ dàng hơn. Điều này thực sự hữu ích khi ứng dụng phát triển và nhiều đối tượng tương tác với nhau. Điều này giúp phân bổ trách nhiệm trong thế giới khách quan, cho phép bạn tập trung suy nghĩ về ứng dụng. Một tính năng quan trọng khác liên quan đến OOP (Lập trình hướng đối tượng) là phân loại đối tượng. Vì thế giới (thực/ảo) có rất nhiều đồ vật nên rất khó để kiểm soát chúng một cách riêng lẻ. Chúng ta cần một cách để phân loại những đồ vật này để giúp chúng ta liên kết các đồ vật khác nhau và đặc tính của chúng, chẳng hạn như bút chì đen. Nó sẽ không thể phân biệt được (giống nhau?) nếu được sử dụng trong ví dụ trước, nhưng nó là một đối tượng khác. Nhưng vì cả hai đều là bút chì nên chúng thuộc cùng một lớp "Bút chì". Trong khi đó, cây bút, rất giống với bút chì, lại thuộc một loại khác. Tuy nhiên, bút và bút chì đều là “Dụng cụ viết”. Lập trình hướng đối tượng có các nguyên tắc sau:
Trừu tượng
Tính trừu tượng được định nghĩa là chất lượng của sự tương tác với các ý tưởng hơn là các sự kiện hay nói cách khác là sự tự do khỏi các phẩm chất mang tính biểu đạt . Điều này cho phép các lập trình viên tập trung vào những gì cần lập trình hơn là lập trình như thế nào . Tính trừu tượng có thể được coi là một hợp đồng thông qua đó chúng tôi cung cấp chức năng. Chi tiết triển khai có thể bị ẩn khi sử dụng khái niệm này. Ví dụ, nếu chúng ta cần một lớp có khả năng viết thì chúng ta phải chắc chắn rằng nó có phương thức "write". abstract class writer { write (); } Chúng ta đã làm gì? Chúng tôi đã thiết kế một lớp cấp cao trừu tượng, nói cách khác, nó biết chúng tôi cần chức năng gì, nhưng cách triển khai nó nằm ngoài phạm vi của lớp này. Điều này mang lại nhiều lợi ích:
  • Chúng tôi tiết lộ thông tin tối thiểu cần thiết cho các tổ chức bên ngoài, điều này cho phép chúng tôi tập trung suy nghĩ xuyên suốt chương trình (điều này cho phép suy nghĩ tập trung), tránh nhầm lẫn và tránh đưa ra những lời hứa ngoài ý muốn.
  • Chúng tôi dành chỗ cho những cải tiến trong tương lai sẽ không thể thực hiện được nếu chi tiết triển khai được tiết lộ.
Di sản
"Kế thừa" trong tiếng Anh thông dụng có nghĩa là "tiếp thu và truyền lại". Từ này đã tồn tại trong văn hóa của chúng tôi trong một thời gian rất dài. Tổ tiên đã làm lụng vất vả để có được đất đai và truyền lại cho con cháu, ngay cả tạo hóa cũng ưu ái thừa kế. Tất cả các đặc tính của cơ thể, chẳng hạn như chiều cao, màu da/mắt/tóc, v.v. phụ thuộc vào gen chúng ta thừa hưởng từ cha mẹ. Kế thừa ngăn chặn việc phát minh lại bánh xe và tăng tốc độ tiến bộ. Nó giống nhau trong OOP. Chúng tôi tạo một lớp cha với một vài thuộc tính/hành vi cơ bản. Tất cả các lớp kế thừa từ lớp cha này sẽ chứa các thuộc tính/hành vi giống như lớp cha của chúng. Tuy nhiên, các lớp kế thừa có thể có thêm thuộc tính/hành vi hoặc thay đổi cách triển khai hành vi. class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } Trong ví dụ trên, lớp cha (WritingInstrument) có thuộc tính “color” và hành vi “write”. Khi lớp con (xử lý) được khai báo, thuộc tính "color" và hành vi "write" không cần phải khai báo lại. Chúng hiện diện trong lớp "xử lý" do tính kế thừa. Tuy nhiên, lớp con có thể khai báo các thuộc tính/hành vi bổ sung của chính nó. Làm thế nào chúng ta có thể sử dụng điều này trong thực tế? Các nhà phát triển chúng tôi rất lười biếng. Chúng tôi không muốn in đi in lại một cái gì đó. Việc tồn tại nhiều bản sao của cùng một mã không được khuyến khích do những cân nhắc sau:
  • Càng ít bản sao mã thì càng dễ bảo trì.
  • Nếu không có nhiều bản sao của mã thì sự thay đổi ở một nơi sẽ hiển thị ở mọi nơi.
  • Càng ít mã, càng ít lỗi.
  • Nếu một mã được sử dụng ở nhiều nơi thì sẽ đạt được sự khái quát hóa.
  • Chúng tôi tập trung vào việc viết mã.
  • Chúng tôi tập trung vào các bài kiểm tra.
Tính kế thừa trong Java đạt được bằng cách sử dụng từ khóa "mở rộng" và "triển khai". class WritingInstrument { } class Pen extends WritingInstrument { }
Đa hình
Từ “đa hình” xuất phát từ hai từ: “Poly” , tức là “nhiều” / “nhiều hơn một” “morph” , tức là “hình thức” Theo nghĩa đen, từ “đa hình” đề cập đến khả năng của các đối tượng hành xử theo những cách khác nhau tùy thuộc vào các điều kiện. Trong lập trình, tính đa hình có thể được triển khai ở một số nơi:
  • Các lớp học
  • phương pháp
  • Toán tử
Tất cả những điều trên có thể hoạt động khác nhau tùy thuộc vào điều kiện, có lẽ là bối cảnh mà chúng được sử dụng. Điều này rất hữu ích vì máy khách (lập trình viên sử dụng thư viện của bạn) không cần biết nhiều chi tiết và chức năng mong muốn được triển khai bằng cách chọn thông tin cần thiết từ ngữ cảnh. Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } } Ví dụ trên có cách triển khai mặc định trong WritingObject, được mở rộng/ghi đè bởi các lớp con pen và pen. Phương thức write() được gọi ba lần trong lớp Main. Mỗi lần một cách triển khai khác nhau được gọi tùy thuộc vào đối tượng mà phương thức đó được gọi. Trong trường hợp này, phương thức write() có nhiều kiểu hành vi vì nó có tính đa hình.
Đóng gói
Đóng gói được định nghĩa là thu thập dữ liệu/chức năng liên quan trong một đơn vị. Điều này giúp tạo điều kiện thuận lợi cho việc truy cập/sửa đổi dữ liệu. Ví dụ: nếu cần in tất cả các thuộc tính mà một người dùng nhất định có, chúng tôi có các tùy chọn sau: printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) Chúng tôi đã tạo một phương thức lấy tất cả các thuộc tính và in chúng lần lượt. Khi số lượng phần tử trong danh sách tăng lên, sẽ không thể xác định được các trường chính xác nữa và việc thêm/xóa một trường sẽ thay đổi chữ ký phương thức. Do đó, chúng tôi cần thay thế tất cả người dùng phương pháp này, ngay cả khi họ không cần các trường được thêm gần đây. Để làm cho mã dễ đọc hơn và giúp việc sửa đổi trong tương lai trở nên dễ dàng hơn, chúng tôi đóng gói các thuộc tính trong một lớp và biến nó thành một đối tượng chung. class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} Đối tượng là một gói phần mềm gồm các biến và các phương thức liên quan. Bạn có thể biểu diễn các đối tượng trong thế giới thực bằng cách sử dụng các đối tượng chương trình. Bạn có thể tưởng tượng những chú chó thật trong một chương trình hoạt hình hoặc một chiếc xe đạp thật như một đối tượng phần mềm bên trong một chiếc xe đạp tập thể dục. Trong OOP, lớp là một mẫu có thể mở rộng (mẫu mã chương trình) để tạo đối tượng, cung cấp cho chúng trạng thái ban đầu (biến) và hành vi triển khai (hàm, phương thức). Từ viết tắt SOLID được Michael Feather đặt ra cho “năm nguyên tắc đầu tiên” được Robert C. Martin đặt tên vào đầu những năm 2000. Mục tiêu của các nguyên tắc này, khi được triển khai cùng nhau, là tăng khả năng người lập trình viên sẽ tạo ra một hệ thống dễ bảo trì và mở rộng. Các nguyên tắc RẮN là những hướng dẫn trong quá trình phát triển chương trình cần thiết để loại bỏ mã “thối” thông qua việc tái cấu trúc, do đó mã sẽ trở nên dễ đọc và có thể mở rộng. Đây là một phần của chiến lược lập trình linh hoạt và thích ứng.
Nguyên tắc trách nhiệm duy nhất
Trong OOP, nguyên tắc trách nhiệm duy nhất nêu rõ rằng mỗi lớp phải chịu trách nhiệm về một phần chức năng do chương trình cung cấp và trách nhiệm đó phải được gói gọn hoàn toàn bởi lớp đó. Tất cả chức năng của nó phải liên quan chặt chẽ đến trách nhiệm này.
Nguyên tắc đóng/mở
Trong OOP, nguyên tắc mở/đóng nêu rõ rằng “các thực thể phần mềm (lớp, mô-đun, phương thức, v.v.) phải mở để mở rộng nhưng đóng để thay đổi”. Nói cách khác, thực thể phải cho phép mở rộng hành vi của mình mà không cần thay đổi mã nguồn.
Nguyên tắc thay thế Liskov
Khả năng thay thế là một nguyên tắc trong OOP. Nó tuyên bố rằng nếu S trong chương trình máy tính là một kiểu con của T, thì các đối tượng thuộc loại T phải sao cho chúng có thể được thay thế bằng các đối tượng thuộc loại S (tức là các đối tượng thuộc loại S có thể được thay thế bằng các đối tượng thuộc loại T) mà không thay đổi bất kỳ chương trình thuộc tính cần thiết nào (độ chính xác, hoàn thành nhiệm vụ, v.v.).
Nguyên tắc phân chia giao diện
Nguyên tắc phân tách giao diện nêu rõ rằng người lập trình máy khách không nên bị buộc phải phụ thuộc vào các phương thức mà nó không sử dụng. Theo nguyên tắc này, cần phải chia các giao diện lớn thành các giao diện nhỏ hơn và cụ thể hơn để lập trình viên máy khách chỉ biết về các phương thức mà anh ta quan tâm. Mục đích của nguyên tắc tách giao diện là giữ cho hệ thống được tách rời, điều này sẽ giúp việc tái cấu trúc, thực hiện thay đổi và triển khai lại dễ dàng hơn.
Nguyên tắc đảo ngược phụ thuộc
Trong OOP, nguyên tắc đảo ngược phụ thuộc có nghĩa là một dạng ngắt kết nối cụ thể của các mô-đun chương trình. Bằng cách tuân theo nguyên tắc này, các mối quan hệ phụ thuộc tiêu chuẩn được thiết lập từ các mô-đun cấp cao hình thành kiến ​​trúc ứng dụng (cài đặt chính sách) đến các mô-đun cấp thấp phụ thuộc sẽ được đảo ngược (đảo ngược), để các mô-đun cấp cao được sửa đổi trở nên độc lập với các chi tiết triển khai của module cấp thấp. Nguyên tắc này nêu rõ:
  • Các mô-đun cấp cao không nên phụ thuộc vào các mô-đun cấp thấp. Cả hai loại mô-đun phải phụ thuộc vào sự trừu tượng.
  • Sự trừu tượng không nên phụ thuộc vào chi tiết triển khai. Chi tiết phải phụ thuộc vào sự trừu tượng.
Nguyên tắc này đảo ngược cách mọi người có thể nghĩ về thiết kế hướng đối tượng bằng cách lập luận rằng các đối tượng cấp cao và cấp thấp phải phụ thuộc vào cùng một sự trừu tượng.

nguyên tắc GRASP

Các mẫu phần mềm phân công trách nhiệm chung (GRASP) cung cấp các hướng dẫn để phân công trách nhiệm cho các lớp và đối tượng trong thiết kế hướng đối tượng.
Bộ điều khiển
Mẫu Bộ điều khiển giao trách nhiệm tương tác với các sự kiện hệ thống cho các lớp không phải GUI đại diện cho toàn bộ hệ thống hoặc kịch bản ca sử dụng. Bộ điều khiển:
  • Đây là đối tượng không tương tác trực tiếp với người dùng và có nhiệm vụ tiếp nhận và phản hồi các sự kiện của hệ thống.
  • Phải được sử dụng để xử lý tất cả các sự kiện hệ thống của một (hoặc nhiều trường hợp sử dụng có liên quan với nhau).
  • Đây là đối tượng đầu tiên đằng sau GUI điều khiển hoạt động của hệ thống.
  • Anh ta không phải tự mình thực hiện công việc, nhiệm vụ của anh ta là kiểm soát dòng sự kiện.
Người sáng tạo
Nhiệm vụ của lớp người sáng tạo là tạo và khởi tạo các đối tượng cho lần sử dụng tiếp theo. Nó biết các tham số khởi tạo cũng như đối tượng nào sẽ được tạo. Đôi khi lớp người sáng tạo chủ động tạo các đối tượng và đặt chúng vào bộ nhớ đệm, đồng thời cung cấp một phiên bản khi cần thiết.
Sự gắn kết cao
Độ gắn kết cao là một mô hình đánh giá, mục đích của nó là bảo quản các đối tượng ở trạng thái nhằm thực hiện một nhiệm vụ rõ ràng, dễ dàng kiểm soát và hiểu được. Khớp nối cao thường được sử dụng để hỗ trợ Khớp nối thấp. Tính mạch lạc cao có nghĩa là trách nhiệm của một yếu tố nhất định được xác định rõ ràng (có liên quan chặt chẽ và tập trung cao độ). Chia chương trình thành các lớp và hệ thống con là một ví dụ về các hành động làm tăng tính gắn kết của các thuộc tính hệ thống. Mặt khác, khớp nối lỏng lẻo là tình huống trong đó một phần tử có quá nhiều nhiệm vụ không liên quan. Các phần tử được ghép nối lỏng lẻo có xu hướng khó hiểu, khó tái sử dụng, khó bảo trì và khó thay đổi.
gián tiếp
Mẫu Roundabout duy trì sự kết nối lỏng lẻo (và khả năng sử dụng lại) giữa hai phần tử bằng cách gán trách nhiệm tương tác giữa chúng cho một đối tượng trung gian. Một ví dụ là việc giới thiệu bộ điều khiển để làm trung gian giữa dữ liệu (mô hình) và màn hình (chế độ xem) của nó trong mẫu Model-View-Controller (MVC).
Chuyên gia thông tin
Chuyên gia thông tin (còn gọi là Chuyên gia hoặc Nguyên tắc chuyên gia) là một nguyên tắc được sử dụng để xác định ai sẽ giao trách nhiệm cho ai. Trách nhiệm bao gồm các phương pháp, trường được tính toán, v.v. Khi sử dụng nguyên tắc này khi phân công trách nhiệm, cách tiếp cận chính là chuỗi hành động sau: phân tích trách nhiệm, xác định thông tin cần thiết để thực hiện trách nhiệm đó và cuối cùng xác định thông tin này nằm ở đâu. Việc sử dụng nguyên tắc Chuyên gia thông tin dẫn đến việc giao trách nhiệm cho lớp có nhiều thông tin nhất để thực thi nó.
Khớp nối thấp
Khớp nối lỏng lẻo là một mẫu đánh giá chỉ định cách phân công trách nhiệm: khớp nối lỏng lẻo giữa các lớp, việc thay đổi lớp này sẽ có tác động tối thiểu đến lớp kia, tối đa hóa khả năng sử dụng lại.
Đa hình
Theo tính đa hình, sự biến đổi của hành vi dựa trên loại được gán cho các loại mà biến thể này xảy ra. Điều này đạt được bằng cách sử dụng các phép toán đa hình.
Các biến thể được bảo vệ
Mẫu Thay đổi được bảo vệ bảo vệ các thành phần khỏi những thay đổi đối với các thành phần khác (đối tượng, hệ thống, hệ thống con) bằng cách tập trung vào sự không ổn định trong một giao diện và sử dụng tính đa hình để tạo ra các cách triển khai khác nhau của giao diện đó.
Chế tạo tinh khiết
Cấu trúc thuần túy bao gồm một lớp không đại diện cho một khái niệm trong miền vấn đề và được thiết kế đặc biệt để đạt được khớp nối lỏng lẻo, khớp nối cao và do đó có tiềm năng tái sử dụng tối đa (giải pháp do mẫu Chuyên gia thông tin cung cấp không đạt được điều này). Một lớp như vậy thường được gọi là “Dịch vụ” trong thiết kế hướng miền.

Sự chỉ trích

Nghiên cứu của Potok và cộng sự cho thấy không có sự khác biệt đáng kể giữa phương pháp tiếp cận OOP và phương pháp thủ tục.
Việc so sánh quan trọng giữa OOP với các công nghệ khác, đặc biệt là các công nghệ quan hệ, là rất khó do thiếu một định nghĩa về OOP được chấp nhận rộng rãi và chặt chẽ (Christopher J. Date)
So với các ngôn ngữ khác (phương ngữ LISP, ngôn ngữ chức năng, v.v.), ngôn ngữ OOP không có lợi thế riêng và áp đặt sự phức tạp không cần thiết. (Lawrence Krubner)
Tôi thấy lập trình hướng đối tượng còn yếu kém về mặt kỹ thuật. Nó cố gắng phân chia thế giới thành các phần về mặt giao diện khác nhau trong một loại duy nhất. Để giải quyết các vấn đề thực tế, bạn cần các đại số đa dạng - các họ giao diện mở rộng trên nhiều loại. Tôi thấy lập trình hướng đối tượng không lành mạnh về mặt triết học. Nó nói rằng mọi thứ đều là một đối tượng. Ngay cả khi điều này là đúng thì cũng không thú vị lắm: nói rằng mọi thứ đều là đối tượng có nghĩa là không nói gì cả. (Alexander Stepanov)
Sự phổ biến của OOP trong các công ty lớn là do "các nhóm lập trình viên tầm thường lớn (và thường xuyên thay đổi)". Kỷ luật do OOP áp đặt sẽ ngăn cản lập trình viên thực hiện “quá nhiều tác hại”. (Paul Graham)
Lập trình hướng đối tượng đặt danh từ lên hàng đầu. Tại sao lại đi đến những biện pháp cực đoan như vậy và đặt một phần lời nói lên bệ? Tại sao một khái niệm được ưu tiên hơn khái niệm khác? OOP không thể đột nhiên làm cho động từ trở nên ít quan trọng hơn đối với suy nghĩ của chúng ta. Đó là một quan điểm lệch lạc một cách kỳ lạ. (Steve Yegge)
Rick Hickey, người tạo ra Clojure, đã mô tả các hệ thống đối tượng là những mô hình cực kỳ đơn giản của thế giới thực. Ông nhấn mạnh OOP không có khả năng mô hình hóa thời gian một cách chính xác, điều này tạo ra những vấn đề lớn khi đa luồng trở nên phổ biến trong các chương trình. Eric S. Raymond, một lập trình viên Unix và người ủng hộ phần mềm nguồn mở, đã chỉ trích tuyên bố rằng OOP là "Giải pháp duy nhất" và đã viết rằng OOP khuyến khích các chương trình nhiều lớp, điều này cản trở tính minh bạch. Với cách tiếp cận ngược lại, Raymond đưa ra ví dụ về Unix và C.

Liên kết

Bởi Margaret Rouse @ WhatIs.com Wikipedia! ( Phiên bản tiếng Nga ) kế thừa là đa hình SOLID (Thiết kế hướng đối tượng) ( Phiên bản tiếng Nga ) Nguyên tắc trách nhiệm duy nhất Lập luận chống lại OOPS ( phiên bản tiếng Nga ) OOPS là gì (không cường điệu) Bản dịch: Varygin D.V.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION