Một bài nghiên cứu năm 1998 đề xuất mẫu thiết kế Extensible Visitor để kết nối lập trình hàm và lập trình hướng đối tượng đã làm bùng nổ lại các cuộc thảo luận về những thách thức cơ bản trong thiết kế ngôn ngữ lập trình. Bài nghiên cứu giải quyết vấn đề được gọi là expression problem - khó khăn trong việc mở rộng cả kiểu dữ liệu và các phép toán mà không cần sửa đổi mã nguồn hiện có.
Bối cảnh thời gian (1998)
- Java đã tồn tại nhưng chưa có generics
- Scala chưa được tạo ra
- Các triển khai Haskell đã có sẵn nhưng với những hạn chế về hiệu suất
- Common Lisp Object System ( CLOS ) đã tồn tại từ những năm 1980
Thách thức lập trình cốt lõi
Nghiên cứu này giải quyết một vấn đề tồn tại lâu dài trong phát triển phần mềm: làm thế nào để mở rộng chương trình theo hai chiều đồng thời. Lập trình hàm xuất sắc trong việc thêm các phép toán mới vào các kiểu dữ liệu hiện có, trong khi lập trình hướng đối tượng giúp dễ dàng thêm các kiểu dữ liệu mới. Tuy nhiên, cả hai phương pháp đều không xử lý được cả hai loại mở rộng một cách uyển chuyển mà không cần thay đổi mã nguồn hiện có.
Mẫu thiết kế Extensible Visitor được đề xuất cố gắng kết hợp điểm mạnh của cả hai mô hình. Nó tổ chức các công cụ theo phong cách hàm trong khi sử dụng các kỹ thuật hướng đối tượng để đạt được khả năng mở rộng dữ liệu.
So sánh các Mô hình Lập trình
Phương pháp | Điểm mạnh | Hạn chế |
---|---|---|
Lập trình Hàm | Dễ dàng thêm các phép toán mới | Khó mở rộng các kiểu dữ liệu |
Lập trình Hướng đối tượng | Dễ dàng thêm các kiểu dữ liệu mới | Thách thức khi thêm phép toán qua các kiểu |
Mẫu thiết kế Visitor có thể mở rộng | Cố gắng thực hiện cả hai loại mở rộng | Triển khai phức tạp |
Hàm Generic CLOS | Đa phân phối, hàm bên ngoài | Yêu cầu hệ sinh thái Lisp |
Cộng đồng đặt câu hỏi về công nghệ tiền nhiệm
Các nhà phát triển đang đặt câu hỏi liệu giải pháp năm 1998 có bỏ qua các công nghệ hiện có hay không. Common Lisp Object System ( CLOS ) từ những năm 1980 đã cung cấp các hàm generic và khả năng multiple dispatch để giải quyết các thách thức mở rộng tương tự. CLOS đặt các hàm generic bên ngoài định nghĩa lớp, cho phép thêm các hàm mới mà không cần sửa đổi các lớp hiện có.
Một số thành viên cộng đồng lưu ý rằng type classes của Haskell , có sẵn trước năm 1998, đã cung cấp một giải pháp khác cho việc liên kết kiểu mở. Type classes đặc biệt xử lý thách thức mở rộng tập hợp kiểu mà bài nghiên cứu mô tả.
Mối quan ngại thực tế về việc mở rộng mã nguồn
Không phải ai cũng ủng hộ triết lý không bao giờ sửa đổi mã nguồn hiện có. Những người chỉ trích cho rằng việc liên tục thêm các bản vá mới mà không bao giờ tái cấu trúc dẫn đến các codebase ngày càng phức tạp và khó bảo trì.
Nếu bạn khăng khăng làm mọi thứ mà không sửa đổi mã nguồn hiện có, điều bạn đang làm là ném những mảng bùn mới lên một quả bóng bùn ngày càng lớn, và quả bóng bùn đó không giống gì với những gì bạn sẽ phát triển nếu bạn phải triển khai tất cả các yêu cầu hiện tại trên một trang giấy trắng.
Quan điểm này cho rằng đôi khi việc sửa đổi và cải thiện mã nguồn hiện có tạo ra kết quả tốt hơn so với việc giải quyết các hạn chế thông qua các mẫu thiết kế phức tạp.
Sự phát triển của ngôn ngữ hiện đại
Cuộc thảo luận nhấn mạnh cách các ngôn ngữ lập trình đã phát triển kể từ năm 1998. Java đã tồn tại nhưng thiếu generics, Scala chưa được tạo ra, và nhiều tính năng ngôn ngữ hiện đại giải quyết khả năng mở rộng vẫn đang trong quá trình phát triển. Các ngôn ngữ ngày nay cung cấp các giải pháp tinh vi hơn cho những thách thức thiết kế cơ bản này, khiến một số phương pháp lịch sử trở nên ít liên quan hơn.
Cuộc tranh luận đang diễn ra cho thấy rằng các câu hỏi thiết kế ngôn ngữ lập trình cốt lõi vẫn là những lĩnh vực nghiên cứu và thảo luận tích cực, ngay cả sau nhiều thập kỷ kể từ các đề xuất ban đầu.
Tham khảo: Synthesizing Object-Oriented and Functional Design to Promote Re-Use