Zabrania się wywoływania dowolnych funkcji / klas w kodzie zewnętrznym

12

Zetknąłem się z przypadkami, w których cenne byłoby ograniczenie dostępu do API zewnętrznych bibliotek i frameworków, aby zapobiec negatywnym konsekwencjom w systemie.

Na przykład w aplikacji SharePoint może wydawać się naturalne, że można wywołać spList.Items.GetItemByIdelement listy, nawet w pętli, nie zdając sobie sprawy, że może to prowadzić do ogromnych problemów z wydajnością.

Może się również zdarzyć, że musimy zabronić korzystania z SmtpClient, aby zmusić wszystkich do korzystania z naszej klasy do wysyłania wiadomości e-mail, aby zapewnić, że możemy właściwie proxy i kpić z wszystkich wiadomości e-mail w środowisku testowym.

Czy istnieją jakieś niezawodne i dość proste sposoby na osiągnięcie tych ograniczeń w kodzie zewnętrznym, z wyjątkiem określonych miejsc w naszym własnym kodzie? Nie jest absolutnie konieczne, by w każdych okolicznościach uniemożliwiać dostęp do tych metod / klas, na przykład poprzez refleksję lub po prostu wyłączenie, powinno być raczej surowym ostrzeżeniem, że nie należy ich używać. Najlepiej wymuszając na programiście aktywne podjęcie działań w celu ominięcia tych ograniczeń, jeśli to możliwe / potrzebne.

Alex
źródło
11
To brzmi jak wymuszenie ekstremalnej formy stylu kodowania (zabronione jest używanie określonego wywołania biblioteki). Więc dla mnie rodzi się wstępne pytanie, czy przeprowadzasz jakieś recenzje kodu, czy przede wszystkim sprawdzasz styl?
Peter M
3
Czy chcesz złapać i zablokować te połączenia w czasie wykonywania lub w czasie kompilacji ?
MetaFight,
1
Ponieważ używasz C #, czy słyszałeś kiedyś o StyleCop ? Wiesz, że możesz tworzyć niestandardowe reguły, jak chcesz, prawda?
Machado,
10
Czy istnieją jakieś niezawodne i stosunkowo proste sposoby na osiągnięcie tych ograniczeń w kodzie zewnętrznym, z wyjątkiem określonych miejsc w naszym własnym kodzie? ”. Tak: napisz własny Roslyn Analyzer, aby zgłosić dostęp do niektórych interfejsów API jako błąd kompilacji.
David Arno,
3
@Machado, StyleCop jest faktycznie martwym produktem. Został zastąpiony StyleCopAnalyzers, który jest zbudowany na Roslyn. Zdecydowanie nie byłoby dobrym pomysłem inwestowanie czasu w pisanie niestandardowych reguł StyleCop.
David Arno,

Odpowiedzi:

8

Czy istnieją jakieś niezawodne i dość proste sposoby na osiągnięcie tych ograniczeń w kodzie zewnętrznym, z wyjątkiem określonych miejsc w naszym własnym kodzie?

Ponieważ pytanie dotyczy w szczególności języka C #, istnieje tutaj rozwiązanie oparte na kompilatorze, którego można użyć do egzekwowania takich reguł: Roslyn Analyzers . Możesz napisać własny analizator, który zgłasza dostęp do niektórych interfejsów API jako błąd kompilacji lub ostrzeżenie.

Przykładowym zestawem analizatorów, które zawierają wiele przykładowego kodu podczas pisania własnego, są analizatory StyleCop , które zastępują starą funkcję StyleCop dla języka C #.

Powiedziawszy to, takie zautomatyzowane kontrole zawsze mogą być obejrzane przez ludzi zdeterminowanych, by „łamać zasady”. Dlatego takie podejście nie zastępuje przeglądów kodu, jak omówiono w odpowiedzi Karla Bielefeldta. Może pomagać w takich recenzjach, ale nie powinien ich zastępować.

David Arno
źródło
Nigdy nie miałem zamiaru zastępować niczego innego, szukałem tylko specjalnego narzędzia do mojego zestawu narzędzi.
Alex
25

Możesz robić czasochłonne rzeczy, takie jak napisanie opakowania na zewnętrznym interfejsie API, które pomija niepożądane operacje, ale nic nie przebije szkolenia i recenzji kodu, ponieważ niezależnie od wprowadzonych standardów lub środków technicznych ludzie znajdą kreatywne sposoby na obejście ich .

Na przykład mamy kilka usług napisanych w Scali, a jedną z rzeczy, o które pytamy w czasie przeglądu kodu, jest niezmienność, ale często komunikujemy to, gdy się go pozbywamy vars. Ktoś inny dzień użył val x: ListBuffer [Boolean] do przechowywania jednej zmiennej zmiennej jako jedynej pozycji na liście. Nie możesz przypisać innej wartości ListBufferdo x, ale możesz zastąpić elementy listy na miejscu tak długo, jak chcesz. Tak samo źle, jak używanie var, ale bardziej podstępne.

Innymi słowy, musisz sprawdzić, czy ludzie obchodzą twoje rozwiązania techniczne. Jeśli te rozwiązania techniczne są kosztowne i zwiększają złożoność, możesz po prostu sprawdzić, czy kodują je poprawnie.

Karl Bielefeldt
źródło
cholera, to jest podstępne!
kiedy
@snb Jest to równoważne z tym, co robi Java jako hack, aby obejść możliwość zwrócenia tylko jednego obiektu / wartości i braku odpowiednich argumentów referencyjnych; zamiast tego przekazuje tablicę, której zawartość zostanie zaktualizowana. (Kilka przykładów: AtomicMarkableReference.geti AtomicStampedReference.get).
JAB
Dziękuję za odpowiedź, ale zdecydowanie nie jestem zainteresowany robieniem czasochłonnych skomplikowanych czynności, takich jak pisanie opakowań wokół zewnętrznego kodu. To prawdopodobnie nie pomogłoby, ponieważ mogą po prostu przejść do źródła. Ta odpowiedź wydaje się zakładać, że rozwiązanie będzie kosztowne i zwiększy złożoność. Co z czystym i prostym rozwiązaniem?
Alex
1
@Alex to najprostsze rozwiązanie: „nic nie przebije szkolenia i recenzji kodu”.
Mr.Mindor
2
„nic nie przebije robienia tego ręcznie” jest słuszne, dopóki ktoś tego nie zautomatyzuje.
Ewan,
0

Odpowiedź Karla jest w 100% poprawna. Nie ma sposobu, aby zagwarantować zgodność. Jednak oprócz szkoleń i przeglądów kodu należy rozważyć użycie narzędzi do analizy statycznej w celu zapewnienia zgodności. (Uwaga: Powiedziałem „oprócz”, ponieważ można je również ominąć dokładnie w taki sam sposób, jak stwierdził Karl).

Zaletą korzystania z narzędzi do analizy statycznej jest usunięcie żmudnej analizy kodu ludzkiego w poszukiwaniu przypadków „wielokrotnego użycia IEnumerable” lub jakiegokolwiek innego problemu z wydajnością w tygodniu, na który patrzysz (lub przynajmniej, że zawsze czuję, że jestem patrzeć na). Pozwoli to przeglądom kodu i szkoleniom skoncentrować się na bardziej „interesujących” kwestiach.

W szczególności w języku C # poniżej zamieściłem kilka sugestii. Podłącz je do środowiska kompilacji i gotowe. Ale generalnie, bez względu na używany język, istnieje gdzieś narzędzie do analizy statycznej.

Skopiuj / wklej bezpośrednio ze strony Wikipedii, skorzystaj ze strony wiki, aby uzyskać najnowsze informacje i linki: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#.NET

  • .NET Compiler Platform (Codename Roslyn) - Framework kompilatora Open Source dla C # i Visual Basic .NET opracowany przez Microsoft .NET. Zapewnia interfejs API do analizowania i manipulowania składnią.
  • CodeIt.Right - Łączy statyczną analizę kodu i automatyczne refaktoryzowanie do najlepszych praktyk, co pozwala na automatyczną korektę błędów i naruszeń kodu; obsługuje C # i VB.NET.
  • CodeRush - wtyczka do Visual Studio, która ostrzega użytkowników o naruszeniu najlepszych praktyk.
  • FxCop - Bezpłatna analiza statyczna dla programów Microsoft .NET, która kompiluje się do CIL. Samodzielny i zintegrowany z niektórymi wersjami Microsoft Visual Studio; przez Microsoft.
  • NDepend - upraszcza zarządzanie złożoną bazą kodu .NET poprzez analizowanie i wizualizowanie zależności kodu, definiowanie reguł projektowych, przeprowadzanie analizy wpływu i porównywanie różnych wersji kodu. Integruje się z Visual Studio.
  • Parasoft dotTEST - Wtyczka do analizy statycznej, testów jednostkowych i recenzji kodu dla Visual Studio; współpracuje z językami dla Microsoft .NET Framework i .NET Compact Framework, w tym C #, VB.NET, ASP.NET i Managed C ++.
  • Sonargraph - Obsługuje C #, Java i C / C ++ z naciskiem na analizę zależności, automatyczne sprawdzanie architektury, metryki oraz możliwość dodawania niestandardowych metryk i kontrolerów kodu.
  • StyleCop - Analizuje kod źródłowy C # w celu wymuszenia zestawu reguł stylu i spójności. Można go uruchomić z poziomu Microsoft Visual Studio lub zintegrować z projektem MSBuild.
Reginald Blue
źródło
-1

Aby rozwinąć sugestię „szkolenia i przeglądu kodu” przedstawioną w innej odpowiedzi: ponieważ kod, którego chcesz zabronić, jest kodem legalnym, nie możesz liczyć na to, że kompilator temu zapobiegnie, i będziesz musiał polegać na późniejszym procesie, recenzja.

Może to (i powinno) obejmować zarówno ręczne, jak i automatyczne kroki przeglądu:

  • Przygotuj listę kontrolną znanych problemów i przejrzyj je po kolei w swoich ręcznych recenzjach kodu. Umów się na spotkanie cykliczne, aby przejrzeć i zaktualizować listę kontrolną. Ilekroć złośliwy błąd zostanie złapany i przeanalizowany, dodaj go do listy kontrolnej.

  • Dodaj reguły odprawy, aby wyszukać znane wzorce. Pisanie może być skomplikowane, ale w przypadku dużego projektu z czasem może się przydać. TFS pozwala pisać reguły w języku C #, a inne systemy kompilacji mają własne zaczepy. Rozważ użycie bramkowanych wersji, aby odrzucić zameldowania pasujące do wzorca. Tak, spowalnia rozwój, ale po pewnym rozmiarze i złożoności projektu spowolnienie deweloperów może być dobrą rzeczą.

Avner Shahar-Kashtan
źródło
-1

Może kompilator może pomóc w przechwytywaniu niechcianych połączeń.

Zmień nazwy klas / metod kodu we własnej bibliotece, które nie powinny być używane przez zewnętrznych klientów bibliotek. Alternatywnie uczyń klasy / metody wewnętrznymi i dodaj elementy wewnętrzne widoczne dla tych klas, które mogą z nich korzystać.

Zewnętrzni użytkownicy lib otrzymają metodę / klasę błędu kompilacji nie znaleziono.

Zabronione klasy / metody z bibliotek publicznych: utwórz taką samą przestrzeń nazw / klasę / metodę w swojej bibliotece

Zewnętrzni użytkownicy lib otrzymają błąd kompilacji z powodu znalezienia zduplikowanej klasy

[aktualizacja]

Nie jest absolutnie konieczne, aby w każdych okolicznościach uniemożliwiać dostęp do tych metod / klas, na przykład przez odbicie lub po prostu wyłączenie ...

zmuszając programistę (... klienta biblioteki lib ...) do aktywnego podjęcia działań w celu ominięcia tych ograniczeń, jeśli to możliwe / potrzebne.

k3b
źródło
Głosowanie to nie tylko dlatego, że jest to paskudny hack, ale można go łatwo obejść w C # (który OP oznaczył to pytanie) za pomocą zewnętrznych aliasów .
David Arno,