Posted by Jarosław Zabiełło
Tue, 07 Feb 2006 22:25:00 GMT
Java, język który dobył sobie silną pozycję na rynku korporacyjnym, jest od jakiegoś czasu pod obstrzałem krytyki z różnych stron. Wyszła cała seria książek krytykujących model obiektowy oraz metodologie promowane przez Javę (od najsłynniejszej Beyond Java po Bitter Java, Bitter EJB, czy inne)
Nie umniejszając zalet Javy, jej krytycy wytykają jej niepotrzebną nadmiarowość kodu, ociężałość i małą zwrotność, która powoduje że język ten słabo nadaje się do modnej ostatnio metodologii _agile programming. _ Aby lepiej ten problem zobaczyć, przyjrzyjmy się typowej praktyce programistów Javy. Tekst ten zainspirowany jest niedawną dyskusją jaka miała miejsce w jednym z blogów mojego kolegi.
Czym są akcesory?
Akcesory (lub inaczej: gettery i settery) to slangowe okreslenie metod jakie używa obiekt do odczytu i modyfikacji swoich atrybutów. Są one tak nagminnie używane przez programistów Javy, że niektóre edytory (np. Eclipse) zostały nawet wyposażone w makra do automatycznego ich generowania.
Dorzucanie nieużywanego kodu “na wszelki wypadek”...
Nagminna (wśród programistów Javy) praktyka dodawania akcesorów do atrybutów klasy pachnie jakimś antipatternem i są głosy, które używanie akcesorów nazwyają wprost złą praktyką . Jest w tym trochę racji. Ale, jak to poniżej wykażę, jest to pewnego rodzaju kompromis w związku ze słabym modelem obiektowy Javy.
Dlaczego programiści Javy generują akcesory dla każdego atrybutu nawet, jak nie przewidują potrzeby ich używania? Otóż czynią to “na wszelki wypadek” bo nie wiedzą, czy w przyszłości nie będzie im to potrzebne…
Weźmy np. taki kod (z powodu kolejnego ograniczenia Javy nie można w jednym pliku trzymać więcej, niż jednej klasy; tu dla krótkości umieszczam kod z obu plików razem)
public class First {
public String msg = "hello";
}
public class Second extends First {
public static void main(String[] args) {
First obj = new First();
System.out.println(obj.msg);
}
}
Jak widać, w Javie można sięgać do atrybutu w sposób bezpośredni.
Wyobraźmy sobie jednak, że projekt nam się rozrósł i mamy już całkiem sporo kodu oraz sporo plików (pomnażanych wydatnie przez javowe ograniczenia co do ilości klas mogących wystąpić w pliku). Teraz przychodzi polecenie aby w momencie odczytu i zapisu atrybutu coś dodatkowego wykonać. (Np. niech to będzie logowanie informacji o takim zdarzeniu, albo zablokowanie możliwości modyfikacji treści atrybutu. Wszystko jedno co)
Mamy zatem pierwszy problem. Trzeba w tych wszystkich milionach miejsc, gdzie odwoływaliśmy się bezpośrednio do atrybutów, wymienić kod…
Właśnie dlatego, aby takich niespodzianek uniknąć w przyszłości, programiści Javy dorzucają dodatkowe metody opakowujące odczyt i zapis atrybutów. Eclipse upraszcza ten proces zwalniając programistę od ręcznego wpisywania tego kodu.
Klasa First po zmianie:
public class First {
public String msg = "hello";
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Wydaje się, że problem jest rozwiązany. Ale to dopiero początek innych problemów.
Jeśli bowiem, automatycznie dorzucamy te metody do wszystkich tysięcy atrybutów nowo tworzonych klas, to pierwszą rzeczą którą zauważamy, jest nagłe “spuchnięcie kodu”. Mamy kupę nieużywanych linii kodu, z których prawdopodobnie większość nie będzie nigdy używana!
Ale to nie wszystko. Załóżmy, że stajemy przed potrzebą zmiany nazwy atrybutu. Oczywiście, możemy to zmienić w jednym miejscu (w ciele akcesora), ale wtedy wprowadzamy chaos w pozostałej części odnośnie… nazw (atrybut “msg” zmieniony na “title” trochę głupio wygląda z akcesorami o nazwie “getMsg” i “setMsg”) Musimy przekopać się przez miliony miejsc w kodzie i pozmieniać nazwy starym wywołaniom.
Zobaczmy jak ta sytuacja wygląda w językach dynamicznych.
Python
Python (podobnie jak Java) pozwala na bezpośredni dostęp do atrybutów klasy. A co w sytuacji kiedy chcemy opakować atrybut akcesorami? Nic prostszego. Python pozwala na dodanie akcesorów wtedy, i tylko wtedy, kiedy są potrzebne. Na dodatek czyni to w sposób całkowicie przezroczysty dla pozostałej części kodu. Programista Javy może sobie o tym tylko pomarzyć.
class X(object):
def get_msg(self):
return self.__msg
def set_msg(self, val):
self.__msg = val
msg = property(get_msg, set_msg)
obj = X()
obj.msg = "hello"
print obj.msg
Python pozwala także związać z dowolną metodą, atrybutem, klasą czy modułem docstring, czyli tekst z dokumentacją, objaśnieniem itp. To jedna z genialnych cech Pythona specjalnie pomyślana dla leniwych programistów, którym nie chce się pisać dokumentacji. ;)
Ruby
W języku Ruby z definicji nie ma żadnej możliwości dostępu do atrubutów klasy inaczej jak przez akcesory. Odpada więc problem zapominania aby je dodać. Ruby jednak narzuca nazwy dla akcesorów (mają nazwę taką jak atrybut!) i całość wygląda tak, jakby operowano bezpośrednio na atrybucie.
class X
def msg
@msg
end
def msg=(val)
@msg = val
end
end
obj = X.new
obj.msg = "hello"
puts obj.msg
Dla osób, które nie lubią za dużo pisać, Ruby ma wygodne skróty. Powyższą definicję klasy można zapisać także w ten sposób:
class X
attr_accessor :msg
end
Istnieją także oddzielne skróty dla getterów i setterów. No i można po przecinku dodać akcesory dla całej grupy atrybutów.
PHP5
PHP w wersji 5 ma przebudowany model obiektowy od podstaw. Twórcy języka PHP nie starali się poprawiać modelu obiektowego PHP4 (był on tak zły, że prościej było im napisać go od nowa). W nowym PHP5 mamy już możliwość przezroczystego dodania akcesora.
<?php
class X {
private $attributes = array('msg'=>null);
private function __get($attrname) {
return $this->attributes[$attrname];
}
private function __set($attrname, $val) {
$this->attributes[$attrname] = $val;
}
}
$obj = new X();
$obj->msg = "hello";
print $obj->msg;
?>
Składnia może nie jest tak prosta jak w Ruby, ale (przynajmniej w tym miejscu), PHP5 zachowuje się tu sensownie i unika dylematów Javy.
Posted in Ruby, Java, Python | Tags java, php, python, ruby | 24 comments
Posted by Jarosław Zabiełło
Sat, 04 Feb 2006 19:39:00 GMT
W końcu udało mi się pozbyć Apache2 na rzecz lżejszego i szybszego Lighttpd. Największą trudność sprawiło mi przemapowanie proxy do Plone. Przeczesałem cały serwis Zope’a i Plone ale nie mogłem znaleźć nic na ten temat. Dopiero dzięki pomocy na forum lighttpd, cała operacja została zakończona sukcesem. Aktualnie dwie instancje Plone chodzą za Lighttpd zamiast Apache’a. PHP 5.1.2 działa mi w trybie FASTCGI, no i RoR (ten blog jest napisany w Railsach) również pod lighttpd.
Tags apache, lighttpd | 1 comment
Posted by Jarosław Zabiełło
Fri, 03 Feb 2006 14:40:00 GMT
Gdy w środowisku Pythona trwa wciąż zamieszanie i dyskusja wokół rywalizujących ze sobą frameworków (moim zdaniem największe szanse na zwycięstwo ma Django) tego problemu nie ma dla języka Ruby. Mimo, że istnieją także inne ciekawe frameworki, to Ruby on Rails zdecydowanie dominuje i pędzi do przodu. Framework jest dojrzały i okrzepnięty. Testowany przez tysiące developerów od wielu miesięcy.
Dokumentacja, API, filmy, FAQ, recepty, Wiki i książki powinny być wystarczające dla każdego kto by chciał spróbować możliwości tego frameworka.
RoR jest wzorcowym przykładem także tego, jak należy promować swój produkt. Oficjalna strona RoR jest bardzo czytelna i pomocna. Istnieje także polska strona Railsów dla osób które chciałyby wymienić się doświadczeniem w jęz. polskim.
Typowe obawy
Częstym argumentem przeciwko zainteresowaniu się Railsami jest to, że są one oparte na języku Ruby, którego się nie zna. Ja też miałem takie obawy na początku. Tym bardziej, że nie wydawało mi się, aby Ruby miał coś zdecydowanie lepszego do zaoferowania w stos. do Pythona.
W praktyce okazalo się, że Ruby nie jest wcale jakoś mocno trudniejszy od Pythona. Okazuje się bowiem, że do praktycznego posługiwania się Railsami nie trzeba wcale znać doskonale Rubiego. Dziwne, ale prawdziwe. Agile Web Development in Rails na końcu zawiera zwięzłe wprowadzenie do Rubiego na użytek Railsów. I jest w miarę wystarczające aby rozpocząć korzystanie z RoR.
Edytor do Railsów
Do wygodnej pracy z RoR, warto sobie zainstalować jakiś dobry edytor. Jest całkiem sporo opcji. Moim faworytem jest Arachno IDE i RadRails (do Railsów), oraz RDE do czystego kodowania w Rubym. Bardzo zachwalany przez wielu jest TextMate. (Niestety działa tylko pod systemem OS-X. Ale znajduje takie uznanie, że wiele osób dla tego edytora kupuje sobie Mini Maki. :)
Dokumentacja
Railsy posiadają bardzo dobrą dokumentację. Na stronie domowej są dostępne filmy (warto obejrzeć!), manuale, recepty, FAQ, WIKI, mnóstwo przydatnych materiałów. No i jak komuś mało, to są dostępne książki. Przede wszystkim kultowa Agile Web Development with Rails oraz PixAxe2 czyli Programming Ruby napisana przez twórcę jęz. Ruby. Poza tym w drodze jest cała grupa nowych książek.
Posted in Ruby on Rails | Tags rails | 2 comments
Posted by Jarosław Zabiełło
Wed, 01 Feb 2006 10:03:00 GMT
Guido van Rossum (twórca języka Python) w swoim blogu przygląda się zaletom i wadom szablonów Django oraz Cheetah.
Warto przyjrzeć się dyskusji, jaka się rozpętała w blogu bo do dyskusji włączyli się developerzy Myghty, Django i Cheetah.
To, że twórca Pythona w końcu zainteresował się kwestią webowych frameworków może w końcu z gąszczu rozwiązań wyłoni wyraźnych zwycięzców. W każdym razie cieszę się że developerzy frameworków włączyli się do tej debaty. Guido pracuje teraz dla Google. Python jest jednym z 3 głównych języków jakie tam są wykorzystywane. Być może Google będzie chciało używać któregoś z frameworków.
Posted in Python, Django, Pylons | Tags django, myghty, pylons | no comments
Posted by Jarosław Zabiełło
Sat, 28 Jan 2006 22:13:00 GMT
Wszystko wskazuje na to, że już wkrótce Django będzie posiadać mocne wsparcie dla AJAX’a. Po namyśle, wybrano bibliotekę Dojo.
Lider zespołu developerów Django ogłosił, że w ciągu nabliższych tygodni, wsparcie AJAX’a zostanie dodane do Django 0.92 Przebudowie ulegnie panel administracyjny wzbogacony o nowe możliwości biblioteki Dojo.
Posted in Django | Tags ajax, django | 2 comments
Posted by Jarosław Zabiełło
Fri, 27 Jan 2006 04:38:00 GMT
Twórca języka Python – Guido van Rossum z racji tego, że aktualnie pracuje dla Google, zainteresował się trochę więcej sprawą budowania aplikacji webowych w Pythonie. :) W swym artykule opisuje swoje wstępne wrażenia m.in. z kontaktu z Django oraz Ruby on Rails.
Zdaniem Guido, Django posiada ładny resolver adresów URL. Nie podoba mu się za to język szablonów, który zdaniem Guido jest zbyt “niepythonowy” (jakoś trudno mi sobie wyobrazić jak system szablonów może być w ogóle “pythonowy” :) No i to, że szablony Django kojarzą mu się z PHP, pokazuje że przyjrzał im się zbyt powierzchownie (ja tam nie widzę żadnego podobieństwa).
System szablonów Django jest ciekawym połaczeniem obiektowości pythonowego Cheetah i cech pehapowego Smarty. Może się podobać, lub nie, ale generalnie jest szybki i spełnia swoją rolę: jest adresowany do nieprogramistów.
Z kolei RoR posiada swój system szablonów który jest b. prosty: to po prostu połączenie Rubiego z HTML (b. podobnie do PHP czy JSP). To podejście ma także zalety jak i wady (np. trzeba znać Rubiego ale z 2-j strony nie trzeba uczyć się kolejnego pseudojęzyka do szablonów). Ostatecznie, jak komuś to nie odpowiada, to dla RoR istnieje alternatywny system szablonów zwany Liquid , system, który składnią przypomina szablony Django.
Szkoda, że Guido nie przyjrzał się bibliotece Pylons, który używa Myghty (niedawno wyszła wersja 1.0) a do rozwiązywania adresów używa b. ciekawej biblioteki – Routes.
Posted in Python | Tags cheetah, django, pylons, python, rails | no comments
Posted by Jarosław Zabiełło
Thu, 26 Jan 2006 09:47:00 GMT
Wyszła finalna wersja Plone 2.1.2. W stos. do porzedniej wersji dokonano ponad 300 poprawek. Plone jest jedną z najlepszych aplikacji CMS na świecie. Jest przykładem możliwości pythonowego serwera aplikacji Zope (Plone jest produktem Zope, czymś w rodzaju modułu do niego; takich produktów Zope ma tysiące).
Posted in Python, Zope & Plone | Tags plone | 2 comments
Posted by Jarosław Zabiełło
Thu, 26 Jan 2006 08:42:00 GMT
Niedawno wyszła finalna wersja Myghty 1.0. Myghty to framework napisany w Pythonie. Jest bardzo szybki (z tego co sprawdzałem, to jest on najszybszy z wszystkich frameworków opartych na jęz. dynamicznych). Mimo silnych inspiracji perlowym Masonem Myghty idzie znacznie dalej. W tej chwili posiada świetnie zaimplementowany cache, wygodny AJAX, i co jest najsilniejszą jego stroną: budowę komponentową. Myghty może działać jako CGI, fast-cgi, mod_python, WSGI.
Warto zwrócić uwagę na Pylons, który jest megaframeworkiem opartym na Myghty o filozofii inspirowanej przez Ruby on Rails i TurboGears.
Posted in Python, Pylons | Tags myghty, pylons | no comments
Posted by Jarosław Zabiełło
Thu, 19 Jan 2006 20:08:00 GMT
DHH, twórca Ruby on Rails w swoim blogu opisał różnicę między Django i RoR
Generalnie podsumował swoje stanowisko, które wyraził na konferencji.
Szkoda, że Adrian (ani nikt z developerów Django) nie napisał w swoim blogu żadnego komentarza. :(
Pod artykułem DHH jest sporo ciekawych komentarzy. Warto je poczytać.
Generalnie DHH został zaatakowany za niedocenianie roli umiędzynarodowienia RoR. Ludzie tego potrzebują i dobrze by było aby do RoR zostało dodane i18n. Jest kilka gotowych modułów, które do tego celu się nadają, np. Globalize
(Być może DHH powstrzymuje wdrożenie i18n z powodu słabej implementacji UTF-8 (Unicode w ogólności) w Ruby? W przeciwieństwie do Rubiego Python ma wzorcową obsługę Unicode, więc wszelkie konwersje znaków nie są żadnym problemem.) Oczywiście nie ma nawet co mówić o kompletnie nędznym supporcie Unicode i UTF-8 w PHP gdzie nie ma nawet jak przeprowadzić konwersji z latin2 do utf8 a podpieranie się kulawym modułem iconv tylko ucina teksty w wypadku znaku który nie da się poddać konwersji. Ale co ja będę kopał leżącego… ;)
Nie mogłem się powstrzymać ;) i dodałem także swój komentarz do tego tekstu i w ogóle do kwestii rzekomej wyższości Rubiego nad Pythonem. Wiekszość osób które wpisały się do blogu Davida najwyraźniej ma mikre pojęcie o Pythonie. To prawda, że Ruby ma kilka cech lepszych od Pythona, ale prawdą jest także że Python posiada kilka cech lepszych od Rubiego. Postaram się później to jakoś podsumować w oddzielnym tekście.
Posted in Django, Ruby on Rails | Tags django, rails | 5 comments
Posted by Jarosław Zabiełło
Wed, 18 Jan 2006 18:19:00 GMT
Widzę, że developerzy Django wzięli sobie do serca to, aby w sposób profesjonalny rozwijać swój framework. Nie tylko zaprzestali udostępniać źródła wyłącznie w SVN, ale zadbali także aby dokumentacja poprzedniego wydania została zamrożona razem z nim. Dzięki temu osoby używające wersji 0.90 mają dokumentację do wersji 0.90. Zaś ci, co używają wersję 0.91 mają oddzielną dokumentację do wersji 0.91.
Więcej na temat zmian w wersji 0.91: tutaj.
Posted in Python, Django | Tags django | no comments