Dijkstra có ý định mô đun hóa mã, khi ông viết về việc tách các mối quan tâm?


9

Đầu tiên, tôi đọc một đoạn trích của Edsger W. Dijkstra năm 1974 "Về vai trò của tư tưởng khoa học":

Hãy để tôi cố gắng giải thích cho bạn, những gì theo sở thích của tôi là đặc trưng cho tất cả những suy nghĩ thông minh. Đó là, người ta sẵn sàng nghiên cứu sâu về một khía cạnh của vấn đề của một người để cô lập vì sự nhất quán của chính mình, tất cả thời gian biết rằng người ta chỉ chiếm giữ bản thân mình với một trong những khía cạnh. Chúng tôi biết rằng một chương trình phải chính xác và chúng tôi chỉ có thể nghiên cứu nó từ quan điểm đó; chúng tôi cũng biết rằng nó sẽ hiệu quả và chúng tôi có thể nghiên cứu hiệu quả của nó vào một ngày khác, có thể nói như vậy. Trong một tâm trạng khác, chúng tôi có thể tự hỏi mình liệu, và nếu vậy: tại sao, chương trình là mong muốn. Nhưng không có gì đạt được ngược lại! - bằng cách giải quyết các khía cạnh khác nhau này cùng một lúc. Đó là điều mà đôi khi tôi đã gọi là "sự tách biệt các mối quan tâm", mà, ngay cả khi không hoàn toàn có thể, vẫn là kỹ thuật duy nhất có sẵn để sắp xếp hiệu quả những suy nghĩ của một người mà tôi biết. Đây là điều tôi muốn nói bằng cách "tập trung sự chú ý của một người vào một khía cạnh nào đó": nó không có nghĩa là bỏ qua các khía cạnh khác, nó chỉ thực sự công bằng với thực tế là từ quan điểm của khía cạnh này, khía cạnh khác là không liên quan. Nó đang được suy nghĩ một và nhiều theo dõi cùng một lúc.

Tôi thấy sự phân tách hiện đại của các mối quan tâm nói về việc mô đun hóa mã của bạn. Tuy nhiên, đọc đoạn trích dẫn trên, tôi hiểu điều này như tập trung tâm trí của bạn vào một nhiệm vụ cụ thể tại một thời điểm, trong khi không tập trung vào các khía cạnh khác. Điều này không có nghĩa với tôi nhất thiết là mã cần phải được tách thành các khối mô-đun.

Đó là, giả sử có một mã trước mặt bạn rằng trong một tệp có các khái niệm về chế độ xem, kho lưu trữ, bộ điều khiển, xử lý sự kiện, nhà máy, v.v ... tất cả trong một tệp.

Ví dụ ngắn gọn, đây là một số mã có quyền truy cập dữ liệu và chế độ xem (đầu ra):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

Sử dụng OO hiện đại Tôi có thể đặt quyền truy cập dữ liệu vào tệp riêng của mình bằng mẫu Kho lưu trữ, mã Xem có thể đi vào mẫu tệp của chính nó và tôi có thể kết nối chúng với nhau để liên lạc qua bộ điều khiển (hoặc Trình xử lý hành động hoặc yêu cầu) và tôi có thể thêm một nhà máy để tạo và kết nối các phụ thuộc khác nhau. Và tôi có thể có một tập tin cấu hình xác định các nhà máy đó. Chắc chắn đó là một bước đi từ tất cả các tập tin duy nhất.

Câu hỏi của tôi về việc phân tách các mối quan tâm là như vậy: đọc trích dẫn của Dijkstra, tôi có một ý tưởng rằng có lẽ anh ta không nhất thiết phải phân tách các mối quan tâm là "tách mã theo mô-đun (thành các tệp hoặc các chức năng / phương thức / v.v." của họ), " và rằng anh ta có ý nghĩa nhiều hơn để tập trung tâm trí của một người vào một khía cạnh của chương trình, mà không phải gánh nặng tập trung vào các khía cạnh quan trọng khác nhưng chưa được xem xét, bất kể họ có bị tách biệt về mặt vật lý hay không.

Tại sao sau đó chúng ta phải gánh nặng với các mẫu thiết kế và phân tách mã mô-đun vật lý? Sẽ không đủ để chỉ tập trung vào một khía cạnh, bất kể mã của bạn được cấu trúc như thế nào?

Tôi không nói về việc viết ra mã spaghetti khủng khiếp nhất và sau đó chỉ xem xét một khía cạnh của nó, đó có thể sẽ là một gánh nặng. Nhưng cuối cùng, điều tôi sẽ hướng tới là tại sao lại thực hiện phân tách mã vật lý, tại sao lại chia mã thành các tệp hoặc khối riêng biệt (phương thức), khi không cần thiết phải tập trung tinh thần vào một khía cạnh?

Có nên tách các mối quan tâm vẫn là một bài tập tinh thần, hơn là thể chất?
Nói cách khác, có nên có sự ngắt kết nối giữa các khía cạnh tinh thần (tập trung vào) và các khía cạnh vật lý (mã trên giấy) của lập trình?


5
Tôi khá chắc chắn rằng vào năm 1974, anh ta chỉ xem lập trình mô-đun là một điều hiển nhiên, và đó là lý do tại sao anh ta không thảo luận rõ ràng về nó trong bài báo đó. Bài viết của Parnas về cách mô đun hóa là vào năm 1972, và vào thời điểm đó liệu có nên mô đun hóa hay không đã là một câu hỏi. Trên thực tế, những gì bạn mô tả thậm chí không phải là lập trình mô-đun, đó là lập trình có cấu trúc , mà chính Dijkstra đã lập luận mạnh mẽ ủng hộ vào năm 1968 trong bài báo "Đi đến được coi là có hại" kinh điển của ông.
Jörg W Mittag

được rồi vì vậy có lẽ tôi có thể hiểu "tách mối quan tâm" nhiều hơn như một bài tập trung tâm trí, và mô đun hóa như một cách để gói gọn một khía cạnh của mã trên giấy. Tuy nhiên bây giờ tôi thấy sự tách biệt các mối quan tâm và mô đun hóa nhiều hơn như các khái niệm riêng biệt.
Dennis

@ JörgWMittag, bạn có thể định nghĩa sự khác biệt giữa lập trình có cấu trúc và mô đun không? Một số liên kết trên google cho thấy chúng giống nhau.
Dennis

Structured = IF, WHILE, FORthay vì GOTO. Modular = các mô-đun với API công khai được xác định rõ ràng tách biệt với việc triển khai và biểu diễn bên trong ẩn. (Ví dụ: Modula, Mesa, Modula-2, Modula-3, phương ngữ Pascal sau này ( UNIT).)
Jörg W Mittag

Câu trả lời:


2

Dijkstra đang đưa ra một tuyên bố rõ ràng về cách suy nghĩ. Chương trình (và quy trình) mô đun hóa - và đó là mong muốn - có lẽ là kết quả của suy nghĩ đó, nhưng điểm mấu chốt mà anh ta đang làm là làm thế nào để đánh giá một vấn đề. Chương trình này thường là giải pháp cho một vấn đề và bằng cách ủng hộ một "sự tách biệt các mối quan tâm", ông đang đưa ra lời khuyên khôn ngoan. Ví dụ tốt nhất về điều này có lẽ là "tối ưu hóa". Trò đùa là: "Khi lập kế hoạch để tối ưu hóa một chương trình, chiến lược đầu tiên của bạn là: Đừng." Nói cách khác, bạn muốn tập trung vào đầu tiên làm cho chương trình chính xác. Làm cho nó nhanh và lạ mắt là một mối quan tâm cần được tách ra - nhưng cũng không hoàn toàn loại bỏ.


14

Tách biệt các mối quan tâm là một cách suy nghĩ trừu tượng bao gồm việc xem xét riêng những thứ không phải liên quan.

Modularisation (tách nhóm chức năng không liên quan thành các mô-đun), đóng gói (ẩn chi tiết bên trong của các mô-đun) và trừu tượng hóa (tách biệt chung với cụ thể và ý tưởng từ việc thực hiện) đều là phương tiện để thực hiện cách suy nghĩ này trong miền thiết kế phần mềm.


9

Tôi sẽ đề nghị rằng, trong khi bài báo là mối quan tâm lịch sử, thì Dijkstra có nghĩa gì với thuật ngữ "tách mối quan tâm" hơn 40 năm trước không đặc biệt liên quan ngày nay. Ngày nay, nó được sử dụng rộng rãi để tham khảo điều chế.

Có rất nhiều bằng chứng cho thấy việc điều tiết là vô cùng có lợi và những lợi ích đó vượt xa "gánh nặng" mà nó đặt lên chúng ta. Dù Dijkstra có ý gì hồi đó, không thay đổi thực tế là các đoạn mã nhỏ, mỗi đoạn chỉ tập trung vào một thứ, dẫn đến mã dễ viết, đọc, hiểu, duy trì và kiểm tra hơn.


5
Tôi nghĩ rằng cần lưu ý rằng phần lớn suy nghĩ hiện đại về Tách biệt mối quan tâm đến từ những bài báo ban đầu cuối cùng đã sinh ra Lập trình định hướng theo khía cạnh từ IBM. Tôi nghĩ rằng các giấy tờ ban đầu (cuối thập niên 90 đến đầu những năm 2000) là ảnh hưởng lớn nhất ở đó. Đã được một lúc và các trang web đã thay đổi. Không chắc chắn nếu tôi thậm chí có thể tìm thấy chúng một lần nữa.
Berin Loritsch

2
Phần khó là cố gắng xác định "một điều" có nghĩa là gì. Không có điều đó, ý tưởng này là vô ích về mặt viết mã thực tế và việc hiểu sai ngay lập tức có tác động bất lợi đến khó khăn trong việc viết, đọc, hiểu, duy trì và kiểm tra mã.
jpmc26

1
Nó thực sự sẽ giúp chúng tôi hiểu vị trí của bạn nếu bạn (a) giải thích những gì bạn nghĩ Dijkstra có nghĩa là "tách mối quan tâm" và (b) giải thích TẠI SAO bạn nghĩ rằng những gì anh ta nói không còn phù hợp.
John R. Strohm

2

Tôi có thể cho bạn một ví dụ cá nhân về sự tách biệt các mối quan tâm mà tôi nghĩ là có thể so sánh với các khái niệm của Dijkstra. Khi tôi phân tích một vấn đề cụ thể trong phần mềm, tôi xây dựng ba khung nhìn.

  1. Đầu tiên tôi xem xét dữ liệu. Dữ liệu đại diện cho các vị từ logic của vấn đề. Các lớp được xây dựng cho các thực thể trừu tượng trong thế giới thực, với các thuộc tính của chúng là các tham số của sự trừu tượng hóa. Liên kết giữa các lớp thể hiện ánh xạ chức năng giữa các thể hiện của lớp. Không có mã liên quan đến suy nghĩ tại thời điểm này và không có khái niệm về bất kỳ xử lý. Chỉ là một cái nhìn tĩnh về logic liên quan đến vấn đề.
  2. Thứ hai tôi xem xét các động lực. Bất kỳ lớp nào có vòng đời không tầm thường đều được mô hình hóa như một máy trạng thái hữu hạn. Điều này liên quan đến việc xem xét thực hiện tuần tự và đồng bộ hóa. Một lần nữa, không có mã nào chỉ tìm ra cách mọi thứ tương tác và trình tự.
  3. Thứ ba tôi xem xét việc xử lý. Ở đây, công việc thuật toán thực tế phải được thực hiện khi chuyển trạng thái hoặc trong các hoạt động đồng bộ khác.

Cuối cùng, người ta có được một cái nhìn ba mặt về vấn đề mà sau đó có thể được coi là mã trong bất kỳ nhóm nào thuận tiện cho chính mã và bảo trì của nó. Ba khía cạnh không chỉ là một bài tập tinh thần. Tôi sản xuất mô tả bằng văn bản của tất cả các khía cạnh. Tại sao? Bởi vì nếu đối tượng đủ lớn, tôi không thể giữ ngay cả một khía cạnh hoàn chỉnh trong bộ nhớ ngắn hạn. Nếu đối tượng là nhỏ, hầu như mọi cách tiếp cận sẽ hoạt động vì bạn có thể giữ tất cả trong đầu.

Động lực để phân tách các mối quan tâm là để khắc phục những hạn chế về trí nhớ ngắn hạn của con người. Chúng ta chỉ đơn giản là không thể mang mọi thứ trong đầu cùng một lúc, mặc dù các lập trình viên máy tính có xu hướng có khả năng cao hơn hầu hết những người khác ở số lượng khái niệm họ có thể thao tác trong bộ nhớ ngắn hạn. Để có hiệu quả, tách các mối quan tâm phải có hệ thốngloại trừ một hoặc nhiều khía cạnh của một vấn đề để tập trung vào một số khía cạnh cụ thể khác. Tất nhiên, loại trừ một khía cạnh không làm cho nó biến mất khỏi xem xét. Phải có một phương tiện để kết hợp tất cả các khía cạnh vấn đề để đạt được một giải pháp. Kinh nghiệm cho thấy thường kết quả cuối cùng của việc tách và kết hợp lại mang lại một giải pháp dễ hiểu hơn một bước nhảy khổng lồ duy nhất trong đó nhiều khía cạnh có thể bị xáo trộn với nhau. Điều này đặc biệt là trường hợp khi kích thước của vấn đề lớn hoặc phức tạp.


1

Tách các mối quan tâm là một khái niệm logic sẽ truyền vào mô hình tổ chức mã của bạn cho dù bạn triển khai nó như thế nào. Đúng là một tệp mã chỉ là một chi tiết kỹ thuật, một cách để giữ cho bạn có thể quản lý phần mềm. Một tệp duy nhất có trình chỉnh sửa tốt cho phép thu gọn sự mở rộng các vùng cũng có thể phù hợp với bạn (trong một thời gian). Hoặc một cơ sở dữ liệu quan hệ lưu trữ các lớp và phương thức theo kiểu cha-con trong các bảng riêng biệt có thể hoạt động như một phương tiện lưu trữ. Nhưng các tệp văn bản rất khó bị đánh bại trong một thế giới nơi mã nguồn cần phải có

  • xách tay
  • có thể truy cập bằng nhiều công cụ bên ngoài khác nhau
  • có thể truy cập bởi nhiều lập trình viên
  • phiên bản và so sánh
  • mở rộng quy mô với các hệ điều hành xảy ra rất tốt trong việc xử lý tệp

Điểm mấu chốt là con người chúng ta không giỏi suy nghĩ hoặc xử lý các vấn đề khác nhau cùng một lúc. Vì vậy, chúng ta cần một mô hình cho phép suy nghĩ và làm việc tại một thời điểm mà không có nguy cơ làm hỏng một số phần khác mà chúng ta không xem xét tại thời điểm đó. Vì vậy, chúng tôi xây dựng, đặt từng viên gạch một lần, đảm bảo những viên gạch chúng tôi đặt trước đó sẽ không can thiệp vào những viên gạch được đặt sau đó. Và nếu chúng ta muốn thay đổi một viên gạch sau này, mọi thứ không được sụp đổ. Đó là một mô hình hoạt động cho tâm trí một đường của chúng tôi.

Đây không phải là cách mà nấm hoặc tảo phát triển mặc dù ... Làm thế nào mà cho một sự thật khiêm nhường?


-1

Tuy nhiên, tôi tin rằng câu trả lời cụ thể cho trích dẫn của Dijkstra đã được giải quyết, vì bạn nêu rõ "Sử dụng OO hiện đại, tôi có thể đặt quyền truy cập dữ liệu vào tệp riêng của mình" và hỏi "Có nên tách biệt các mối quan tâm, thay vì vật lý?" hãy để tôi chú ý đến nơi mà các hiệu trưởng OO hiện đại hướng dẫn chúng tôi.

Người ta phải tuân theo các nguyên tắc RẮN trong việc phát triển bằng OO. Đây là một liên kết tốt đẹp cho họ, nhưng, TLDR về "phân tách mối quan tâm" chủ yếu nằm ở S trong RẮN: Nguyên tắc Trách nhiệm duy nhất hoặc SRP.

Điều này, chắc chắn nhất, là một bài tập thể chất, không phải là một tinh thần. Ví dụ bạn cụ thể, MVC (hoặc nó anh chị em MVVM và MVP) chỉ đạo một đến thể chất tách các buổi hòa nhạc của Model, View, và Controller / Presenter / ViewModel vào các tập tin riêng biệt. Tôi đã thấy một số triển khai MVVM trong đó chúng được triển khai thành các cụm riêng biệt để tiếp tục hạn chế xu hướng "trộn lẫn các khái niệm" của một người.

Nhưng. Nó vượt xa chỉ đơn giản "đây là một góc nhìn và đây là một mô hình", nếu bạn làm theo quan điểm của chú Bob về điều này.

Người ta cũng cần xem xét nguồn gốc của các yêu cầu đối với bất kỳ yếu tố OO cụ thể nào. Nếu bạn đang trộn, giả sử, những gì Khách hàng muốn với những gì Nhân viên Hoạt động muốn, thì bạn cũng vi phạm SRP. Hoặc, để đặt nó như chú Bob làm: Một Lớp nên có một và chỉ một lý do để thay đổi.

Tôi đặc biệt khuyên bạn nên nghiên cứu thêm về việc sử dụng các liên kết được cung cấp hoặc thực hiện tìm kiếm trên web cho "các nguyên tắc vững chắc".


Các nguyên tắc RẮN cho đến nay vẫn bị ngắt kết nối với thực tế viết mã (= triết học) đến mức chúng chỉ có thể được hiểu theo bất kỳ cách hữu ích từ xa nào một khi bạn đã biết cách viết mã tốt, tại thời điểm đó chúng là dự phòng tốt nhất. Sử dụng chúng làm nguyên tắc hướng dẫn mà không có kinh nghiệm và khả năng tạo ra mã cực kỳ kém.
jpmc26
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.