Ja nie mam problemu z adnotacjami, tylko z tym co one robią np. w Javie, w większości frameworków. Przykład oderwany z od konkretnych bibliotek:
Załóżmy, że mamy klasę:
public class Person(){
private int age;
public int getAge(){
return age;
}
public setAge(int age){
if(age<0 || age > 140){
throw new DataValidationException("Age out of limit");
}
this.age = age;
}
}
Teraz jakiś spryciarz stwierdził, że napisze do tego framework do walidacji i w rezultacie może być tak:
public class Person(){
private int age;
public int getAge(){
return age;
}
public setAge(@ValidateRange(0, 140, "Age out of range") int age){
this.age = age;
}
}
Powiedzmy, że czytelniej.
Teraz piszę sobie test:
person = new Person();
expect(DataValidationException.class person.setAge(-1))
I test się sypie, bo logika adnotacji nie miała szansy zadziałać.
Żeby mogła zadziałać test powinien wyglądać tak:
person = ValidationProxy.wrap(new Person());
expect(DataValidationException.class person.setAge(-1))
Czyli obiekt musi zostać przetworzony, zapakowany w DynamicProxy, które ten obiekt owinie, sprawdzi, czy przypadkiem nie ma na nim jakiejś adnotacji i przepuszczając przez siebie zapytanie do owiniętego obiektu sprawdzi wcześniej, czy parametr metody jest zgodny z atrybutami zawartymi w adnotacji.
Jednocześnie adnotacja nie zadziała w takim przypadku:
public class Person(){
private int age;
public int getAge(){
return age;
}
public setAge(@ValidateRange(0, 140, "Age out of range") int age){
this.age = age;
}
public doSomething(){
setAge(-1)
}
}
Bo doSomething()
ominie proxy.
Nie każda biblioteka używająca adnotacji używa też DynamicProxy, można te adnotacje obsługiwać na etapie prekompilacji (przynajmniej w Javie) i wygenerować dodatkowy kod. Tylko obsługę w taki sposób ciężej wykonać i na ogół trochę trudniej sie tego użya, więc przeważająca większość adnotacji jest obsługiwana w trybie runtime, z ostrym rzeźbieniem refleksjami po wszystkim co wpadnie w łapy, łącznie z takimi magiami jak zmiana dostępności prywatnego pola na publiczne i wstawienie tam jakiejś wartości z pominięciem interface'u klasy.
Czyli tak - uważam, ze część adnotacji to zło, część bardzo popularnych frameworków to również zło, a jest na rynku od groma narzędzi, które próbują tworzyć jakieś ~DSLe tam gdzie jest to kompletnie zbędne i nie rozwiązuje żadnych problemów.