2 điểm bởi GN⁺ 2024-02-17 | 2 bình luận | Chia sẻ qua WhatsApp
  • Ngay cả khi không thể cung cấp chức năng thực tế vì một nền tảng cụ thể hoặc trạng thái đã ngừng hỗ trợ, để các ứng dụng hiện có không bị hỏng, cần thiết kế hành vi “không làm gì” trong phạm vi hợp đồng API đã được tài liệu hóa
  • Trong môi trường không có hạ tầng in ấn như Xbox, phản hồi thành công với 0 máy in sẽ an toàn hơn cho các ứng dụng được viết theo giả định trên PC so với NotSupportedException
  • Cách này là inert API: thiết kế giữ nguyên bề mặt API và đặc tả, nhưng thực tế không thực hiện công việc hữu ích nào
  • Với API widget đang bị ngừng hỗ trợ, nếu CreateWidget thành công nhưng trả về nullptr, bên gọi sẽ gặp trạng thái mâu thuẫn; vì vậy đường dẫn thất bại ERROR_CANCELLED đã được tài liệu hóa sẽ nhất quán hơn
  • Một inert API đúng cách chỉ làm biến mất chức năng, đồng thời dùng các đường dẫn thất bại mà mã hiện có đã chuẩn bị để giảm ngoại lệ, handle sai và crash

Ngay cả khi không còn chức năng, hợp đồng API vẫn còn

  • Có những trường hợp phải làm cho API không làm gì cả, nhưng trạng thái không hoạt động đó cũng phải phù hợp với mã hiện có và hành vi đã được tài liệu hóa
  • Một thiết kế không hoạt động sai có thể tạo ra ngoại lệ, giá trị trả về mâu thuẫn hoặc trạng thái không hợp lệ, dẫn đến ứng dụng crash hoặc lỗi người dùng không cần thiết

Cách vô hiệu hóa API in ấn trên Xbox

  • Windows có hạ tầng in ấn rộng khắp, nhưng Xbox không có hạ tầng đó
  • Nếu một ứng dụng cố gắng in trên Xbox và hàm in ném NotSupportedException, vấn đề có thể trở nên nghiêm trọng hơn
    • Các ứng dụng được cài trên Xbox nhiều khả năng chủ yếu đã được kiểm thử trên PC
    • Trên PC, việc in luôn khả dụng, nên một ngoại lệ không được xử lý có thể khiến ứng dụng crash
    • Ngay cả khi bắt ngoại lệ, người dùng có thể thấy thông báo lỗi như “hãy cung cấp incident code cho đội hỗ trợ”
  • Thiết kế tốt hơn là hàm in thành công nhưng báo rằng không có máy in nào được cài đặt
    • Ứng dụng mở UI chọn máy in và hiển thị danh sách trống
    • Người dùng thấy rằng không có máy in và có thể hủy yêu cầu in
  • Với ứng dụng cố hỗ trợ cài máy in, hàm cài đặt có thể trả về ngay với mã kết quả có nghĩa là người dùng đã hủy thao tác

Điều kiện của inert API

  • Hành vi “không làm gì” như vậy được gọi là inert
  • Inert API là API mà bề mặt API vẫn tồn tại nguyên vẹn và hoạt động đúng theo đặc tả, nhưng thực tế không làm công việc hữu ích nào
  • Điểm cốt lõi là không làm gì theo cách nhất quán với tài liệu và ít có khả năng gây vấn đề nhất cho mã hiện có
  • Với API in ấn, cũng có thể thêm một hàm kiểm tra xem bản thân việc in có khả dụng hay không
    • Ứng dụng có thể dùng hàm này để ẩn nút Print trên các hệ thống hoàn toàn không hỗ trợ in
    • Ngay cả các ứng dụng chỉ đơn giản giả định có thể in cũng sẽ hoạt động như trong “một hệ thống không có máy in và việc thử cài đặt cũng không có tác dụng”

Thiết kế cần tránh trong API widget đang ngừng hỗ trợ

  • API thuộc diện ngừng hỗ trợ có một hàm tạo handle widget, một hàm nhận handle widget và một hàm đóng handle widget
  • Đề xuất ban đầu là để CreateWidget trả về S_OK đồng thời đặt *widget = nullptr
    • Lời gọi thành công nhưng không nhận được handle hợp lệ
    • Trong mã kiểm thử thực tế, có đoạn xác định thành công hay không dựa trên việc handle có null hay không, chứ không dựa trên giá trị trả về
  • Thiết kế để EnableWidget trả về “handle không hợp lệ” cũng khiến bên gọi bối rối
    • Ứng dụng truyền handle nhận được sau khi CreateWidget thành công vào EnableWidget
    • API đáp rằng handle đó không hợp lệ
    • Bên gọi gặp trạng thái mâu thuẫn: “đã yêu cầu widget và đã nhận được, nhưng khi đưa lại thì bị bảo đó không phải widget”

Thiết kế được sửa bằng đường dẫn thất bại đã được tài liệu hóa

  • Tài liệu hiện có có giá trị trả về ERROR_CANCELLED, mang nghĩa người dùng đã hủy việc tạo widget
  • Ứng dụng vốn đã phải xử lý khả năng widget không được tạo do điều kiện bên ngoài, nên có thể làm cho việc tạo widget luôn thất bại dưới dạng người dùng hủy
  • Luồng của thiết kế đã sửa rất đơn giản
    • CreateWidget để *widget = nullptr và trả về HRESULT_FROM_WIN32(ERROR_CANCELLED)
    • Vì việc tạo widget luôn thất bại, không tồn tại handle widget hợp lệ nào
    • GetWidgetAliases, EnableWidget, Close trả về E_HANDLE, nghĩa là handle không hợp lệ
  • Theo cách này, vì không có widget, cũng không cần tạo alias giả
    • Do không tồn tại widget hợp lệ, cũng không có trường hợp ứng dụng có thể yêu cầu alias một cách bình thường

Tiêu chí khi đưa API desktop sang môi trường khác

  • Trên desktop, API in ấn luôn tồn tại, và hàm “lấy danh sách máy in” được tài liệu hóa là không ném ngoại lệ
  • Khi đưa API này sang Xbox, nếu muốn các ứng dụng desktop hiện có tiếp tục chạy, hành vi inert trả về một cách trung thực rằng “Xbox không có máy in” là phù hợp
  • Ném ngoại lệ cho câu hỏi “có bao nhiêu máy in?” không phù hợp với hợp đồng API đã được tài liệu hóa
  • Nguyên tắc tương tự cũng áp dụng khi ngừng hỗ trợ một API hiện có
    • Dù không làm công việc hữu ích, hành vi của API vẫn phải nhất quán với hợp đồng
    • Điều quan trọng là dùng các giá trị trả về và trạng thái mà mã hiện có đã có thể xử lý

2 bình luận

 
GN⁺ 2024-02-17
Ý kiến trên Lobste.rs
  • Ý ở đây là các chức năng in hoạt động nhất quán như thể việc in được hỗ trợ hoàn toàn, nhưng kỳ lạ là sẽ không bao giờ có máy in thật để in, và như vậy thì giải thích được khá nhiều điều
    Nói đùa vậy thôi, tôi không đồng ý với kiểu lập trình và trải nghiệm người dùng phòng thủ quá mức như thế này. Làm vậy thì phần mềm sẽ không làm đúng việc của nó mà người dùng cũng không biết vì sao, lại càng không có cách nào để tìm ra. Ứng dụng nên bắt lỗi và nếu có thể thì tạo thông báo thân thiện với người dùng, nếu không thì ít nhất cũng phải hiển thị thông báo lỗi gốc cho người dùng. Nếu là tác vụ nền thì phải có nhật ký lỗi
    Tôi công nhận bài này được viết từ góc nhìn của nhà phát triển API chứ không phải nhà phát triển ứng dụng. Vậy thì cần tài liệu hóa lỗi API và cung cấp thông báo lỗi để phía gọi có thể xử lý
    Tôi cũng không thích việc ẩn nút trong UI chỉ vì không có quyền truy cập. Nếu không gian cho phép thì tốt hơn nên hiện nút nhưng vô hiệu hóa nó, và khi người dùng rê chuột vào thì hiển thị thông điệp cho biết làm thế nào để kích hoạt nó
    • Cũng cần lưu ý rằng bài này không chỉ từ góc nhìn của một nhà phát triển API bình thường mà là của nhà phát triển Windows API. Từ lâu Microsoft đã giữ lập trường rằng Windows API không được phá vỡ khả năng tương thích chỉ vì phiên bản thay đổi
    • Đây là một cuộc thảo luận điển hình về Định luật Postel / nguyên tắc tính bền vững. Giờ thì ai cũng biết nguyên tắc tính bền vững đã lỗi thời và đã sinh ra những quái vật như HTML hay các giao thức/định dạng tệp khổng lồ khiến việc viết parser đúng đắn trở nên khó khăn
      Nhìn chung, yêu cầu tính chính xác vẫn tốt hơn. Tuy nhiên, nếu bạn đã có 1 tỷ người dùng hiện hữu thì việc tránh làm hỏng họ nhiều nhất có thể là lựa chọn rất khôn ngoan, và từ góc nhìn người dùng thì cứ chạy được là tạo ra giá trị thực ở cấp hệ thống. Cuối cùng, thái độ nên là thất bại sớm, nhưng đừng để thất bại hàng loạt
    • Trong trường hợp này, có vẻ một trong các API hiện có không có lỗi được tài liệu hóa, nên rất có thể ngay từ đầu đã không có xử lý lỗi. Nếu không muốn làm hỏng toàn bộ phần mềm hiện có thì phải nói dối vì mục đích tốt
      Chuyện này gần với độ ổn định ABI hơn là API. Trên Windows, phần mềm được build từ 15 năm trước vẫn phải tiếp tục chạy được trên hệ điều hành mới càng nhiều càng tốt. Bạn không thể thay đổi chữ ký hàm, nên nếu muốn những API không còn ý nghĩa nữa vẫn tiếp tục hoạt động thì phải dùng những lời nói dối thiện ý
      Ví dụ, API vẫn giả vờ như Active Desktop còn tồn tại, vì lựa chọn khác là làm hỏng hàng loạt phần mềm cũ đang tồn tại
    • Tôi thật sự đồng ý. Không có gì bực bội bằng việc loay hoay tìm một nút mà vì lý do nào đó không hiện trên màn hình của tôi, trong khi người ngồi bên cạnh giải thích hoặc trong tutorial lại thấy nó
      Khi đó bạn không thể biết là tính năng ấy đã biến mất hay chỉ bị chôn ở một màn hình khác trong lúc đó
    • Đúng là ứng dụng nên bắt lỗi và hiển thị cho người dùng.
      Nhưng nếu ứng dụng không làm vậy, thì người dùng ứng dụng đó sẽ đổ lỗi cho Windows. Họ đổ lỗi cho Windows chứ không phải cho ứng dụng, và ngay cả khi ứng dụng bị crash cũng thế
      Vì vậy Microsoft mới tạo ra các giải pháp vòng vo. Cứ để tác vụ in tự biến mất thì dễ hơn nhiều, và rồi người dùng sẽ nghĩ một lát rồi chấp nhận rằng “à đúng rồi, mình đâu có máy in”
  • Nếu hàm cài đặt máy in có thể trả về ngay lập tức và trả mã kết quả là người dùng đã hủy thao tác, thì từ góc độ hỗ trợ ứng dụng, gần như chắc chắn điều đó sẽ dẫn đến hành vi ngoài ý muốn còn khó xử lý hơn nhiều so với việc API in ném ngoại lệ ngay từ đầu
  • Dạo này tôi dùng lập trình có trợ giúp bởi AI khá nhiều, và thấy agent thường hay chèn các kiểm tra if để kiểm tra null. Mỗi lần thấy vậy tôi lại nhớ đến bài này
    Vì thế tôi đã bảo agent đừng lặp đi lặp lại kiểm tra null, mà hãy dùng các hàm vô hại và chỉ xác nhận một lần tại thời điểm khai báo rằng giá trị chắc chắn không bao giờ là null
 
GN⁺ 2024-02-17
Các ý kiến trên Hacker News
  • Tôi học được rằng đây là cách nuốt lỗi, và cho rằng đó là một thực hành không tốt
    Nó không chỉ không giải quyết được vấn đề thực tế là không thể in trên Xbox, mà còn che giấu mức độ hỏng hóc của phần mềm, khiến việc phát hiện lỗi và kiểm thử khó hơn nhiều
    panic của Go tốt ở chỗ nó không được tạo ra để bị lạm dụng hoặc phục hồi trong runtime, mà là công cụ hú còi thật to ở thời điểm kiểm thử để báo rằng lập trình viên đã làm sai
    Nếu các tác nhân trong hệ thống chủ động che giấu khiếm khuyết hoặc lỗi của chính mình, việc tìm ra nguyên nhân và sửa chữa sẽ khó lên theo cấp số nhân

    • Thiết kế lỗi phụ thuộc vào ngữ cảnh
      Trong các hệ thống B2B, microservice, lấy API làm trung tâm mà tôi xử lý, các yêu cầu ngoài đặc tả nên được cho fail nhanh
      Nhưng Windows đã phải uốn mình rất nhiều để giữ tương thích, và còn có những trường hợp cứu phần mềm nổi tiếng bị lỗi như SimCity bằng cả cách vá bộ nhớ: https://arstechnica.com/gadgets/2022/10/windows-95-went-the-...
      Trong môi trường desktop nơi người dùng không thể sửa mã hệ thống, trải nghiệm người dùng cuối trong nhiều trường hợp quan trọng hơn tính đúng đắn
      Microsoft đã học được rằng lý do gây BSOD không quan trọng; phần mềm hay phần cứng tệ vẫn làm xấu đi danh tiếng của Microsoft
      Cá nhân tôi thích thiết kế fail nhanh hoặc dừng ngay khi gặp đầu vào hay điều kiện sai, nhưng cũng hiểu giá trị của cách tiếp cận này trong môi trường đó
      Điều quan trọng là ngữ cảnh, chứ không phải áp dụng một phía nào đó một cách giáo điều
      Ví dụ, không nên mang cách tiếp cận của Chen vào thiết kế lò phản ứng hạt nhân hay giao dịch tần suất siêu cao, còn với engine game thì đó có thể là một cách rất hay
    • Khi thiết kế một runtime thay thế cho nền tảng mới, điều cốt lõi là tự quyết định cái gì được xem là lỗi
      Việc quyết định có để một thành phần runtime ở trạng thái “vô hại nhưng bất hoạt” hay không là một quyết định thiết kế có trước chuyện phần triển khai có panic hay không
      Trong trường hợp này, việc định nghĩa “in trên Xbox” nghĩa là gì thuộc về Microsoft
      Có thể định nghĩa đó là lỗi, hoặc về mặt lý thuyết có thể định nghĩa là một chức năng sau này hỗ trợ được nhưng hiện chưa có cách thực hiện thực tế
      Nếu cắm máy in USB và “game” biết cách in, chẳng hạn như cổng mở rộng của trò chơi Gameboy từng hỗ trợ GB Printer, thì về lý thuyết Xbox cũng có thể in
      Việc một game Xbox thử in không nhất thiết là lỗi về bản chất; định nghĩa nó là lỗi cũng chỉ là một lựa chọn có các đánh đổi như tính di động của ứng dụng
      Có thể hiện màn hình chọn nhưng không có máy in nào để chọn như trên Xbox, có thể khiến API nói dối rằng đã in, hoặc cũng có thể hỗ trợ in thật
      Chỉ sau khi đã định nghĩa ý nghĩa của “in trên Xbox” là lỗi, việc lỗi đó không được ném ra mà bị nuốt mới trở thành vấn đề triển khai hay gỡ lỗi
    • Đây không phải là nuốt lỗi, mà theo cách nói của Linux thì gần hơn với việc không phá vỡ user space
      Có hai cách xử lý khả dĩ: báo lỗi vì máy chắc chắn không bao giờ có máy in, hoặc trả về danh sách máy in rỗng vì máy chắc chắn không bao giờ có máy in
      Cả hai đều hợp lý, nhưng chỉ có một cách là không phá vỡ user space
    • Đọc bài thì thấy họ đang nói về trải nghiệm người dùng nhiều hơn trải nghiệm nhà phát triển
      “Hú còi thật to” thì tốt cho tester hay developer, nhưng không hay lắm với người dùng cuối
      Với người dùng cuối, nuốt lỗi vẫn tốt hơn là ứng dụng chết
    • Thật bực mình khi suốt mấy chục năm nay, mỗi khi kết nối Internet thất bại thì chỉ hiện mỗi thông báo rằng nó đã thất bại
      Không thể biết cái gì đã hỏng: phần mềm trên máy tính của tôi, phần cứng, cáp Ethernet hay Wi‑Fi, switch, router, modem cáp, đường cáp Internet kéo tới nhà, ISP, hay hệ thống từ xa mà tôi đang cố truy cập; chuyện này chẳng được cải thiện chút nào
  • Việc phản ứng tiêu cực là có thể đoán trước, nhưng chính những chuyện bừa bộn như thế này là lý do khi bạn bấm vào tài liệu Word ’97 hay một trò chơi được biên dịch cho MS-DOS từ 30 năm trước, nó vẫn mở như bạn kỳ vọng
    Tương thích ngược luôn messy, và chỉ có hai lựa chọn: làm không hoàn hảo, hoặc không làm gì cả

    • Tôi hay nghe điệp khúc đó về Microsoft, nhưng với game thì không may mắn như vậy
      Cuối cùng phải dùng GOG, và GOG rốt cuộc cũng ảo hóa môi trường
      Ví dụ, tôi không nghĩ sẽ có ai cài được bản Sim City gốc trên Windows 11 thành công
    • Tệp được tạo bằng Word ’97 ngay cả 25 năm trước cũng không mở đúng như kỳ vọng trên hai máy tính khác nhau
      Định dạng phụ thuộc vào driver máy in đã cài
      Trong khi đó, tệp LaTeX từ 35 năm trước đến nay vẫn chạy tốt
    • Ngay cả tệp năm 1997 cũng phải may mắn mới được, và mở bằng bất kỳ ứng dụng office nào cũng rất có thể trông sai
      Word từng không thể đảm bảo rằng định dạng sẽ không thay đổi ngay cả khi mở lại trên cùng máy tính và cùng phiên bản, nên tôi đã học TeX
      Game cũng vậy, Microsoft đã làm hỏng vô số game khi đóng GFWL
      Bản Dark Souls gốc không thể chơi được cho đến khi được phát hành lại trên Steam, nên phải dùng bản lậu
    • Trên Windows 64-bit hiện đại, phần mềm MS-DOS không chạy được
      Một hộp thoại “không được hỗ trợ” sẽ hiện ra, và bạn có thể tải dosbox, nhưng như thế không phải là “đúng như kỳ vọng”
    • Giá mà điều này đúng thì tốt, nhưng tôi đã cực kỳ vất vả để chạy lại những game lưu giữ từ thời thơ ấu
      Gần như lần nào cũng phải bỏ cuộc hoặc mua lại trên GOG; thực chất là trả tiền cho công sức đã dọn dẹp các vấn đề tương thích
  • Không gì khó chịu bằng một UI thiết bị ám chỉ rằng những thiết bị đó có thể thực sự tồn tại, nhưng hiện tại lại báo là không có
    Rốt cuộc phải mất thời gian mới phát hiện ra rằng các thiết bị đó không được hỗ trợ, và màn hình kia chỉ là một mockup do ai đó dựng ra

    • Dù vậy chắc vẫn đỡ khó chịu hơn việc ứng dụng cứ chết luôn
      Nếu ứng dụng không chuẩn bị cho trường hợp không hỗ trợ in/xuất mà thao tác xuất lại ném exception, ứng dụng có lẽ sẽ chết ngay
      Một ứng dụng có chuẩn bị cho việc không hỗ trợ in/xuất thì nên dùng API tường minh để kiểm tra trước xem có hỗ trợ hay không, và nếu không được hỗ trợ thì không nên hiển thị UI in/xuất
      Bài viết không nói về loại ứng dụng đó, mà nói về cách xử lý những ứng dụng không kiểm tra trước
      Lỗi nằm ở ứng dụng, nhưng một nền tảng tốt nên cố gắng làm cho cả ứng dụng tệ vẫn chạy được, thay vì cứ để nó chết
    • Ở đây, trách nhiệm lớn có thể thuộc về người viết phần mềm vì đã không xử lý tình huống máy in, chứ không phải Microsoft
      Vai trò của Microsoft là đảm bảo ứng dụng không chết chỉ vì nhà cung cấp phần mềm đã không tính đến máy in
  • Việc khi ứng dụng muốn in thì yêu cầu người dùng chọn máy in rồi hiển thị một danh sách trống — có vẻ Microsoft đã không học được gì trong 30 năm: https://www.reddit.com/r/hacking/comments/djvzd/windows_nt_l...

  • Hướng cụ thể mà bài viết đề xuất, tức là trước khi người dùng chịu khổ thì thành phần phải chịu khổ, là đúng, nhưng cách framing rất khó chịu
    Những câu kiểu “có lúc nên làm cho API không làm gì cả”, “hàm in/xuất ném NotSupportedException là sai” tuyệt đối không phải lời khuyên chung
    Đây là một hack để hỗ trợ các client tệ, đôi khi cần thật, nhưng không phải lời khuyên bình thường hay có thể khái quát hóa
    Cách diễn đạt này cho thấy dấu vết của việc nội tâm hóa nỗi khổ trong vai trò lập trình viên Microsoft

    • Không phải client tệ, mà là client được viết trước khi bạn quyết định thay đổi này
      Nếu client không thay đổi mà API lại làm hỏng nó, thì thứ tệ không phải client mà là API
    • Nếu một nền tảng phần mềm đã được nhiều hơn một nhóm nhỏ lập trình viên chấp nhận, chắc chắn sẽ có cả ứng dụng tệ, và khi đó phải làm những việc như thế này
      Với mọi nền tảng được chấp nhận rộng rãi và xem trọng tương thích ngược, đây là việc hoàn toàn bình thường và có thể khái quát hóa
      Windows là ví dụ tiêu biểu, nhưng chuyện tương tự cũng xảy ra với Linux kernel ABI, glibc, nền tảng web, Java, v.v.
    • Có lúc bạn phải triển khai một API mà các client hiện có đã đang dùng
      Không thể quay ngược thời gian để biên dịch lại hoặc viết lại client
      Nếu client đã kiểm tra NotSupportedException thì bạn nên trả về nó, nhưng nếu không thì cần cách tiếp cận khác
    • Nếu bạn ở trong đội Windows mà có thái độ như vậy, nếu tôi là quản lý có lẽ tôi đã sa thải bạn
      Đây là Windows
      Không được làm hỏng các ứng dụng mà người dùng phụ thuộc vào
      Nếu có ứng dụng client “tệ” hoặc hoạt động sai, bạn phải dùng mọi workaround, shim, hack tương thích cần thiết để làm cho nó hoạt động như kỳ vọng
      Kể cả khi phải thêm mã quản lý bộ nhớ đặc biệt để SimCity chạy được cũng vậy
    • “Client tệ” đó có thể do một công ty đã phá sản từ lâu viết ra
      Khách hàng của bạn đang phụ thuộc vào client đó, và nếu nó dừng lại vì thay đổi của bạn, họ sẽ trách bạn
  • Ở đây mọi người đều bám vào “không làm gì cả” và “xử lý lỗi”, nhưng có vẻ bài viết chưa giải thích tốt rằng nó không kêu gọi nuốt mọi vấn đề rồi cùng hát kumbaya
    Bối cảnh thực sự là giả lập và tương thích cho phần mềm sẽ không thay đổi, và điều đó rất khác với hầu hết tình huống
    Bản thân Microsoft cũng thường làm mờ ranh giới giữa hai thứ nên càng dễ gây nhầm lẫn, nhưng điều đang nói ở đây không phải xử lý lỗi thông thường
    Giả lập về bản chất là nói dối
    Xbox thực ra không có cách nào gắn máy in, bạn đang chạy game Windows trên Linux, và chiếc iPhone giả có thể thực chất là một máy chủ ARM của AWS
    Nếu đã nói dối thì phải nói sao cho thuyết phục, để các ứng dụng hiện có tiếp tục hoạt động
    Khi Microsoft nói có thể port ứng dụng Windows hiện có sang Xbox, trong ứng dụng Windows vốn có lời hứa rằng nó có thể in/xuất, nên Xbox phải nói dối để làm cho việc đó trông có vẻ khả thi
    Ngược lại, nếu chương trình đang use-after-free mà bạn âm thầm né đi như thể không có bug, đó không phải cách xử lý đúng
    Vì không ai hứa rằng cả use-after-free hiện có cũng sẽ tương thích tới mức từng bug trên nền tảng mới

    • Trong bài viết không có chỗ nào đặt bối cảnh là giả lập cho phần mềm sẽ không thay đổi
      Đó chỉ là giả định vì cách diễn giải đó ủng hộ lập trường bạn muốn
      Thực tế, nội dung bài viết vẫn áp dụng y nguyên khi ngày mai tôi viết một chương trình cho Xbox và muốn in/xuất
      Không có phần nào phân biệt rằng hành vi này chỉ dành cho phần mềm cũ và không còn được bảo trì
  • Tôi vừa thích vừa không thích cách tiếp cận này
    Theo bản năng, tôi không thích xử lý vấn đề bằng kiểu tuân thủ ác ý
    Mặt khác, nếu mục tiêu là làm cho nhiều người dùng hơn chạy được nhiều phần mềm hơn trên nền tảng, dù chức năng in/xuất bị hỏng, thì tôi hoàn toàn đồng ý rằng đó là quyết định tốt

  • Luồng bình luận này thật kỳ lạ
    Rõ ràng có những người ghét bất cứ thứ gì Microsoft làm
    Trọng tâm của blog là làm cho quá trình đưa ứng dụng (UWP) lên XBOX diễn ra không ma sát
    Không cần biên dịch lại, không cần ifdef bẩn, không cần thêm việc; ứng dụng “cứ chạy”, rồi sau đó lập trình viên có thể điều chỉnh ứng dụng cho phù hợp với nền tảng XBOX
    Điều quan trọng là lập trình viên đã có thể đưa ứng dụng lên XBOX mà không tốn công sức, và điều này tốt cho cả nền tảng lẫn lập trình viên
    Với người dùng, danh sách máy in trống là tín hiệu rõ ràng rằng không thể in
    Quan trọng nhất là ứng dụng không chết hoặc hiển thị lỗi tệ nhất kiểu “Đã xảy ra sự cố. Vui lòng thử lại sau”
    Thông báo đó không phải trải nghiệm người dùng tốt hơn
    Lập trình viên có thể biên dịch lại ứng dụng và thêm thông báo giải thích rõ hơn, nhưng như vậy lại quay về điểm xuất phát

    • Có vẻ 95% thread này không hiểu bài viết
      Ví dụ, chỉ trích rằng nó nuốt lỗi hoàn toàn không trúng trọng tâm
  • Điểm cốt lõi mà phía phê phán bài viết này bỏ sót là ở đây không có tình huống ngoại lệ nào cần phải ném exception
    Thiết bị này không có máy in nào được kết nối, và trong trường hợp này theo định nghĩa là như vậy, nên ứng dụng phải xử lý tình huống đó một cách gọn gàng chứ không được chết
    Không thể vì laptop không truy cập được máy in mà ném exception

    • Nếu muốn một ví dụ hiện đại về một sản phẩm phi Microsoft được dùng rộng rãi nhưng xử lý sai tính khả dụng của máy in, thì có gnome-control-center
      Sau khi thêm máy in trong phần cài đặt, nếu chuyển sang tab “Color Profiles” trong lúc đang cài đặt, đúng thời điểm thì gnome-control-center sẽ chết
      Nhìn kỹ thì nó đã cố liệt kê các máy in khả dụng; nó biết là phải có máy in, nhưng thông tin chưa tồn tại nên cứ thế chết
      May mắn là chỉ cần đợi vài giây cho đến khi GNOME hoàn tất cài đặt máy in rồi mở lại phần cài đặt là được
      Dù vậy, nếu là ứng dụng cốt lõi giúp người dùng cuối từ nhiều nền tảng khác nhau dùng desktop cho đúng, thì trong một thế giới lý tưởng nó tuyệt đối không nên chết
      Nghĩ đến các điều kiện biên đã khó, tưởng tượng rằng bản thân việc xử lý điều kiện biên cũng có những điều kiện biên khác còn khó hơn
      Đúng hay sai thì ít nhất tác giả cũng đang suy nghĩ sâu hơn câu “đây là app tệ, nên viết lại để hỗ trợ Wayland”
  • Đã từng có thời việc trình duyệt cố gắng hết sức để hiển thị trang dù mã HTML có lỗi được xem là một chiến lược tuyệt vời
    Kiểu như đoán ý định của tác giả càng nhiều càng tốt rồi tiếp tục, vì lỗi là xấu và người dùng không muốn thấy lỗi
    Tôi tưởng chúng ta đã học được từ trải nghiệm đó, nhưng có vẻ là không

    • Trình duyệt vẫn đi theo chiến lược đó
      Nỗ lực XHTML nhằm thay thế bằng kiểm chứng nghiêm ngặt đã thất bại; thay vào đó, HTML5 thành công đã quay lại và định nghĩa rõ ràng cách diễn giải mọi chuỗi sai có thể có, để ít nhất các trình duyệt hành xử nhất quán
    • Chính nhờ trình duyệt khoan dung với đầu vào mà web hiện đại mới trở nên khả thi
      Nếu các trình duyệt thời đầu cứ gặp thẻ chưa từng thấy là hiển thị lỗi ngay, các tính năng trình duyệt mới đã bị bóp nghẹt từ lúc mới ra đời
    • Hãy thử nhập HelloWorld! để xem nhờ trí tuệ chúng ta thu được, giờ có lỗi hiện ra hay không
      Nhưng nếu nó vẫn render ổn, điều đó có nghĩa là vẫn còn nhiều thứ để học, hoặc cũng có thể là việc xử lý một số loại lỗi một cách mềm mại và chỉ chết trong các tình huống ngoại lệ là có ý nghĩa
    • Sự phát triển của phần mềm trong 20 năm qua, trừ LLM, không mấy xuất sắc; mà LLM thì cũng đã bị kiểm duyệt làm hỏng
      Có lẽ nếu quay về năm 1999 cũng chẳng tiếc nuối gì nhiều
    • Tôi tò mò không biết chúng ta nghĩ mình đã học được điều gì