2009-02-18 14 views
13

Nếu tôi thêm một lớp chữ hoa mới, điều đó có nghĩa là tôi cần phải tìm kiếm qua tất cả các mã mẫu phù hợp và tìm ra nơi mà lớp mới cần phải được xử lý? Gần đây tôi đã học ngôn ngữ, và khi tôi đọc về một số đối số và chống lại sự khớp mẫu, tôi đã nhầm lẫn về nơi nó nên được sử dụng. Thấy như sau:Khớp mẫu của Scala có vi phạm Nguyên tắc Mở/Đóng không?

Pro: Odersky1Odersky2

Côn: Beust

Các ý kiến ​​là khá tốt trong từng trường hợp, quá. Vì vậy, là mô hình phù hợp với một cái gì đó để được vui mừng về hoặc một cái gì đó tôi nên tránh sử dụng? Trên thực tế, tôi tưởng tượng câu trả lời là "nó phụ thuộc vào khi bạn sử dụng nó", nhưng một số trường hợp sử dụng tích cực cho nó là gì và một số tiêu cực là những gì?

+0

Liên kết Beust bị hỏng, dường như làm thay đổi lược đồ URL. Tôi đã cố gắng xem liệu tôi có thể tìm ra bài đăng nào được dự định không, nhưng tôi không chắc chắn. Vui lòng cung cấp liên kết đã sửa hoặc một số thông tin khác để tiếp tục (tiêu đề của bài đăng là gì?). –

Trả lời

22

Jeff, tôi nghĩ bạn có trực giác đúng: tùy theo điều đó.

Phân cấp lớp hướng đối tượng với phương thức ảo là tốt khi bạn có một bộ phương pháp tương đối cố định cần được triển khai, nhưng nhiều lớp con tiềm năng có thể kế thừa từ gốc của cấu trúc phân cấp và triển khai các phương thức đó. Trong một thiết lập như vậy, tương đối dễ dàng để thêm các lớp con mới (chỉ cần thực hiện tất cả các phương thức), nhưng tương đối khó thêm các phương thức mới (bạn phải sửa đổi tất cả các lớp con để đảm bảo chúng thực hiện đúng phương thức mới).

Loại dữ liệu có chức năng dựa trên đối sánh mẫu là tốt khi bạn có một nhóm lớp tương đối cố định thuộc về kiểu dữ liệu, nhưng có nhiều chức năng hoạt động trên loại dữ liệu đó. Trong một thiết lập như vậy, việc thêm chức năng mới cho kiểu dữ liệu tương đối dễ dàng (chỉ khớp mẫu trên tất cả các lớp của nó), nhưng tương đối khó thêm các lớp mới là một phần của kiểu dữ liệu (bạn phải sửa đổi tất cả các hàm phù hợp trên kiểu dữ liệu để đảm bảo chúng hỗ trợ đúng lớp mới).

Ví dụ kinh điển cho cách tiếp cận OO là lập trình GUI. Các yếu tố GUI cần hỗ trợ rất ít chức năng (vẽ bản thân trên màn hình là tối thiểu), nhưng các phần tử GUI mới được thêm vào mọi lúc (các nút, bảng, biểu đồ, thanh trượt, vv). Ví dụ kinh điển cho cách tiếp cận đối sánh mẫu là trình biên dịch. Ngôn ngữ lập trình thường có cú pháp tương đối cố định, vì vậy các phần tử của cây cú pháp sẽ thay đổi hiếm khi (nếu có), nhưng các hoạt động mới trên cây cú pháp liên tục được thêm vào (tối ưu hóa nhanh hơn, phân tích kỹ lưỡng hơn, vv).

May mắn thay, Scala cho phép bạn kết hợp cả hai cách tiếp cận. Cả hai trường hợp có thể là mẫu phù hợp và hỗ trợ gửi phương thức ảo. Các lớp thông thường hỗ trợ việc gửi phương thức ảo và có thể là mẫu khớp nhau bằng cách xác định một trình trích xuất trong đối tượng đồng hành tương ứng. Việc lập trình viên quyết định khi nào mỗi phương pháp phù hợp, nhưng tôi nghĩ cả hai đều hữu ích.

16

Trong khi tôi tôn trọng Cedric, anh ấy hoàn toàn sai về vấn đề này. Kết hợp mẫu của Scala có thể được đóng gói hoàn toàn từ các thay đổi của lớp khi muốn. Mặc dù sự thay đổi đối với trường hợp trường hợp sẽ yêu cầu thay đổi bất kỳ trường hợp khớp mẫu nào tương ứng, đây chỉ là khi sử dụng các lớp như vậy một cách ngây thơ.

Khớp mẫu của Scala luôn là đại biểu cho bộ giải mã của đối tượng đồng hành của lớp. Với một lớp vỏ, trình giải mã này được tạo tự động (cùng với một phương thức factory trong đối tượng đồng hành), mặc dù vẫn có thể ghi đè lên phiên bản được tạo tự động này. Tại mọi thời điểm, bạn có thể khẳng định toàn quyền kiểm soát quá trình khớp mẫu, cách ly bất kỳ mẫu nào từ những thay đổi tiềm năng trong chính lớp đó. Do đó, đối sánh mẫu đơn giản là một cách khác để truy cập dữ liệu lớp thông qua bộ lọc đóng gói an toàn, giống như bất kỳ phương thức nào khác. Vì vậy, ý kiến ​​của Tiến sĩ Odersky sẽ là người tin cậy ở đây, đặc biệt là với khối lượng nghiên cứu tuyệt đối mà ông đã thực hiện trong lĩnh vực lập trình và thiết kế hướng đối tượng.

Đối với nơi cần sử dụng, điều đó hoàn toàn tùy theo khẩu vị. Nếu nó làm cho mã của bạn ngắn gọn và dễ bảo trì hơn, hãy sử dụng nó! Nếu không, đừng. Đối với hầu hết các chương trình hướng đối tượng, đối sánh mẫu là không cần thiết. Tuy nhiên, một khi bạn bắt đầu tích hợp thêm các thành ngữ chức năng (Option, List, v.v.) Tôi nghĩ bạn sẽ thấy rằng việc khớp mẫu sẽ làm giảm đáng kể cú pháp cú pháp cũng như cải thiện độ an toàn được cung cấp bởi hệ thống kiểu. Nói chung, bất kỳ lúc nào bạn muốn trích xuất dữ liệu trong khi đồng thời kiểm tra một số điều kiện (ví dụ: trích xuất một giá trị từ Some), có thể sử dụng mẫu phù hợp.

1

Kết hợp mẫu chắc chắn là tốt nếu bạn đang lập trình chức năng. Trong trường hợp OO, có một số trường hợp nó tốt. Trong ví dụ của Cedric, nó phụ thuộc vào cách bạn xem phương thức print() một cách khái niệm. Đó có phải là hành vi của từng đối tượng Term không? Hay nó ở bên ngoài nó? Tôi sẽ nói nó ở bên ngoài, và có ý nghĩa để làm khớp mẫu. Mặt khác, nếu bạn có một lớp Employee với các lớp con khác nhau, đó là một lựa chọn thiết kế kém để thực hiện khớp mẫu trên một thuộc tính của nó (nói tên) trong lớp cơ sở.

Ngoài ra mẫu phù hợp cung cấp một cách thanh lịch để giải nén các thành viên của một lớp học.