... Và có lẽ là một trong những bài viết mà OOP dựa trên.
Không thực sự, nhưng nó đã thêm vào cuộc thảo luận, đặc biệt với các học viên rằng, vào thời điểm đó, được đào tạo để phân hủy các hệ thống bằng cách sử dụng các tiêu chí đầu tiên mà anh mô tả trong bài báo.
Đầu tiên tôi muốn biết nếu đánh giá của tôi là chính xác. Liệu mô hình FP và bài viết này không đồng ý về mặt triết học?
Không. Ngoài ra, trong mắt tôi, mô tả của bạn về một chương trình FP trông như thế nào không khác với bất kỳ chương trình nào sử dụng các quy trình hoặc chức năng:
Dữ liệu được truyền từ chức năng này sang chức năng khác, mỗi chức năng đều nhận thức sâu sắc về dữ liệu và "thay đổi nó" trên đường đi.
... Ngoại trừ phần "thân mật", vì bạn có thể (và thường làm) có các chức năng hoạt động trên dữ liệu trừu tượng, chính xác để tránh sự thân mật. Do đó, bạn có một số quyền kiểm soát đối với "sự thân mật" đó và bạn có thể điều chỉnh nó theo cách bạn muốn, bằng cách thiết lập giao diện (ví dụ: các hàm) cho những gì bạn muốn ẩn.
Vì vậy, tôi thấy không có lý do tại sao chúng tôi sẽ không thể tuân theo các tiêu chí che giấu thông tin của Parnas bằng lập trình chức năng và kết thúc bằng việc thực hiện một chỉ số KWIC với lợi ích nhọn tương tự như cách thực hiện thứ hai của anh ấy.
Giả sử họ đồng ý, tôi muốn biết việc triển khai ẩn dữ liệu của FP là gì. Rõ ràng để thấy điều này trong OOP. Bạn có thể có một trường riêng mà không ai ngoài lớp có thể truy cập. Không có sự tương tự rõ ràng về điều này với tôi trong FP.
Đối với dữ liệu là mối quan tâm, bạn có thể xây dựng trừu tượng dữ liệu và trừu tượng loại dữ liệu bằng cách sử dụng FP. Bất kỳ trong số này ẩn các cấu trúc cụ thể và thao tác của các cấu trúc bê tông này bằng cách sử dụng các hàm làm trừu tượng.
CHỈNH SỬA
Có một số lượng lớn các xác nhận ở đây nói rằng "ẩn dữ liệu" trong bối cảnh của FP không hữu ích lắm (hoặc OOP-ish (?)). Vì vậy, hãy để tôi đóng dấu ở đây một ví dụ rất đơn giản và rõ ràng từ SICP:
Giả sử hệ thống của bạn cần phải làm việc với các số hữu tỷ. Một cách bạn có thể muốn biểu diễn chúng là một cặp hoặc một danh sách gồm hai số nguyên: tử số và mẫu số. Như vậy:
(define my-rat (cons 1 2)) ; here is my 1/2
Nếu bạn bỏ qua việc trừu tượng hóa dữ liệu, rất có thể bạn sẽ nhận được tử số và mẫu số bằng cách sử dụng car
và cdr
:
(... (car my-rat)) ; do something with the numerator
Theo cách tiếp cận này, tất cả các bộ phận của hệ thống thao túng các số hữu tỷ sẽ biết rằng một số hữu tỷ là một cons
- chúng sẽ đánh cons
số để tạo ra các số hữu tỷ và trích xuất chúng bằng cách sử dụng các toán tử danh sách.
Một vấn đề bạn có thể gặp phải là khi bạn cần giảm một dạng số hữu tỷ - những thay đổi sẽ được yêu cầu trên toàn bộ hệ thống. Ngoài ra, nếu bạn quyết định giảm thời gian tạo, bạn có thể thấy rằng việc giảm khi truy cập một trong các điều khoản hợp lý sẽ tốt hơn, mang lại sự thay đổi toàn diện khác.
Một vấn đề khác là nếu, theo giả thuyết, một đại diện thay thế cho chúng được ưa thích và bạn quyết định từ bỏ cons
đại diện - thay đổi toàn bộ quy mô một lần nữa.
Bất kỳ nỗ lực lành mạnh nào trong việc xử lý các tình huống này có thể sẽ bắt đầu che giấu sự đại diện của các lý trí đằng sau các giao diện. Cuối cùng, bạn có thể kết thúc với một cái gì đó như thế này:
(make-rat <n> <d>)
trả về số hữu tỷ có tử số là số nguyên <n>
và mẫu số của chúng là số nguyên <d>
.
(numer <x>)
trả về tử số của số hữu tỉ <x>
.
(denom <x>)
trả về mẫu số của số hữu tỷ <x>
.
và hệ thống sẽ không còn (và không còn nữa) biết những gì hợp lý được tạo ra. Điều này là bởi vì cons
, car
và cdr
không phải là nội tại đối với các lý trí, nhưng make-rat
, numer
và denom
là . Tất nhiên, đây có thể dễ dàng là một hệ thống FP. Vì vậy, "ẩn dữ liệu" (trong trường hợp này, được gọi là trừu tượng hóa dữ liệu, hoặc nỗ lực đóng gói các biểu diễn và cấu trúc cụ thể) là một khái niệm có liên quan và một kỹ thuật được sử dụng và khám phá rộng rãi, cho dù trong bối cảnh của OO, lập trình chức năng hay bất cứ điều gì.
Và vấn đề là ... mặc dù người ta có thể cố gắng phân biệt giữa "loại ẩn" hoặc đóng gói mà họ đang làm (cho dù họ đang che giấu một quyết định thiết kế, hoặc cấu trúc dữ liệu hoặc thuật toán - trong trường hợp trừu tượng hóa thủ tục), tất cả chúng đều có cùng một chủ đề: chúng được thúc đẩy bởi một hoặc nhiều điểm mà Parnas đưa ra rõ ràng. Đó là:
- Khả năng thay đổi: cho dù các thay đổi cần thiết có thể được thực hiện cục bộ hoặc được lan truyền qua hệ thống.
- Phát triển độc lập: đến mức độ nào hai phần của hệ thống có thể được phát triển song song.
- Tính toàn diện: cần biết bao nhiêu hệ thống để hiểu một trong các bộ phận của nó.
Ví dụ trên được lấy từ cuốn sách SICP vì vậy, để thảo luận và trình bày đầy đủ về các khái niệm này trong cuốn sách, tôi khuyên bạn nên kiểm tra chương 2 . Tôi cũng khuyên bạn nên làm quen với các kiểu dữ liệu trừu tượng trong ngữ cảnh của FP, điều này mang đến các vấn đề khác cho bảng.