CodeGym /Các khóa học /Python SELF VI /Mọi thứ đều là đối tượng

Mọi thứ đều là đối tượng

Python SELF VI
Mức độ , Bài học
Có sẵn

1.1 Đối tượng và lớp

Hôm nay bạn sẽ tìm hiểu về cấu trúc của một chương trình điển hình trên Python. Và tin vui là: mỗi chương trình trên Python bao gồm các lớp và đối tượng. Python là một ngôn ngữ hướng đối tượng, và mọi thứ trong đó đều là đối tượng: số, chuỗi, hàm và thậm chí cả các lớp cũng là đối tượng.

Vậy thì lớp là gì nhỉ?

Để mình bắt đầu bằng một phép so sánh. Hãy tưởng tượng bạn muốn làm một chiếc tàu nhỏ. Đầu tiên cần làm bản vẽ, sau đó đưa nó đến nhà máy, nơi mà theo bản vẽ đó sẽ lắp ráp chiếc tàu. Hoặc một chục. Thật ra, bao nhiêu chiếc tàu tùy ý bạn. Theo một bản vẽ có thể sản xuất hàng chục tàu giống hệt nhau, đó là điều quan trọng.

Trong lập trình Python mọi thứ cũng tương tự.

Bản vẽ

Lập trình viên giống như một nhà thiết kế. Chỉ có điều nhà thiết kế vẽ bản vẽ, còn lập trình viên Python viết lớp. Sau đó từ bản vẽ tạo ra các chi tiết, còn từ lớp tạo ra các đối tượng.

Đầu tiên chúng ta viết lớp (làm bản vẽ), và sau đó, trong quá trình thực thi chương trình, dựa trên các lớp này, Python tạo ra các đối tượng. Giống hệt như tàu được tạo ra từ bản vẽ.

Một bản vẽ, nhưng có thể có nhiều tàu. Tàu khác, có tên khác, vận chuyển hàng khác nhau. Nhưng chúng rất giống nhau: tất cả đều là tàu có cấu trúc giống hệt và có thể thực hiện các nhiệm vụ tương tự.

Hay như một phép so sánh khác...

Tổ kiến

Tổ kiến là một ví dụ tốt về sự tương tác giữa các đối tượng. Trong tổ kiến đơn giản có ba loại kiến: nữ hoàng, binh lính và kiến công nhân.

Số lượng kiến thuộc mỗi loại khác nhau. Nữ hoàng có một con trên tổ kiến, binh lính có hàng chục con, còn kiến công nhân có hàng trăm. Ba loại và hàng trăm đối tượng. Kiến tương tác với nhau, với những con kiến tương tự và kiến thuộc loại khác theo những quy tắc cứng nhắc.

Đây là ví dụ hoàn hảo. Trong một chương trình điển hình mọi thứ cũng tương tự. Có một đối tượng chính, tạo ra các đối tượng thuộc các lớp khác. Các đối tượng bắt đầu tương tác với nhau và với "thế giới bên ngoài" của chương trình. Bên trong những đối tượng này có hành vi được lập trình cứng nhắc.

Hai ví dụ này là hai mặt của cùng một vấn đề. Sự thật nằm ở giữa. Ví dụ đầu tiên (về bản vẽ và tàu) cho thấy mối liên hệ giữa lớp và các đối tượng của lớp đó. Phép so sánh rất mạnh mẽ. Ví dụ thứ hai (về tổ kiến) cho thấy mối liên hệ giữa các đối tượng tồn tại trong quá trình chạy của chương trình và các lớp đã viết.

Đầu tiên bạn phải viết các lớp cho tất cả các đối tượng tồn tại trong chương trình, và sau đó mô tả sự tương tác giữa chúng. Nghe có vẻ phức tạp, nhưng nó dễ hơn bạn nghĩ.

Trong Python, tất cả các thực thể trong quá trình chạy của chương trình đều là đối tượng, và viết chương trình đưa đến việc mô tả các phương pháp tương tác khác nhau giữa các đối tượng. Các đối tượng chỉ gọi phương thức của nhau và truyền qua các dữ liệu cần thiết.

Tài liệu

Vậy làm thế nào để biết những dữ liệu cần truyền vào các phương thức? Tất cả đã được nghĩ đến trước bạn rồi.

Thông thường mỗi lớp có một mô tả, trong đó cho biết nó được tạo ra để làm gì. Thông thường, mỗi phương thức công khai đều có mô tả: nó làm gì và cần truyền những dữ liệu nào vào nó.

Để sử dụng lớp, bạn cần biết tổng quan về những gì nó làm. Và cũng cần biết chính xác những gì mỗi phương thức của nó làm. Hoàn toàn không cần phải biết nó làm như thế nào. Giống như một chiếc đũa phép vậy.

Hãy xem qua mã — sao chép tệp:


src = open('source.txt', 'r')
dst = open('destination.txt', 'w')
            
for line in src:
    dst.write(line)
            
src.close()
dst.close()
        

Nếu đọc dòng mã này từng dòng, bạn có thể đoán được nó làm gì trong tổng quan. Mặc dù cần có kinh nghiệm và thực hành. Vì vậy, sau một thời gian mã này sẽ trở nên quen thuộc và dễ hiểu đối với bạn.

1.2. Thiết kế chương trình

Thiết kế chương trình là một nghệ thuật. Nó vừa dễ vừa khó đồng thời. Dễ, vì không có luật lệ nào cứng nhắc cả: mọi thứ không bị cấm thì được phép. Và cũng khó vì lý do này: có rất nhiều cách để làm điều gì đó, và không dễ để tìm ra phương pháp tốt nhất.

Thiết kế chương trình giống như viết một cuốn sách. Một mặt, bạn chỉ viết chữ, từ, câu. Nhưng mặt khác, câu chuyện quan trọng, tính cách nhân vật, mâu thuẫn nội tâm, xung đột, phong cách kể chuyện, intrigue v.v.

Điều quan trọng là hiểu, bạn viết mã cho ai. Hãy nhớ rằng mã của bạn dành cho các lập trình viên khác.

Phát triển bất kỳ sản phẩm nào là quá trình chỉnh sửa: thêm vào đây, xóa bỏ kia, làm lại chỗ này. Và như vậy, qua các vòng lặp nhỏ, các dự án lớn, khổng lồ và vĩ đại ra đời.

Yêu cầu chính đối với mã — nó phải dễ hiểu đối với các lập trình viên khác. Mã sai nhưng dễ hiểu có thể sửa chữa được. Mã đúng đắn nhưng khó hiểu thì không thể cải thiện được. Nó chỉ có thể bị vứt đi thôi.

Vậy làm thế nào để viết mã tốt và dễ hiểu?

Để làm điều này bạn cần làm ba điều:

  • Viết mã tốt và dễ hiểu trong các phương thức — điều đơn giản nhất.
  • Quyết định những thực thể nào nên có trong chương trình.
  • Phân chia chương trình thành các phần logic đúng cách.

Vậy điều gì đứng sau những khái niệm này?

Viết mã tốt trong các phương thức

Nếu bạn có ít nhất cấp độ tiếng Anh cơ bản, có thể bạn đã nhận thấy rằng mã thường dễ đọc như những câu tiếng Anh:

  • class Cat(Pet) – lớp Cat mở rộng từ lớp Pet.
  • while stream: – khi dòng chưa rỗng ...
  • a if a < b else b – nếu a nhỏ hơn b, trả về a, ngược lại trả về b.

Điều này được thực hiện cố ý. Python là một trong số ít ngôn ngữ, mà trong đó dễ dàng viết mã tự tài liệu hóa: mã dễ hiểu mà không cần chú thích. Trong mã tốt của Python, nhiều phương thức đọc như những câu tiếng Anh.

Nhiệm vụ của bạn khi viết mã là làm cho nó đơn giản và gọn gàng nhất có thể. Hãy suy nghĩ xem mã của bạn có dễ đọc không, và bạn sẽ bắt đầu đi đúng hướng.

Trong Python, người ta thường viết mã dễ đọc. Tốt nhất mỗi phương thức nên nằm hoàn toàn trên màn hình (độ dài phương thức — 20-30 dòng). Đây là tiêu chuẩn cho toàn bộ cộng đồng Python. Nếu mã có thể cải thiện, nó nên được cải thiện.

Cách tốt nhất để học viết mã tốt là thực hành liên tục. Viết nhiều mã, nghiên cứu mã của người khác, yêu cầu đồng nghiệp có kinh nghiệm hơn đánh giá mã của bạn. Và hãy nhớ rằng, khi bạn nói với bản thân "vậy cũng được", sự phát triển của bạn sẽ dừng lại.

Quyết định những thực thể nào nên có trong chương trình

Bạn cần viết mã mà người khác có thể hiểu được. Nếu 9 trong số 10 lập trình viên thiết kế chương trình sẽ tạo ra các lớp A, B và C, thì bạn cũng nên tạo ra các lớp A, B và C trong chương trình của mình. Bạn phải viết mã mà người khác có thể hiểu được.

Mã tuyệt vời, hoạt động, nhanh, không chuẩn là mã xấu.

Bạn cần nghiên cứu các dự án của người khác: đây là cách tốt nhất, nhanh nhất và dễ nhất để tiếp thu sự tinh hoa đã tích lũy trong ngành công nghệ thông tin qua nhiều thập kỷ.

Và tình cờ, bạn đã có sẵn một dự án tuyệt vời, phổ biến, được tài liệu hóa tốt — Python SDK. Hãy bắt đầu với nó.

Phân tích các lớp và cấu trúc lớp. Hãy nghĩ về lý do tại sao một số phương thức được thực hiện như là static, còn những phương thức khác thì không. Tại sao phương thức có những tham số đó, mà không là những tham số khác. Tại sao lại là những phương thức này, tại sao lớp có tên như vậy và nằm trong các package nhất định.

Khi bạn bắt đầu hiểu câu trả lời cho tất cả những câu hỏi này, bạn sẽ có thể viết mã mà người khác có thể hiểu.

Tuy nhiên, mình muốn cảnh báo bạn không nên phân tích mã trong các phương thức của Python SDK. Mã của nhiều phương thức đã được viết lại để tối ưu tốc độ hoạt động — khả năng đọc hiểu của nó là một vấn đề lớn.

Phân chia chương trình thành các phần logic đúng cách

Bất kỳ chương trình nào thường được chia thành các phần hoặc module. Mỗi phần chịu trách nhiệm về một khía cạnh riêng của chương trình.

Như máy tính có bộ phận hệ thống, màn hình, bàn phím, tất cả đều là những phần tách biệt, có ít sự phụ thuộc lẫn nhau. Hơn nữa, sự tương tác giữa chúng đã được chuẩn hóa: USB, HDMI v.v. Nhưng nếu bạn đổ cà phê lên bàn phím, bạn có thể chỉ cần rửa nó bằng nước, làm khô và sử dụng lại.

Còn laptop là một ví dụ về kiến trúc monolithic: các phần logic dường như có, nhưng tích hợp mạnh mẽ hơn nhiều. Ví dụ, để làm sạch bàn phím trên Macbook Pro, bạn cần tháo rời một nửa laptop. Mà đổ cà phê lên laptop sẽ là lý do để đặt hàng một cái mới. Chỉ không phải là cà phê thôi.

1.3 Tạo lớp riêng

Khi bạn mới bắt đầu lập trình, quan trọng là bắt đầu từ những việc nhỏ — học cách tạo ra các lớp riêng.

Chắc chắn bạn đã từng tạo ra chúng, nhưng bạn cần học cách hiểu lớp nào nên có trong chương trình, chúng nên được đặt tên như thế nào, chúng nên có các phương thức nào. Và chúng nên tương tác với nhau như thế nào.

Danh sách các thực thể

Nếu bạn không biết bắt đầu từ đâu, hãy bắt đầu từ đầu.

Vào lúc bạn bắt đầu thiết kế chương trình, bạn có thể chỉ cần viết ra một danh sách các thực thể (đối tượng) cần có trong chương trình. Sau đó lập trình chúng theo nguyên tắc: mỗi thực thể là một lớp riêng biệt.

Ví dụ

Giả sử bạn muốn viết một trò chơi cờ vua. Bạn sẽ cần các thực thể như: bàn cờ và 6 loại quân cờ. Quân cờ di chuyển khác nhau, có giá trị khác nhau — logic là đây là các lớp riêng biệt. Và thực sự, ban đầu, càng có nhiều lớp thì càng tốt.

Gặp một lập trình viên mới mà thay vì hai lớp sẽ viết mười là rất hiếm. Còn thay vì viết mười lớp mà viết hai, hay thậm chí một — là điều mà người mới yêu thích. Vì vậy, càng nhiều lớp, các lập trình viên. Và mã của bạn sẽ trở nên rõ ràng hơn đối với tất cả mọi người, trừ có lẽ là bạn 😛

Cờ vua

Giả sử chúng ta quyết định viết các lớp cho cờ vua: các lớp này sẽ trông như thế nào?

Bàn cờ vua chỉ là một mảng 8 x 8? Tốt hơn là bạn tạo ra một lớp riêng dành cho nó, trong đó lưu trữ liên kết đến mảng. Sau đó trong lớp "bàn cờ vua" bạn có thể thêm nhiều phương thức hữu ích, ví dụ, kiểm tra ô trống hay đã có quân cờ.

Nói chung, lúc đầu bạn có thể tuân theo nguyên tắc này: Chương trình có các Thực thể khác nhau, và mỗi Thực thể có kiểu riêng. Và loại này — chính là lớp.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION