czwartek, listopada 18, 2010

O wyższości klas anonimowych

Kiedyś przychodzi taki moment, że potrzebujemy funkcjonalności pewnej istniejącej już klasy, ale nie całej, tylko kawałka i to lekko zmodyfikowanego.
Możemy oczywiście najzwyczajniej w świecie zadziedziczyć i stworzyć nową klasę, która robi to co chcemy i blokuje przez rzucanie wyjątku z komunikatem Not yet implemented te metody, których działanie byłoby bez sensu.

Ba, nawet by wypadało to tak zrobi jeżeli obiekt stworzony z takiej klasy będzie udostępniany "gdzieś indziej" poza metodą, w której go tworzymy.

Można to obejść dość ładnie jeżeli mamy interfejs opisujący dokładnie to co udostępniamy. Często warto go dopisać. Ale nie zawsze to jest dobre i wygodne.

Wtedy przychodzą klasy anonimowe :-)

No bo z klasą anonimową możemy poszaleć, nie musimy nadpisywać "niechcianych" metod w taki sposób by wyrzucały wyjątki.
Nie musimy, bo kod całej klasy mamy w metodzie przez co pisząc w niej kod mamy przed oczami to, że obiekty "urodzone" z tej klasy nie będą umiały wszystkiego co powinny.

Teraz przykład, taki koślawy ;-)

Mamy klasę, która gada z bazą danych, i robi getList(), get(), delete(), create(), update() i co tam jeszcze.
Metody pobierające listę i rekord zwracają obiekty będące reprezentacją tego co jest w bazie, create() i update() wrzucają zawartość takich rekordów do bazy i fajnie jest.
Do czasu gdy się okazuje, że ze względu na wydajność nie chcemy się dotykać z wszystkimi polami rekordów. Po co gdy pobieramy informacje o plikach przechowywanych w bazie wczytywać BLOBy z danymi? [tu akurat lepiej by było zrobić sobie 2 tabele, jedną na informacje o plikach w stylu nazwy i podobnych oraz drugą do trzymania samych danych z plików, ale nie zawsze możemy tak zrobić].
Wtedy można nadpisać sobie taką klasę dotykającą się z bazą, ale powstaje problem, że zwraca ona nadal obiekty tego samego typu co klasa bazowa, ale dość mocno ograniczone, bo nie mają "pełnych" wszystkich pól.
Przez to create(), ale szczególnie update() stają się niebezpieczne dla danych.
Gdybyśmy pisali "pełną" nie wewnętrzną klasę to nie ma przeproś, musimy popsuć update() tak by wyrzucało wyjątek. Bo a nóż ktoś zwabiony naszą klasą postanowi jej użyć i sobie dane w bazie popsuje?

I tutaj wewnętrzna klasa anonimowa jest jak znalazł. Mamy plusy, czyli mało pisania i nie mamy minusów w postaci nadpisania niepotrzebnych metod :-)

Tak, to ładne nie jest, ale jest sprytne ;-)

A teraz idę spać :-)


Podobne postybeta
Modale nie takie dobre dla Androida ;-)
Klasa statyczna - ki diabeł?;-)
Cukierki, radosny chaos i takie tam, czyli Przemkowe rojenia ;-)
Sztuczki tropiciela błędów, part 3 - hackujemy klasy finalne ;-)
Refleksje i serializacja w Java'ie - podstawy i obalanie mitów ;-)