Hệ thống đặt vé xem phim
Xem xét các yêu cầu
- Chúng ta muốn triển khai một hệ thống đặt vé xem phim trực tuyến.
- Phim thể hiện thông tin cơ bản về bộ phim.
- Chẳng hạn như tiêu đề, thời lượng, thông tin giá cả, v.v.
- Suất chiếu thể hiện sự kiện khán giả thực sự đến xem phim.
- Chẳng hạn như ngày chiếu, giờ chiếu, thứ tự, v.v.
- Mọi người nói rằng họ đặt vé xem phim, nhưng trên thực tế, họ nên nói rằng họ đặt vé cho một buổi chiếu phim cụ thể.chiếucủa bộ phim.
- Điều kiện giảm giá
- Có giảm giá hay không.
- Điều kiện thứ tự: Sử dụng thứ tự suất chiếu để xác định xem có giảm giá hay không.
- Điều kiện thời gian: Sử dụng giờ bắt đầu chiếu phim để xác định xem có giảm giá hay không.
- Chính sách giảm giá
- Xác định giá giảm giá.
- Chính sách giảm giá theo số tiền: Giảm một số tiền nhất định từ giá vé.
- Chính sách giảm giá theo tỷ lệ: Giảm một tỷ lệ phần trăm nhất định từ giá gốc.
- Mỗi bộ phim có thể được gán một chính sách giảm giá hoặc không có chính sách giảm giá nào, và có thể kết hợp nhiều điều kiện giảm giá.
- Nếu chính sách giảm giá được áp dụng nhưng không đáp ứng được điều kiện giảm giá, hoặc không có chính sách giảm giá nào được áp dụng, thì giá vé sẽ không được giảm.
Hướng tới lập trình hướng đối tượng
Hợp tác, đối tượng, lớp
- Lập trình hướng đối tượng là hướng tới đối tượng.
- Không nên quyết định lớp trước rồi mới suy nghĩ xem lớp đó cần những thuộc tính và phương thức nào.
- Cần quyết định những đối tượng nào sẽ có trạng thái và hành vi như thế nào.
- Không nên xem đối tượng là một thực thể độc lập, mà nên xem chúng là một phần của cộng đồng hợp tác.
Cấu trúc chương trình tuân theo cấu trúc miền vấn đề
- Miền vấn đề đề cập đến lĩnh vực mà người dùng sử dụng chương trình để giải quyết vấn đề.
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe7d22a03-4a24-40e9-8068-bd03b9fd816b%2FUntitled.png?table=block&id=3f1931fc-8ef9-470a-8189-3727146638f6&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/438;" width="2000" height="438"></span>
- Nói chung, tên của lớp nên giống hoặc ít nhất là tương tự như tên của khái niệm miền tương ứng.
- Quan hệ giữa các lớp cũng nên được tạo ra sao cho tương tự như quan hệ giữa các khái niệm miền, để chương trình dễ hiểu và dự đoán hơn.
Triển khai lớp
- Lớp được chia thành phần bên trong và bên ngoài, và để thiết kế một lớp tốt, chúng ta cần quyết định phần nào sẽ được công khai và phần nào sẽ được ẩn.
- Các thuộc tính của đối tượng được ẩn bằng private, và các phương thức cần thiết để thay đổi trạng thái bên trong được mở ra bằng public.
- Việc phân biệt bên trong và bên ngoài của lớp giúp đảm bảo tính tự trị của đối tượng, từ đó cung cấp cho lập trình viên sự tự do trong việc triển khai.
Đối tượng tự trị
- Đối tượng phải là các đối tượng tự trị có trạng thái và hành vi.
- Việc gói gọn dữ liệu và chức năng bên trong đối tượng được gọi là đóng gói.
- Việc kiểm soát truy cập giúp giảm thiểu sự can thiệp từ bên ngoài, cho phép đối tượng tự quyết định hành vi của mình.
- Nguyên tắc tách biệt giao diện và triển khai là một nguyên tắc quan trọng cần tuân thủ trong lập trình hướng đối tượng.
- Giao diện công khai: Phần có thể truy cập từ bên ngoài.
- Triển khai: Phần chỉ có thể truy cập từ bên trong.
Sự tự do của lập trình viên
- Vai trò của lập trình viên được chia thành lập trình viên tạo lớp và lập trình viên khách hàng.
- Lập trình viên tạo lớp thêm loại dữ liệu mới.
- Lập trình viên khách hàng sử dụng loại dữ liệu mà lập trình viên tạo lớp đã thêm.
- Ẩn triển khai
- Lập trình viên tạo lớp có thể ẩn triển khai bên trong bằng cách chỉ cung cấp những phần cần thiết cho lập trình viên khách hàng.
- Lập trình viên khách hàng chỉ cần biết giao diện, do đó có thể giảm lượng kiến thức cần nắm bắt.
Cộng đồng các đối tượng hợp tác
- Khi thể hiện tiền, thay vì chỉ khai báo biến kiểu Long, tốt hơn hết là nên đóng gói chúng thành đối tượng, ví dụ như Money. Sử dụng đối tượng giúp truyền tải ý nghĩa tốt hơn và có thể thực hiện xử lý các phép toán trùng lặp ở một nơi duy nhất.
- Tương tác giữa các đối tượng để thực hiện một chức năng nào đó của hệ thống được gọi là hợp tác.
Câu chuyện ngắn về hợp tác
- Cách duy nhất mà đối tượng có thể tương tác với các đối tượng khác là bằng cách gửi hoặc nhận tin nhắn.
- Phương thức riêng của đối tượng để xử lý tin nhắn nhận được được gọi là phương thức.
- Việc phân biệt giữa tin nhắn và phương thức là rất quan trọng, và từ đó, khái niệm đa hình bắt đầu xuất hiện.
Tính toán phí giảm giá
Bắt đầu hợp tác để tính toán phí giảm giá
- Lớp Movie không chứa logic chi tiết về chính sách giảm giá, mà ủy quyền cho giao diện DiscountPolicy. Việc sử dụng kế thừa, đa hình và trừu tượng hóa là vô cùng quan trọng.
Chính sách giảm giá và điều kiện giảm giá
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7b9b27a5-0dac-4ba7-9552-05b7f8fbdecd%2FUntitled.png?table=block&id=3264f189-6e12-4a55-94d2-75b851320c7a&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/535;" width="2000" height="535"></span>
Kế thừa và đa hình
Sự phụ thuộc thời gian biên dịch và sự phụ thuộc thời gian chạy
- Sự phụ thuộc của mã và thời điểm thực thi có thể khác nhau.
- Sự khác biệt giữa hai loại phụ thuộc này làm cho mã khó hiểu hơn, nhưng đồng thời cũng làm cho mã trở nên linh hoạt và có thể mở rộng hơn.
Lập trình dựa trên sự khác biệt
- Kế thừa cho phép thêm lớp mới một cách dễ dàng và nhanh chóng dựa trên lớp hiện có, đồng thời có thể tái sử dụng triển khai của lớp cha.
- Phương pháp tạo lớp mới bằng cách chỉ thêm những phần khác biệt so với lớp cha được gọi là lập trình dựa trên sự khác biệt.
Kế thừa và giao diện
- Kế thừa cho phép lớp con kế thừa tất cả các giao diện mà lớp cha cung cấp.
- Giao diện định nghĩa danh sách các tin nhắn mà đối tượng có thể hiểu.
- Movie gửi tin nhắn calculateDiscountAmount đến DiscountPolicy. Đối với Movie, nó không quan tâm đối tượng của lớp nào trả lời, miễn là trả lời thành công.
- Do đó, cả AmountDiscountPolicy và PercentDiscountPolicy đều có thể hợp tác với Movie thay cho DiscountPolicy.
- Việc lớp con thay thế cho lớp cha như vậy được gọi là ép kiểu lên (upcasting). Bởi vì nó giống như việc lớp con được tự động ép kiểu thành lớp cha ở cấp độ cao hơn.
Đa hình
- Đa hình là khả năng phản hồi khác nhau đối với cùng một tin nhắn, tùy thuộc vào kiểu của đối tượng.
- Movie gửi cùng một tin nhắn, nhưng phương thức thực sự được thực thi sẽ phụ thuộc vào lớp của đối tượng nhận được tin nhắn.
- Đa hình dựa trên thực tế là sự phụ thuộc thời gian biên dịch và thời gian chạy của chương trình có thể khác nhau.
- Đa hình xác định phương thức sẽ được thực thi tại thời điểm chạy, do đó nó được gọi là liên kết trễ hoặc liên kết động.
Giao diện và đa hình
- Nếu chúng ta không muốn chia sẻ triển khai mà chỉ muốn chia sẻ giao diện, chúng ta có thể sử dụng giao diện thay vì lớp trừu tượng.
Trừu tượng hóa và tính linh hoạt
Sức mạnh của trừu tượng hóa
- Ưu điểm của trừu tượng hóa
- Nếu chỉ xem xét cấp độ trừu tượng, chúng ta có thể mô tả chính sách yêu cầu ở cấp độ cao hơn.
- Thiết kế trở nên linh hoạt hơn.
Thiết kế linh hoạt
- Trừu tượng hóa ngăn cản thiết kế bị ràng buộc với các tình huống cụ thể, do đó có thể tạo ra thiết kế linh hoạt.
Lớp trừu tượng và giao diện: Trao đổi
- Hiện tại, NoneDiscountPolicy thực sự không cần thiết, vì phương thức calculateDiscountAmount() của DiscountPolicy đã trả về 0 nếu không có điều kiện giảm giá nào, nên không có vấn đề gì. Tuy nhiên, về phía người dùng, họ phải truyền chính sách giảm giá None vào Movie, nên đã thêm vào.
- Do đó, lớp NoneDiscountPolicy gây nhầm lẫn về mặt khái niệm, vì vậy chúng ta có thể sửa đổi như sau để dễ hiểu hơn.
- Như vậy, chúng ta sẽ trừu tượng hóa DiscountPolicy thành giao diện và chia nó thành NoneDiscountPolicy (thực thi giao diện) và DefaultDiscountPolicy (là lớp triển khai mặc định của chính sách giảm giá).
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F712983a9-3937-4265-82fe-66a144c44a0f%2FUntitled.png?table=block&id=f5ca651c-d03c-4a6c-97e9-7443ee5649a0&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/886;" width="2000" height="886"></span>
- Có thể cho rằng việc thêm giao diện riêng cho NoneDiscountPolicy sẽ làm tăng độ phức tạp mà không mang lại hiệu quả cao.
- Cần nhận thức rằng mọi thứ liên quan đến triển khai đều có thể là đối tượng của trao đổi, và cần phải thiết kế với lý do chính đáng cho mọi đoạn mã được viết. Nói cách khác, tất cả mã phải có mục đích.
Tái sử dụng mã
- Kế thừa có thể được sử dụng để tái sử dụng mã.
- Tuy nhiên, để tái sử dụng mã, tốt hơn hết là nên sử dụng tổng hợp thay vì kế thừa.
- Trong mã hiện tại, cách Movie tái sử dụng mã của DiscountPolicy chính là tổng hợp.
- Nếu chúng ta đặt Movie làm lớp cha và phân chia thành AmountDiscountMovie và PercentDiscountMovie, thì đó là sử dụng kế thừa.
Kế thừa
- Nhược điểm của kế thừa
- Vi phạm tính đóng gói.
- Cần phải hiểu rõ cấu trúc bên trong của lớp cha.
- Khả năng cao là lớp con cũng cần phải được thay đổi khi lớp cha được thay đổi.
- Làm cho thiết kế kém linh hoạt.
- Quan hệ giữa lớp cha và lớp con được xác định tại thời điểm biên dịch.
- Không thể thay đổi kiểu của đối tượng tại thời điểm chạy.
- Tuy nhiên, tổng hợp cho phép thay thế đối tượng tại thời điểm chạy thông qua các phương thức như chageDiscountPolicy() ở phía đối tượng sử dụng.
- Vi phạm tính đóng gói.
Tổng hợp
- Phương pháp tái sử dụng mã bằng cách chỉ sử dụng các tin nhắn được định nghĩa trong giao diện được gọi là tổng hợp.
- Có thể triển khai tính đóng gói và duy trì sự liên kết lỏng lẻo.
- Để sử dụng đa hình, cần phải kết hợp cả kế thừa và tổng hợp.
- Ví dụ, giao diện DiscountPolicy bắt buộc phải sử dụng kế thừa để triển khai các lớp con.
Nguồn tham khảo
- Đối tượng
Bình luận0