Tất cả những điểm này có thể được áp dụng cho phát triển di động, giao diện người dùng web và phụ trợ. Tôi đã thu thập các phương pháp này từ các nhóm khác nhau và thông qua các vấn đề tôi gặp phải trong 6 năm qua. Những thực hành này có thể đặc biệt hữu ích khi bạn xây dựng một dự án từ đầu. Một số trong số họ có thể phù hợp với bạn một cách hoàn hảo, trong khi những người khác có thể không. Nếu bạn có cách tiếp cận của riêng mình và những kinh nghiệm khác nhau, tôi sẽ rất vui nếu bạn chia sẻ chúng ở đây. Nhân tiện, nếu bạn là nhà phát triển cấp trung hoặc cấp cơ sở đang tìm kiếm cơ hội thăng tiến, việc triển khai các phương pháp này trong nhóm của bạn thực sự có thể hữu ích. Đi nào!
Trong một quy trình phát triển phần mềm tiêu chuẩn, khi một yêu cầu tính năng mới đến từ doanh nghiệp, nó sẽ được phân phối giữa một số nhóm: phát triển ứng dụng dành cho thiết bị di động và giao diện người dùng.
Sau đó, mỗi nhóm tiến hành lập kế hoạch và phân tách nhiệm vụ. Nhưng điều gì sẽ xảy ra nếu nhóm phụ trợ cần nhiều thời gian hơn đáng kể để phát triển phần của họ? Điều gì sẽ xảy ra nếu họ chỉ có thể cung cấp điểm cuối mỗi tuần một lần?
Phần phụ trợ trở thành một nút cổ chai.
Các nhóm phát triển di động và front-end kết thúc công việc như thế này: "Ồ, back-end đã triển khai việc này rồi. Hãy để tôi đảm nhận nhiệm vụ này." Sau đó, họ nghỉ ngơi, chuyển bối cảnh của họ sang một tính năng khác và chu kỳ tiếp tục. Điều này dẫn đến mệt mỏi, giảm tốc độ và giảm chất lượng.
Giải pháp: thỏa thuận hợp đồng với nhóm phụ trợ và giả định tất cả các yêu cầu.
1. Phối hợp với nhóm back-end về các điểm cuối và thực thể.
2A. Triển khai API phụ trợ với các phản hồi sơ khai. Thư viện Faker có thể giúp tạo dữ liệu mẫu.
2B. Hoặc triển khai sơ khai trên giao diện người dùng. Đây có thể là một đối tượng có dữ liệu trực tiếp trong mã. Ví dụ: trong Node.js, bạn có thể triển khai điều này một cách hiệu quả bằng cách sử dụng tính năng nhập động và tránh tăng kích thước gói:
getUser() { return import('../../assets/mocks/users') .then(data => data.userById) .then(deserializeUser); };
Đây cũng có thể là một dịch vụ HTTP mô phỏng tìm nạp các tệp JSON từ nội dung thay vì thực hiện các yêu cầu thực.
Ẩn đối tượng địa lý đằng sau cờ đối tượng địa lý.
Khi chương trình phụ trợ đã sẵn sàng, hãy chuyển sang API thực tế nếu bạn đã sử dụng phương pháp sơ khai giao diện người dùng và xác minh rằng mọi thứ hoạt động như mong đợi. Và bật tính năng này lên.
Bây giờ, như bạn có thể nhận thấy, trong phần trước, tôi đã đề cập đến các cờ đặc trưng. Tóm lại, cờ tính năng hay còn gọi là chuyển đổi tính năng cho phép nhà phát triển bật hoặc tắt tính năng trong môi trường trực tiếp. Ngoài ra còn có một số trường hợp khi chúng hữu ích: dần dần triển khai các tính năng mới, thực hiện thử nghiệm A/B, bật các tính năng beta và triển khai các bản sửa lỗi nóng.
Chúng tôi sử dụng Gitlab để lưu trữ các cờ tính năng. Đó là một kho lưu trữ chuyên dụng được sử dụng bởi cả dự án phụ trợ và giao diện người dùng. Tin vui là nó có giao diện người dùng thân thiện với người dùng, do đó người quản lý sản phẩm có thể tự mình quản lý các tính năng. Trước đây, chúng tôi thường sử dụng các cờ tính năng cho từng kho lưu trữ dự án riêng biệt. Tuy nhiên, phương pháp này không cung cấp khả năng vô hiệu hóa các tính năng cho toàn bộ sản phẩm cùng một lúc. Vì vậy, chúng tôi di chuyển mọi thứ vào kho lưu trữ duy nhất.
Trong mã, nó trông khá đơn giản:
if features.YOUR_FEATURE
vào mã cần ẩn.
Khi sản phẩm của chúng tôi chuyển từ giai đoạn MVP sang ứng dụng sản xuất, chúng tôi lo ngại rằng người dùng sẽ gặp lỗi mà chúng tôi không thể tái tạo và thậm chí có thể không biết. Sau khi nghiên cứu các công cụ theo dõi lỗi, chúng tôi quyết định chọn Sentry. Kinh nghiệm là tích cực. Và bây giờ, chúng ta hãy đi qua một số sắc thái quan trọng.
Dưới mui xe, mọi ngoại lệ chưa được phát hiện sẽ được theo dõi. Khi ứng dụng và số lượng người dùng tăng lên, số lượng lỗi có thể trở nên nhiều đến mức gần như không thể nhận thấy điều gì thực sự quan trọng. Sentry có thể biến thành thùng rác nếu bạn không lọc bỏ những thứ không cần thiết. Ví dụ: các sự kiện như yêu cầu bị hủy, lỗi kết nối và lỗi từ các tập lệnh được kết nối hoàn toàn vô ích và sẽ chỉ gửi thư rác cho email công việc của bạn bằng các thông báo. Như một giải pháp, bạn có thể thêm bộ lọc vào cấu hình. Để thực hiện việc này, chỉ cần xác định một cuộc gọi lại beforeSend
và đặt nó vào sentryPackage.init
của bạn. Trong cuộc gọi lại này, bạn có thể phân tích từng lỗi đã bắt được và sau đó loại bỏ nó (bằng cách trả về null) nếu nó vô dụng. Đây là một ví dụ về bộ lọc loại trừ các lỗi không cần thiết:
function beforeSend(event, hint) { const error = hint.originalException; const externalScripts = [ 'gtm.js', // Google Tag Manager 'watch.js', // X Analytics ].join('|'); const errorsToIgnore = [ AxiosError.ERR_NETWORK, AxiosError.ECONNABORTED, AxiosError.ETIMEDOUT ]; if (axios.isCancel(error) || errorsToIgnore.includes(error.code) || error.stack?.match(externalScripts)) { return null; } return event; }
Theo mặc định, Sentry có thể không bao gồm nội dung của yêu cầu và phản hồi trong báo cáo lỗi. Không có thông tin này, việc gỡ lỗi thích hợp là không thể. May mắn thay, trong trình xử lý beforeSend
, chúng tôi có thể bao gồm thông tin này.
function beforeSend(event, hint) { const error = hint.originalException; if (error.isAxiosError) { const url = error.request?.responseURL; const response = error.response?.data; const request = error.config?.data; event.extra = { ...(event.extra || {}), url, response, request }; } return event; }
Dữ liệu như mật khẩu, địa chỉ email và khóa không được đưa vào nội dung lỗi. Sentry có một cơ chế tích hợp để ẩn loại thông tin này. Bạn có thể định cấu hình nó trong cài đặt bảo mật. Ngoài ra, bạn cũng có thể xóa nội dung nào đó trong đối tượng sự kiện ở beforeSend
Nếu bản chất công việc kinh doanh của bạn cấm lưu trữ loại dữ liệu này trên máy chủ ở một nơi khác, Sentry cung cấp khả năng sử dụng nó trên máy chủ của riêng bạn.
Hãy tưởng tượng một tình huống mà bạn nắm bắt thành công một lỗi trong Sentry, nhưng thông tin trong phần mô tả không đầy đủ. Bạn chuyển sang nhật ký, nhưng làm thế nào bạn có thể xác định lỗi cụ thể trong số hàng nghìn yêu cầu và thậm chí nhiều dòng nhật ký hơn mỗi giây? Làm cách nào bạn có thể phân biệt đúng, xây dựng chuỗi yêu cầu và xác định lỗi chính xác, đặc biệt khi doanh nghiệp của bạn có nhiều nhóm và tích hợp với các dịch vụ khác? Đây là nơi truy tìm phát huy tác dụng.
Trong quá trình triển khai cụ thể của mình, chúng tôi đã sử dụng Jaeger dựa trên API OpenTracing.
Tóm lại, mỗi yêu cầu và tất cả các lệnh gọi phương thức của nó được gắn một nhãn duy nhất. Mỗi nhãn có một tham chiếu đến nhãn gốc và một số siêu dữ liệu. Cấu trúc của số này phụ thuộc vào việc triển khai nhưng đối với OpenTracing, bạn có thể đọc cách thức hoạt động của nó và làm quen với các thuật ngữ như nhịp, tham chiếu, con, gốc, v.v. trên trang kho lưu trữ chính thức . Trong cuộc sống thực, truy tìm may mắn sẽ hiếm khi được sử dụng. Tuy nhiên, trong những tai nạn hy hữu này, nó có thể giúp bạn tiết kiệm thời gian.
Khi chúng tôi triển khai MVP của ứng dụng fintech, chúng tôi có một biểu mẫu khá phức tạp. Lúc đó tôi còn trẻ và chưa có nhiều kinh nghiệm. Và cuối cùng, chúng tôi nhận ra rằng dự án của chúng tôi đang bị chậm lại. Chúng tôi đã phải dành thêm giờ để tìm ra lý do. Chúng tôi có nhiều lần re-render không cần thiết vì chúng tôi đã bỏ qua các quy tắc cơ bản liên quan đến props trong React. Tôi muốn làm mọi thứ có thể để tránh những tình huống như vậy trong tương lai.
Vì vậy, tôi đã thêm vào dự án các tập tin rác như thế này và một cấu hình bắt đầu bổ sung cho package.json để chạy tại sao-did-you-render . Nói tóm lại, plugin này đưa ra cảnh báo nếu có thứ gì đó được hiển thị lại một cách không cần thiết và gợi ý cách tránh nó. Ngoài ra, chúng tôi đã bao gồm việc chạy Ngọn hải đăng ở chế độ không đầu . Một số người nói rằng tối ưu hóa quá sớm là không tốt, nhưng đối với tôi, đó là một nguyên tắc: làm đúng ngay từ đầu .
Bạn có thể đã nghe nói về lý thuyết cửa sổ bị hỏng. Nếu có một cửa sổ bị vỡ trong một tòa nhà và không có ai thay thế nó, cuối cùng sẽ không còn một cửa sổ nguyên vẹn nào trong tòa nhà đó.
Dự án càng có ít quy tắc và điều khiển thì càng dễ bị cám dỗ để viết mã chất lượng thấp hoặc viết mã theo một phong cách hoàn toàn khác. Mã không nhất quán làm tăng thời gian cần thiết để hiểu nó, trong khi mã rõ ràng, quen thuộc và ngắn gọn cho phép đọc nhanh. Ở một trong các nhóm của chúng tôi, chúng tôi đã mô tả phong cách viết mã ở một nơi . Là một điểm khởi đầu tuyệt vời, bạn có thể sử dụng kiểu mã Đẹp hơn hoặc Airbnb .
Một số lượng đáng kể tài liệu đã được viết về các loại bài kiểm tra khác nhau, cách tiếp cận và cách viết chúng đúng cách. Điều duy nhất đáng nói ở đây là không có ứng dụng sản xuất nào có thể tồn tại nếu không có kiểm thử hồi quy. Đó là lý do tại sao chúng tôi tập trung mọi nỗ lực vào việc tạo ra một khung thử nghiệm toàn diện từ đầu đến cuối và dựa trên khung đó, chúng tôi đã viết các thử nghiệm được liên kết với các kịch bản BDD và câu chuyện của người dùng. Chúng tôi đã sử dụng mẫu Đối tượng Trang để tổ chức mã của mình và khung Playwright để tương tác với trình duyệt. Để kiểm tra trên các trình duyệt khác nhau, kể cả Safari, bạn có thể sử dụng giải pháp có tên là Moon . Nó có thể được triển khai trên một trong các máy chủ của bạn.
Cảm ơn bạn đã dành thời gian để đọc bài viết này! Tóm lại, bài viết này nêu bật các thực tiễn kỹ thuật phần mềm chính giúp nâng cao quy trình phát triển và chất lượng mã. Bằng cách áp dụng các kỹ thuật như mô phỏng phản hồi phụ trợ, cờ tính năng, giám sát lỗi, tối ưu hóa hiệu suất, tiêu chuẩn kiểu mã, kiểm tra hồi quy và theo dõi, bạn có thể tạo ra phần mềm đáng tin cậy và hiệu quả hơn. Hãy tiếp tục cải thiện phần mềm của chúng tôi và giữ liên lạc! :)