Cấm các cuộc gọi đến các hàm / lớp tùy ý trong mã bên ngoài


12

Tôi đã gặp các trường hợp có giá trị khi hạn chế quyền truy cập vào API của các thư viện và khung bên ngoài để ngăn ngừa hậu quả tiêu cực trong hệ thống.

Ví dụ, trong một ứng dụng SharePoint, có vẻ như tự nhiên gọi spList.Items.GetItemByIdđể lấy một mục danh sách, thậm chí có thể trong một vòng lặp, mà không nhận ra rằng điều này có thể dẫn đến các vấn đề hiệu suất lớn.

Cũng có thể là chúng ta cần cấm sử dụng SmtpClient để buộc mọi người sử dụng lớp riêng của chúng tôi để gửi email, để đảm bảo rằng chúng tôi có thể ủy quyền và giả lập tất cả email khi ở trong môi trường thử nghiệm.

Có bất kỳ cách đáng tin cậy và hợp lý đơn giản nào để đạt được các ràng buộc này đối với mã bên ngoài, ngoại trừ từ các vị trí cụ thể nhất định trong mã của chúng ta không? Không nhất thiết phải tuyệt đối trong mọi trường hợp ngăn chặn truy cập vào các phương thức / lớp này, ví dụ như bằng phản xạ hoặc chỉ là một loại vô hiệu hóa, nó nên là một cảnh báo nghiêm ngặt rằng chúng không nên được sử dụng. Tốt nhất là buộc lập trình viên phải chủ động thực hiện các biện pháp để ghi đè các ràng buộc này nếu có thể / cần thiết.


11
Điều này nghe có vẻ như là một hình thức cực đoan của phong cách mã hóa (Cấm sử dụng một cuộc gọi thư viện cụ thể). Vì vậy, với tôi nó đặt ra câu hỏi tiên quyết là bạn có thực hiện bất kỳ đánh giá mã nào, hoặc kiểm tra kiểu ở vị trí đầu tiên không?
Peter M

3
Bạn có hy vọng bắt và chặn các cuộc gọi này là thời gian chạy hoặc thời gian biên dịch không?
MetaFight

1
Vì bạn đang sử dụng C #, bạn đã bao giờ nghe nói về StyleCop chưa? Bạn biết bạn có thể tạo quy tắc tùy chỉnh theo ý muốn, phải không?
Machado

10
" Có cách nào đáng tin cậy và hợp lý đơn giản để đạt được các ràng buộc này đối với mã bên ngoài, ngoại trừ từ các vị trí cụ thể nhất định trong mã của chúng tôi không? ". Có: viết Trình phân tích Roslyn của riêng bạn để báo cáo việc truy cập một số API nhất định là lỗi biên dịch.
David Arno

3
@Machado, StyleCop thực sự là một sản phẩm chết. Nó được thay thế bằng StyleCopAnalyzers, được xây dựng trên đỉnh Roslyn. Những ngày này chắc chắn sẽ không phải là một ý tưởng tốt để viết các quy tắc StyleCop tùy chỉnh trong những ngày này.
David Arno

Câu trả lời:


8

Có bất kỳ cách đáng tin cậy và hợp lý đơn giản nào để đạt được các ràng buộc này đối với mã bên ngoài, ngoại trừ từ các vị trí cụ thể nhất định trong mã của chúng ta không?

Vì câu hỏi cụ thể là về C #, có một giải pháp dựa trên trình biên dịch có thể được sử dụng ở đây để thực thi các quy tắc như vậy: Roslyn Phân tích . Bạn có thể viết trình phân tích của riêng mình báo cáo việc truy cập một số API nhất định dưới dạng lỗi biên dịch hoặc cảnh báo.

Một bộ ví dụ về các máy phân tích, cung cấp rất nhiều mã ví dụ về cách viết của riêng bạn, là Bộ phân tích StyleCop , là một thay thế cho tính năng StyleCop cũ cho C #.

Đã nói rằng, kiểm tra tự động như vậy luôn luôn có thể được làm việc xung quanh bởi dân gian xác định để "phá vỡ các quy tắc". Do đó, cách tiếp cận này không thay thế cho các đánh giá mã như được thảo luận trong câu trả lời của Karl Bielefeldt. Nó có thể hỗ trợ với các đánh giá như vậy, nhưng không nên thay thế chúng.


Nó không bao giờ có ý định thay thế bất cứ thứ gì khác, tôi chỉ tìm kiếm một công cụ chuyên dụng cho hộp công cụ của mình.
Alex - Dừng lại vào

25

Bạn có thể thực hiện những việc tốn thời gian như viết một trình bao bọc xung quanh API bên ngoài mà bỏ qua các hoạt động không mong muốn của bạn, nhưng không có gì đánh giá được việc đào tạo và đánh giá mã, bởi vì bất kỳ tiêu chuẩn hoặc biện pháp kỹ thuật nào bạn áp dụng, mọi người sẽ tìm ra cách sáng tạo để khắc phục chúng .

Ví dụ: chúng tôi có một số dịch vụ được viết bằng Scala và một trong những điều chúng tôi yêu cầu tại thời điểm xem xét mã là không thay đổi, nhưng chúng tôi thường liên lạc rằng việc loại bỏ vars. Một số người khác đã sử dụng val x: ListBuffer [Boolean] để giữ một biến có thể thay đổi duy nhất là mục duy nhất trong danh sách. Bạn không thể gán cái khác ListBuffercho x, nhưng bạn có thể thay thế các mục trong danh sách theo ý muốn. Cũng tệ như sử dụng một var, nhưng lén lút hơn.

Nói cách khác, bạn phải kiểm tra xem mọi người đang đi xung quanh các giải pháp kỹ thuật của bạn. Nếu những giải pháp kỹ thuật đó tốn kém và thêm độ phức tạp, bạn cũng có thể kiểm tra xem chúng có mã hóa chính xác không.


chết tiệt thật là lén lút
whn

@snb Nó tương đương với những gì Java thực hiện khi hack chỉ để có thể trả về một đối tượng / giá trị và không có đối số tham chiếu thích hợp; thay vào đó một mảng sẽ được cập nhật nội dung của nó. (Một số ví dụ: AtomicMarkableReference.getAtomicStampedReference.get).
JAB

Cảm ơn câu trả lời của bạn, nhưng tôi chắc chắn không quan tâm đến việc thực hiện những việc phức tạp tốn thời gian như viết các hàm bao quanh mã bên ngoài. Điều đó thậm chí sẽ không giúp được gì vì họ chỉ có thể đi đến nguồn. Câu trả lời này dường như cho rằng một giải pháp sẽ tốn kém và thêm phức tạp. Một giải pháp đơn giản và tinh khiết thì sao?
Alex - Dừng lại vào

1
@Alex giải pháp đơn giản nhất là ngay tại đó: "không có gì vượt qua đào tạo và đánh giá mã".
Mr.Mindor

2
"Không có gì nhịp đập làm nó bằng tay" là đúng cho đến khi ai đó tự động hóa nó.
Ewan

0

Câu trả lời của Karl là chính xác 100%. Không có cách nào để đảm bảo sự phù hợp. Tuy nhiên, ngoài việc đào tạo và đánh giá mã, hãy xem xét việc sử dụng các công cụ phân tích tĩnh để đảm bảo tuân thủ. (Lưu ý: Tôi đã nói "ngoài", vì người ta có thể bỏ qua những điều đó theo chính xác như cách mà Karl đã nêu).

Lợi thế của việc sử dụng các công cụ phân tích tĩnh là loại bỏ phân tích mã con người tẻ nhạt tìm kiếm các trường hợp "sử dụng nhiều IEn" hoặc bất kỳ vấn đề hiệu suất nào trong tuần bạn đang xem (hoặc, ít nhất, tôi luôn cảm thấy nhìn). Điều này sẽ cho phép các đánh giá và đào tạo mã tập trung vào các vấn đề "thú vị" hơn.

Đối với C #, cụ thể, tôi đã bao gồm một số đề xuất bên dưới. Cắm những thứ này vào môi trường xây dựng của bạn và bạn sẽ ổn. Nhưng, nói chung, bất kể bạn đang sử dụng ngôn ngữ nào, có một công cụ phân tích tĩnh ở đâu đó.

Sao chép / dán trực tiếp từ trang Wikipedia, sử dụng trang wiki để biết thông tin và liên kết gần đây nhất: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET

  • Nền tảng trình biên dịch .NET (Codename Roslyn) - Khung trình biên dịch mã nguồn mở cho C # và Visual Basic .NET được phát triển bởi Microsoft .NET. Cung cấp một API để phân tích và thao tác cú pháp.
  • CodeIt.Right - Kết hợp phân tích mã tĩnh và tái cấu trúc tự động để thực hành tốt nhất cho phép tự động sửa lỗi và vi phạm mã; hỗ trợ C # và VB.NET.
  • CodeRush - Một plugin cho Visual Studio cảnh báo người dùng vi phạm các thực tiễn tốt nhất.
  • FxCop - Phân tích tĩnh miễn phí cho các chương trình Microsoft .NET biên dịch thành CIL. Độc lập và tích hợp trong một số phiên bản Microsoft Visual Studio; bởi Microsoft.
  • NDepend - Đơn giản hóa việc quản lý cơ sở mã .NET phức tạp bằng cách phân tích và trực quan hóa các phụ thuộc mã, bằng cách xác định quy tắc thiết kế, bằng cách phân tích tác động và bằng cách so sánh các phiên bản mã khác nhau. Tích hợp vào Visual Studio.
  • Parasoft dotTEST - Một phân tích tĩnh, thử nghiệm đơn vị và plugin đánh giá mã cho Visual Studio; hoạt động với các ngôn ngữ cho Microsoft .NET Framework và .NET Compact Framework, bao gồm C #, VB.NET, ASP.NET và Managed C ++.
  • Sonargraph - Hỗ trợ C #, Java và C / C ++, tập trung vào phân tích phụ thuộc, kiểm tra kiến ​​trúc tự động, số liệu và khả năng thêm số liệu tùy chỉnh và trình kiểm tra mã.
  • StyleCop - Phân tích mã nguồn C # để thực thi một tập hợp các quy tắc về kiểu dáng và tính nhất quán. Nó có thể được chạy từ bên trong Microsoft Visual Studio hoặc được tích hợp vào một dự án MSBuild.

-1

Để giải thích về đề xuất "đào tạo và đánh giá mã" được nêu trong một câu trả lời khác: vì mã bạn muốn cấm là mã hợp pháp, bạn không thể tin vào trình biên dịch ngăn chặn nó và bạn sẽ phải dựa vào quy trình sau, bài đánh giá.

Điều này có thể (và nên) bao gồm cả các bước đánh giá thủ công và tự động:

  • Chuẩn bị một danh sách kiểm tra các vấn đề đã biết và lần lượt xem qua chúng trong các bài đánh giá mã thủ công của bạn. Có một cuộc họp định kỳ để xem xét và cập nhật danh sách kiểm tra. Bất cứ khi nào một lỗi khó chịu được bắt và phân tích, hãy thêm nó vào danh sách kiểm tra.

  • Thêm quy tắc kiểm tra để tìm kiếm các mẫu đã biết. Điều này có thể phức tạp để viết, nhưng đối với một dự án lớn, theo thời gian, có thể hữu ích. TFS cho phép bạn viết các quy tắc trong C # và các hệ thống xây dựng khác có các móc nối riêng. Xem xét sử dụng các bản dựng có kiểm soát để từ chối các đăng ký phù hợp với mẫu. Vâng, nó làm chậm sự phát triển, nhưng sau một quy mô và độ phức tạp của dự án nhất định, làm chậm các nhà phát triển có thể là một điều tốt.


-1

Có lẽ trình biên dịch có thể giúp bạn bắt các cuộc gọi không mong muốn.

Đổi tên các lớp / phương thức mã trong lib của riêng bạn mà các máy khách lib bên ngoài không nên sử dụng. Luân phiên làm cho các lớp / phương thức bên trong và thêm các phần bên trong hiển thị cho các lớp được phép sử dụng chúng.

Người dùng lib bên ngoài sẽ nhận được một phương thức / lớp biên dịch lỗi không tìm thấy.

Các lớp / phương thức bị cấm từ các thư viện công cộng: tạo cùng một không gian tên / lớp / phương thức trong lib của bạn

Người dùng lib bên ngoài sẽ gặp lỗi biên dịch do tìm thấy lớp trùng lặp

[cập nhật]

Không cần thiết phải tuyệt đối trong mọi trường hợp ngăn chặn truy cập vào các phương thức / lớp này, ví dụ bằng phản xạ hoặc chỉ một loại vô hiệu hóa, ....

buộc lập trình viên (... khách hàng của lib ...) phải chủ động thực hiện các biện pháp để ghi đè các ràng buộc này nếu có thể / cần thiết.


Bỏ qua điều này, không chỉ vì đó là một vụ hack khó chịu, mà nó còn dễ dàng được xử lý với C # (mà OP đã gắn thẻ câu hỏi với) bằng cách sử dụng các bí danh bên ngoài .
David Arno
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.