1 điểm bởi geesecross 4 giờ trước | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • 「Programming as Theory Building」 của Peter Naur xem lập trình không phải là hoạt động tạo ra văn bản chương trình mà là hoạt động trong đó lập trình viên hình thành một lý thuyết về bài toán và lời giải.
  • Ở đây, “lý thuyết” không chỉ là một mệnh đề trừu tượng hay phần mô tả thiết kế đã được tài liệu hóa.
    • Đó là khả năng hiểu vấn đề trong thế giới thực mang ý nghĩa gì
    • giải thích cấu trúc chương trình tương ứng với thế giới thực đó như thế nào
    • biện minh vì sao thiết kế như vậy
    • và khi có yêu cầu mới, đánh giá cách tích hợp nó vào cấu trúc hiện có.
  • Vì vậy, tri thức cốt lõi của chương trình không được chứa trọn vẹn trong mã nguồn hay tài liệu, mà nằm trong đầu của lập trình viên hiểu chương trình đó.

Lập trình và tri thức

  • Naur xem lập trình là hoạt động ánh xạ các hoạt động trong thế giới thực thành những thao tác ký hiệu hình thức mà máy tính có thể thực hiện.
  • Theo góc nhìn này, sửa đổi chương trình cũng là một phần của lập trình.
    • Vì khi hoạt động trong thế giới thực thay đổi, chương trình cũng phải thay đổi theo.
  • Bản chất của lập trình không nằm ở tài liệu hay mã nguồn như sản phẩm đầu ra, mà ở loại tri thức đặc thù mà các lập trình viên tích lũy.
  • Tài liệu là quan trọng, nhưng chỉ mang tính hỗ trợ.
    • Tài liệu không thể thay thế hoàn toàn lý thuyết.
    • Tài liệu gần hơn với vai trò công cụ hỗ trợ việc hình thành lý thuyết.

Trường hợp 1: chuyển giao trình biên dịch và thất bại

  • Nhóm A đã tạo một trình biên dịch cho ngôn ngữ L.
  • Nhóm B, để tạo trình biên dịch cho ngôn ngữ mở rộng L + M, đã được cung cấp mã nguồn, tài liệu và lời khuyên từ trình biên dịch của A.
  • Dù mã nguồn và tài liệu đã được cung cấp đầy đủ, B vẫn không tận dụng được sức mạnh của cấu trúc hiện có trong một số thiết kế và đề xuất các lời giải vá víu.
  • A lập tức nhận ra vấn đề và đưa ra lời giải đơn giản, tự nhiên hơn trong chính cấu trúc sẵn có.
  • Điểm cốt lõi của trường hợp này:
    • Chỉ với văn bản chương trình và tài liệu thì không thể truyền đạt được lý thuyết sâu bên dưới thiết kế.
    • Cái “vì sao” của thiết kế hiện có và “mở rộng như thế nào” không thể được truyền đạt đầy đủ chỉ bằng tài liệu.
  • Sau đó, khi những lập trình viên khác không có sự hướng dẫn của A tiếp tục sửa trình biên dịch, cấu trúc mạnh ban đầu dần bị suy yếu bởi những phần bổ sung vô định hình.
  • Điều này cho thấy văn bản chương trình và tài liệu có giới hạn trong việc bảo tồn lý thuyết thiết kế cốt lõi.

Trường hợp 2: hệ thống thời gian thực quy mô lớn

  • Bài viết đưa ra trường hợp một hệ thống thời gian thực công nghiệp khoảng 200.000 dòng mã.
  • Các lập trình viên phụ trách cài đặt và chẩn đoán lỗi đã gắn bó chặt chẽ với hệ thống trong một thời gian dài ngay từ giai đoạn đầu thiết kế.
  • Khi chẩn đoán lỗi, họ chủ yếu dựa vào sự hiểu biết trực tiếp về hệ thống và mã nguồn có chú thích.
  • Trong khi đó, các lập trình viên vận hành bên ngoài dù đã được cung cấp tài liệu và đào tạo vẫn liên tục gặp khó khăn.
  • Các lập trình viên dày dạn kinh nghiệm của nhà sản xuất thì dễ dàng giải quyết các vấn đề đó.
  • Kết luận:
    • Việc bảo trì và sửa đổi các chương trình lớn về bản chất phụ thuộc vào tri thức của những người đã gắn bó lâu dài với chương trình đó.
    • Chỉ với phần giải thích đã được tài liệu hóa thì không thể thay thế hoàn toàn tri thức ấy.

Khái niệm “lý thuyết” của Ryle

  • Naur mượn khái niệm lý thuyết từ Gilbert Ryle.
  • Có một lý thuyết không đơn thuần là biết một mệnh đề.
    • Đó là biết cách làm một việc
    • có thể giải thích việc đó
    • có thể trả lời câu hỏi
    • và có thể biện minh cho phán đoán của mình.
  • Hoạt động mang tính trí tuệ không nhất thiết có thể quy giản thành hoạt động tuân theo quy tắc.
    • Bởi chính việc tuân theo quy tắc cũng phải được thực hiện một cách thông minh.
    • Nếu lại cần thêm quy tắc khác để biết cách tuân theo quy tắc, sẽ xảy ra hồi quy vô hạn.
  • Vì vậy, hoạt động trí tuệ không chỉ là thực hiện quy tắc, mà còn bao gồm khả năng nhận ra sự tương đồng giữa các tình huống và phản ứng phù hợp.

Lý thuyết không thể được biểu đạt hoàn toàn bằng quy tắc

  • Người có một lý thuyết sẽ nhận ra những điểm tương đồng có ý nghĩa giữa nhiều tình huống trong thực tế.
  • Nhưng những sự tương đồng như vậy rất khó biểu đạt đầy đủ bằng các tiêu chí rõ ràng hay các quy tắc.
  • Ví dụ:
    • sự giống nhau giữa các khuôn mặt
    • sự tương đồng giữa các giai điệu
    • sự tương đồng về hương vị của rượu vang
  • Tương tự, trong lập trình, việc nhận ra yêu cầu mới giống với cấu trúc hiện có ở điểm nào và nên tích hợp vào đâu cũng khó quy giản thành các quy tắc đơn giản.
  • Đây chính là cốt lõi của tri thức ngầm.

Lý thuyết mà lập trình viên cần có

  • Lập trình viên sở hữu lý thuyết về chương trình phải có khả năng làm những điều sau.

1. Giải thích được sự tương ứng giữa thế giới thực và chương trình

  • Phải có khả năng giải thích từng phần của chương trình tương ứng với hoạt động hay khái niệm nào trong thế giới thực.
  • Ngược lại, cũng phải có khả năng giải thích một hoạt động nào đó trong thế giới thực được biểu đạt như thế nào trong chương trình.
  • Muốn phân biệt điều gì liên quan và điều gì không liên quan, cần có sự hiểu biết về toàn bộ thế giới thực.

2. Biện minh được vì sao chương trình lại có dạng như vậy

  • Phải có khả năng giải thích vì sao cấu trúc chương trình và các chi tiết triển khai lại được thiết kế như thế.
  • Việc biện minh này có thể dùng quy tắc, suy luận, nguyên tắc thiết kế, ước lượng định lượng, v.v.
  • Tuy nhiên, cuối cùng việc quyết định áp dụng nguyên tắc nào vẫn phụ thuộc vào trực giác trực tiếp của lập trình viên.

3. Có thể phản ứng một cách xây dựng trước yêu cầu sửa đổi mới

  • Phải có khả năng nhận ra yêu cầu mới tương đồng với chức năng hay cấu trúc nào của chương trình hiện có.
  • Dựa trên sự tương đồng đó, phải có khả năng thiết kế để phần sửa đổi được tích hợp tự nhiên vào lý thuyết hiện có.
  • Khả năng này khó có thể được thay thế chỉ bằng các quy trình đã tài liệu hóa.

Sửa đổi chương trình và chi phí

  • Phần mềm tất yếu sẽ bị sửa đổi.
    • Vì trong quá trình sử dụng sẽ xuất hiện yêu cầu mới
    • và các điều kiện trong thế giới thực cũng thay đổi.
  • Người ta thường cho rằng sửa chương trình hiện có rẻ hơn làm mới.
  • Nhưng theo quan điểm của Naur, kỳ vọng này không phải lúc nào cũng đúng.
  • Chi phí sửa đổi chương trình không phải là chi phí chỉnh sửa văn bản.
    • Chi phí cốt lõi nằm ở việc hiểu lý thuyết của chương trình hiện có
    • và tích hợp yêu cầu mới vào trong lý thuyết đó.
  • Vì vậy, chỉ dựa vào việc mã nguồn là văn bản có thể chỉnh sửa dễ dàng thì không thể nói việc sửa đổi là dễ.

Giới hạn của tính linh hoạt

  • Lập luận rằng nên cài sẵn tính linh hoạt để chuẩn bị cho thay đổi trong tương lai chỉ đúng một phần.
  • Tính linh hoạt không miễn phí.
    • Phải quyết định cần chuẩn bị cho tình huống tương lai nào
    • phải thiết kế tham số và cấu trúc
    • và tốn chi phí triển khai, kiểm thử, giải thích.
  • Tính hữu ích của nó phụ thuộc vào các sự kiện tương lai bất định.
  • Vì vậy, tính linh hoạt không thể trở thành lời giải chung cho việc thích ứng với thay đổi.
  • Điều quan trọng không phải là cài sẵn cấu trúc cho mọi thay đổi, mà là năng lực đưa ra phán đoán phù hợp dựa trên lý thuyết của chương trình khi thay đổi thực sự xuất hiện.

Sửa đổi tốt và sửa đổi tệ

  • Cùng đáp ứng một hành vi bên ngoài, vẫn có thể có nhiều cách triển khai sửa đổi khác nhau.
  • Bề ngoài, tất cả có thể đều trông đúng.
  • Nhưng xét từ góc nhìn lý thuyết của chương trình thì khác biệt rất lớn.
    • Có những sửa đổi mở rộng lý thuyết hiện có một cách tự nhiên.
    • Có những sửa đổi chỉ hoạt động như một bản vá chắp thêm lên cấu trúc cũ.
  • Nếu kiểu sửa đổi thứ hai lặp lại nhiều lần, chương trình sẽ dần trở thành một mớ chắp vá.
  • Khả năng sống còn lâu dài của chương trình phụ thuộc vào mức độ mỗi lần sửa đổi bén rễ tốt thế nào trong lý thuyết hiện có.

Sự sống, cái chết và sự hồi sinh của chương trình

Sự sống của chương trình

  • Khi những lập trình viên nắm giữ lý thuyết của chương trình vẫn còn chủ động kiểm soát nó, chương trình vẫn còn sống.
  • Họ có thể phản ứng một cách trí tuệ trước các yêu cầu sửa đổi.

Cái chết của chương trình

  • Khi nhóm sở hữu lý thuyết của chương trình tan rã, chương trình chết.
  • Một chương trình đã chết vẫn có thể tiếp tục chạy và tạo ra kết quả hữu ích.
  • Nhưng cái chết đó bộc lộ ra khi nó không còn có thể đáp ứng đúng đắn các yêu cầu sửa đổi.

Sự hồi sinh của chương trình

  • Đây là nỗ lực của một nhóm mới nhằm tái xây dựng lý thuyết của chương trình hiện có.
  • Naur cho rằng điều này, theo nghĩa chặt chẽ, là bất khả thi.
  • Vì chỉ với tài liệu và mã nguồn thì không thể phục dựng hoàn toàn lý thuyết mà nhóm ban đầu từng có.
  • Dù có thể hồi sinh, việc đó vẫn tốn kém, khó khăn và rất dễ tạo ra một lý thuyết khác với lý thuyết ban đầu.
  • Trong một số trường hợp, thay vì cứu mã nguồn cũ, để nhóm mới giải quyết lại bài toán từ đầu có thể tốt hơn và rẻ hơn.

Phê phán đối với phương pháp luận

  • Naur xem phương pháp luận lập trình là “tập hợp các quy tắc quy định lập trình viên phải làm những công việc nào theo thứ tự nào”.
  • Từ góc nhìn xây dựng lý thuyết, phương pháp luận theo nghĩa đó không nắm bắt được bản chất của lập trình.
  • Lý do:
    • Việc hình thành lý thuyết không có một trình tự cố định.
    • Lý thuyết về bản chất không phải là sự kết hợp tuyến tính của các phần.
    • Ký pháp hay định dạng tài liệu có thể hỗ trợ việc hình thành lý thuyết, nhưng không phải là bản thân lý thuyết.
  • Vì vậy, có thể đi đến kết luận rằng không tồn tại một phương pháp đúng phổ quát cho hoạt động sơ cấp của lập trình.

Điều đó không có nghĩa phương pháp luận hoàn toàn vô giá trị

  • Điều Naur phủ nhận là phương pháp luận như một quy trình có thể bảo đảm thiết kế tốt theo kiểu cơ học.
  • Phương pháp luận, kỹ thuật thiết kế, ký pháp, kỹ thuật kiểm chứng vẫn có thể có giá trị giáo dục.
  • Lập trình viên quen thuộc với các trường hợp hay, nguyên lý cấu trúc và kỹ thuật kiểm chứng sẽ có khả năng hình thành lý thuyết tốt hơn.
  • Tuy nhiên, việc áp dụng kỹ thuật nào, khi nào và theo thứ tự nào phải được giao cho phán đoán của lập trình viên đã hiểu vấn đề thực tế.

Vị thế của lập trình viên

  • Nếu xem lập trình như sản xuất công nghiệp, lập trình viên sẽ bị đối xử như những bộ phận có thể thay thế.
  • Đó là quan điểm cho rằng chỉ cần tuân theo thủ tục và quy tắc thì ai cũng có thể tạo ra cùng một kết quả.
  • Naur bác bỏ quan điểm này.
  • Nếu sản phẩm cốt lõi của chương trình là lý thuyết mà lập trình viên nắm giữ, thì lập trình viên không phải là lao động dễ dàng thay thế.
  • Lập trình viên gần với một nghề chuyên môn chịu trách nhiệm phát triển và quản lý toàn bộ hoạt động có bao gồm máy tính.
  • Vì vậy, lập trình viên cần được trao vị thế và trách nhiệm lâu dài.
  • Việc giáo dục cũng phải vượt qua phạm vi ngữ pháp, ký pháp và kỹ thuật xử lý dữ liệu đơn thuần để hướng tới rèn luyện năng lực hình thành lý thuyết.

Ẩn dụ trong XP và việc hình thành lý thuyết

  • “Ẩn dụ” trong XP được giải thích rất rõ qua góc nhìn xây dựng lý thuyết của Naur.
  • Một ẩn dụ tốt giúp cả nhóm có những dự đoán tương tự nhau về cấu trúc chương trình.
  • Ví dụ:
    • hiểu chương trình như một “dây chuyền lắp ráp”
    • hiểu chương trình như một “nhà hàng”
  • Một ẩn dụ tốt không chỉ là ví von đơn giản.
    • Nó giúp người thiết kế biết nên kỳ vọng cấu trúc nào
    • nên thêm mã mới vào đâu
    • và nên đánh giá việc nó ăn khớp với mã do người khác viết như thế nào.
  • Càng nhiều thành viên và càng nhiều công việc song song, giá trị của một ẩn dụ được chia sẻ càng lớn.
  • Nếu không có lý thuyết chung, mỗi lập trình viên sẽ tự xây dựng lý thuyết riêng của mình, và hệ thống sẽ ngày càng thiếu nhất quán, ngày càng phức tạp.

Vai trò của tài liệu

  • Tài liệu khó có thể theo kịp hoàn toàn trạng thái hiện tại của chương trình.
  • Nhưng điều đó không có nghĩa tài liệu là không cần thiết.
  • Mục đích của tài liệu không phải là ghi lại mọi thứ, mà là giúp lập trình viên kế tiếp hình thành một lý thuyết phù hợp.
  • Tài liệu tốt sẽ khơi gợi trí nhớ và kinh nghiệm của người đọc, đồng thời mở ra con đường tư duy đúng đắn.
  • Loại tài liệu như vậy bền hơn những tài liệu chỉ đơn thuần liệt kê các class, function và module hiện tại.

Cấu thành của một tài liệu thiết kế tốt

  • Các nhà thiết kế dày dạn kinh nghiệm thường bắt đầu tài liệu bằng những mục sau.
    • Ẩn dụ cốt lõi
    • giải thích mục đích của các thành phần chính
    • sơ đồ các tương tác cốt lõi giữa những thành phần chính
  • Ba điều này giúp ích rất nhiều cho nhóm kế tiếp trong việc hình thành lý thuyết thiết kế.
  • Bản thân mã nguồn cũng là một phương tiện truyền đạt lý thuyết.
    • cách đặt tên nhất quán
    • cấu trúc đơn giản
    • các mẫu hình dễ dự đoán
    • giảm thiểu các ngoại lệ không cần thiết
  • Phần lớn của “mã sạch” liên quan đến việc người đọc có thể dễ dàng hình thành một lý thuyết nhất quán về hệ thống đến mức nào.

Chưa có bình luận nào.

Chưa có bình luận nào.