Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: ActiveRecord, ORM
Forum PHP.pl > Forum > PHP > Pro
Stron: 1, 2
Sedziwoj
@regis87

I moim zdanie się mylisz, jak jest duży projekt bez ORM to masakra.
A co do wydajności, to jak masz wiele do wielu to tak zawsze jest, ale pamiętaj że korzystając z ORM najbardziej zachłanne rzeczy można przepisać na niższy poziom, czyli wykorzystując tylko abstrakcję bazy danych.

Do tego tak często nie doceniane widoki (przez większość zwane perspektywami) się przy stosowaniu ORM bardzo przydają.

Bo nie można zaprzeczyć, że ORM jest bardziej obciążający niż prosty dostęp, ale tak samo programowanie obiektowe (w tym wspomniane MVC) też jest wolniejsze od proceduralnego, jednak jakoś nikt na to nie zwraca zbytniej uwagi, chyba że jest jakiś punkt gdzie wydajność siada, ale to się małe fragmenty kodu zmienia, nie całą aplikację.
"Nie używajmy ORM", to prawie jakby mówić "piszmy w asemblerze". Może trochę przesadzam, ale jak się nie przestawia korzyści, i gada głupoty że w dużych projektach to lepiej bez... to mnie to irytuje.
Oczywiście zawsze się znajdzie coś co musi być napisane w asemblerze, ale to są na prawdę specyficzne rzeczy, a nie typowe aplikacje.
Cysiaczek
W 100% popieram. Za całą obiektową otoczką takiego Propela lecą zwykłe zapytania SQL, a jedynie konieczność utworzenie obiektów ze zwracanego wyniku lekko spowalnia. Lepiej zatem (jak mówi Sedziwoj) pisać z użyciem ORM, a potem jedynie odnaleźć bardzo czasochłonne operacje i je przepisać. Zauważ, że jak coś jest bardzo zasobożerne, to jest to zazwyczaj operacja na ogromnych ilościach danych na raz. Z autopsji powiem, bo dziś w nocy troszkę potestowałem, że operacje z wyszukiwaniem LIKE %xxx% na 250 000 rekordach to 3.49 s gołe zapytanie i 3.6 s Propel (wliczam utworzenie paczki z danymi).

Pozdrawiam.
splatch
Może w kwestii dużych projektów. Panowie nie zapominajmy, że duże projekty zazwyczaj stoją na dedykowanych maszynach, gdzie nie martwimy się tym, że nasz dostawca odetnie vhosta z racji na generowane obciążenie. Z drugiej strony - jakie są różnice czasowe, bo procentowo jest to dużo, ale czy będzie to odczuwalne dla użytkownika?
Nie pracowałem może w największych projektach, ale ilość linii kodu szła w tysiące czy też dziesiątki tysięcy. Gdyby każdy miał klepać zapytania, bo "tak jest wydajniej" to stracili byśmy na tym zbyt wiele czasu. Podstawą w takich wypadkach jest ORM i dobrze skonstruowane DAO, tak by nie pojawiały się metody duplikujące swe działania (pytanie - które DAO co może odczytywać). Zaoszczędzasz czas upraszczając sobie pracę z pozyskanymi danymi - w dalszym ciągu masz obiekty, w których możesz zawrzeć jakieś w miarę proste operacje, a nie półśrodki w postaci tablic bądź map. Chodzi o to, że gdy ORM stworzy Ci obiekt powiedzmy faktury - tworzysz metodę isPaid a w niej masz jakiś warunek. Normalnie, pisząc strukturalnie - ten warunek przerzuciłbyś do kontrolera bądź, co gorsza, widoku. Gdy coś się zmienia w sposobie uznawania płatności i masz ORM modyfikujesz tylko jedną metodę. Nie szukasz wszystkich warunków, gdzie dany typ danych się przewija.

Popatrzcie proszę na ORM przez perspektywę tego, co może dać nam obiekt smile.gif.
regis87
Może źle to ująłem. Mówiąc o dużych projektach nie mam na myśli bardzo rozbudowanych aplikacji z ogromną funkcjonalnością. Chodzi mi raczej o serwisy, które wystawione są na działanie bardzo dużej liczby użytkowników, a więc wywołań. Sam rozmiar bibliotek ORM daje do myślenia - po skompilowaniu DoctrinePHP do pojedyńczego pliku, zajmuje on prawie 700KB. Bez kompilacji jest jeszcze gorzej, bo wszystko rozbite jest na nie dziesiątki, ale setki plików klas. Z tego co wiem podobnie wygląda to w przypadku Propela.

Ale... jakiś czas temu trafiłem na bibliotekę realizującą wzorzec ORM, o nazwie Pork. Jest bardzo mała, szybka... trzeba to przetestować smile.gif

http://www.schizofreend.nl/Pork.dbObject
Cysiaczek
W przypadku Propela masz kilka plików + te, które sam wygenerujesz.
Rozumiemy, o co chodzi z dużą ilością odwiedzin, ale w którym momencie upatrujesz koniec sensowności ORM? Ile odwiedzin dziennie?
regis87
Nie potrafię tego oszacować. Ale kiedy wydajność staje się problemem, w ORM w pierwszej kolejności szukałbym oszczędności...
Cysiaczek
Jeśli dysponujesz dedykowanym serwerem, to moim zdaniem problemy zaczną się gdzieś w okolicach kilkudziesięciu tysięcy odsłon dziennie. Bardzo mało serwisów osiąga takie liczby. Ja bym w tym wypadku zainwestował w jakiś cache dla modelu danych, czy nawet w cachowanie całych stron www. Dopiero gdyby to nie pomogło, szukałbym optymalizacji zapytań. Nie będę rzucał liczbami, ale np. forum.php.pl mimo, że jest popularnym, średniej klasy forum nie osiąga jeszcze pułapu, przy którym zdycha sprzęt ;p

Pozdrawiam
Martio
Cytat(Martio @ 26.02.2008, 02:54:43 ) *
Używam Zend Frameworka. Chciałbym oddzielić warstwę logiki biznesowej od warstwy dostępu do danych. Dla warstwy logiki biznesowej najlepiej pasowałoby zastosować wzorzec "Domain Model". Jak wykorzystać "Zend_Db_Table" wraz z "Zend_Db_Table_Row" jako warstwy dostępu do danych? Mogę prosić o praktyczne zastosowanie?


W sumie jakby nie było, to połączenie Zend_Db_Table_Row z DomainModel to wzorzec wypisz wymaluj.... ActiveRecord smile.gif

Mam pytanie do osób, które korzystają z wzroca Active Record. Czy implementujecie w nim logikę biznesową?

Przykład:

  1. <?php
  2. class Produkt extends ActiveRecord {}
  3. class Zamowienie extends ActiveRecord {
  4. public function obliczWartoscZamowienia() {
  5.  $produkty = $this->pobierzZamowioneProdukty();
  6.  
  7.  $wartosc = 0
  8.  
  9.  foreach ($produkty as $produkt) {
  10. $wartosc += $produkt->pobierzCene() * $produkt->pobierzIlosc();
  11.  }
  12.  
  13.  return $wartosc;
  14. }
  15. }
  16. ?>
menic
@up: TAK
regis87
Skończyłem testy, pork.dbObject. Jest imponujący pod względem wydajności i małych rozmiarów, ale ma ten mankament, że aby obsługiwać relacje pola w tabelach muszą być nazywane według ustalonego schematu. Ten schemat tak naprawdę wymusza PRAWIDŁOWE nazewnictwo pól: pole primary nazywa się ID_obiekt, pola będące kluczami relacji mają nazwy odpowiadających kluczy primary itd... ale wiadomo jak to wygląda w praktyce, rzadko zdarzają się tak ładnie skonstruowane bazy smile.gif
Autor mówi, że to właśnie takie ograniczenie pozwala na tę oszczędność kodu. Ale w planach ma dodanie funkcjonalności tworzenia relacji "ręcznie".
Strzałek
To może ja coś skrobnę od siebie, o moich doświadczeniach z ORM, a konkretnie z Doctrine. Obok wcześniej wspominanego Propela jest to jedeno z najpopularniejszych narzędzi tego typu. Doctrine przeciwieństwie do Propela nie generuje żadnego kodu. Oraz właściwie nie uwalnia nas do końca od pisania SQL. Jednak MASYMALNIE go uprasza i przyśpiesza. Mianowicie, w Doctrine definuje się każdą tablę np. tak (przykłady będą z dokumentacji)

  1. <?php
  2.  
  3. class Article
  4. {
  5. public function setTableDefinition()
  6. {
  7. $this->hasColumn('name', 'string');
  8. $this->hasColumn('content', 'string');
  9.  
  10. $this->index('content', array('fields' => 'content',
  11. 'type'  => 'fulltext'));
  12. }
  13. }
  14.  
  15. ?>
  16.  
  17. <?php
  18.  
  19. class Product extends Doctrine_Record
  20. {
  21. public function setTableDefinition()
  22. {
  23. $this->hasColumn('id', 'integer', 4, 'primary');
  24. $this->hasColumn('price', 'decimal', 18, array('min' => 0, 'max' => 1000000));
  25. }
  26. }
  27.  
  28. ?>


W metodzie setUp ustawia się relacje do innych Rekordów (czyli klas "odpowiadających" tabelom w db). Przykładowe wyciąganie z bazy danych wygląda tak:

  1. <?php
  2. $q = new Doctrine_Query();
  3. $q->from('User u')
  4. ->leftJoin('u.Group g')
  5. ->innerJoin('u.Phonenumber p WITH u.id > 3')
  6. ->leftJoin('u.Email e');
  7.  
  8. $users = $q->execute();
  9.  
  10. //używanie danych, przykładowo ilustruje jak to wygląda. Nie wiem jakie są pola w 
    bazie dancyh. 
  11. $users[0] -> name;
  12. $users[0] -> Phonenumber -> number;
  13. ?>


Gdzie zamiast nazw tabel podaje się nazwy rekordów. To jest właśnie DQL - Doctrine Query Language. Zapytanie zostaje parsowane do zwykłego zapytania SQL a następnie zostaje zwrócona tablica z obiektami rekordów wcześniej zadeklarowanych. Wreszcie możemy zapomnieć o babraniu się z wyciąganiem danych zwróconych przez zapytanie. Wystarczy takie zapytanie jak powyżej i mamy wszystko z głowy. Dostajemy tablicę z ładnymi obiektami. DQL dodatkowo oferuje inne możliwości jak np. INDEXBY.

Gdyby jednak okazało się że nie da rady wykonać zapytanie przez DQL. Mamy wtedy 2 możliwości. Użyć Doctrine_RawSql, gdzie piszemy właściwie normalne zapytanie, a na końcu podpinamy obiekty. Albo możemy po prostu z Doctrine wziąć obiekt PDO i użyć go jak za starych (dobrych) czasów winksmiley.jpg Ja jak narazie tylko raz użyłem RawSql, a PDO? Szczerze to już nie pamiętam jak się z tego korzysta winksmiley.jpg

Tyle jeżeli chodzi o wyciąganie. Tworzenie i update rekordów jest również banalny i oczywiście odbywa się przez obiekty rekordu. Dodatkowo Doctrine posiada kilka pluginów które są naprawdę bardzo użyteczne i przydatne. Po więcej informacji odsyłam do dokumentacji.

Zaraz padną głosy że doctrine to krowa. Owszem, trochę to wszystko waży. Jeżeli chodzi jednak o wydajność nie poczułem żadnych niedogodności, więc to wszystko mi odpowiada (kolega mówił że jeden projekt składający się z 35 tabel napisał na doctrine smile.gif. Projekt się szybko rozwija. Autorzy zapowiadają że niedługo pojawi się nowa wersja z nowym parserem DQL, który ma być szybszy, chyba ma posiadać nawet jakieś nowe możliwości.

Generalnie, polecam Doctrine. Warto zainteresować się tym ORM.
Sedziwoj
Cytat
$users[0] -> Phonenumber -> number;


Czyli mam rozumieć, że on korzysta z stdClass? Czy działa podpowiadanie składni? Bo jak nie to zupełnie niewygodne jest takie coś w porównaniu do Propela.
Do tego trzeba się nauczyć dodatkowej składni DQL. Pisać mimo wszystko w PHP, w Prpelu jest to za darmo generowane, nie wiem czemu ale czuję że ludzie uciekają od złożoności działania, tracąc prostotę użytkowania.

Jakoś nadal nie widzę aby Doctrine był w czymś lepszy od Propela (wydajność nie biorę jako składową oceny)
Może ktoś mi napisze dlaczego miałby być lepszy od Propela, jest na pewno lepszy od ręcznego klepania, ale chyba szuka się najlepszych rozwiązań.
Strzałek
Cytat
Czyli mam rozumieć, że on korzysta z stdClass?


Nie rozumiem? Czemu niby? $users jest obiektem Doctrine_Colletion. Doctrine_Collection posiada kolekcje obiektów User (wcześniej zdefiniowanych przez nas rekordów). User natomiast ma zdefiniowane przykładowo relację do Phonenumbers. Właściwość Phonenumber obiektu user przechowuje obiekt Phonenumber. Wszystko bardzo logiczne.

Cytat
Do tego trzeba się nauczyć dodatkowej składni DQL.


No cóż. Nie przesadzajmy. Czy naprawdę musisz się uczyć całkowicie nowej składni? Po tyg. użytkowania wszystko staje się proste. Tworzysz łańcuszej jak zwykły SQL. Ba, lepiej. Masz mniej pisania, bo nie musisz przy joinach pisac ON ... bo relacje masz wczesniej zadeklarowane i same są dołączane przez parser DQL.


NIe napisałem że Doctrine jest lepsze od Propela. Sam przy wyborze ORM, przeczytałem trochę dokumentacji Propela i Doctrine i wybrałem opcje drugą. Nie mogę sie do końca wypowiadać o Propelu bo go nie używałem i nie znam. Wiem jednak (od samych użytkowników propela) że np. jakieś większe JOINY to już problem. Dodatkowo dla mnie pomyłką jest coś takiego:


  1. person.gender = 'M' AND (person.location IN ('Birmingham', 'Coventry') OR person.location = 'Manchester') AND (person.enabled <> 0) AND person.age > 16


W propelu żeby uzyskać coś takiego trzeba napisać:

  1. <?php
  2. $c = new Criteria();
  3. $crit0 = $c->getNewCriterion(PersonPeer::GENDER, 'M');
  4. $crit1 = $c->getNewCriterion(PersonPeer::LOCATION, array('Birmingham', 'Coventry'), Criteria::IN);
  5. $crit2 = $c->getNewCriterion(PersonPeer::LOCATION, 'Manchester');
  6.  
  7. // Perform OR at level 1 ($crit1 $crit2 )
  8. $crit1->addOr($crit2);
  9. $crit3 = $c->getNewCriterion(PersonPeer::ENABLED, 0, Criteria::NOT_EQUAL);
  10. $crit4 = $c->getNewCriterion(PersonPeer::AGE, 16, Criteria::GREATER_THAN);
  11.  
  12. // Perform AND at level 0 ($crit0 $crit1 $crit3 $crit4 )
  13. $crit0->addAnd($crit1);
  14. $crit0->addAnd($crit3);
  15. $crit0->addAnd($crit4);
  16.  
  17. // Remember to change the peer class here for the correct one in your model
  18. $c->add($crit0);
  19. $result = TablePeer::doSelect($c);
  20. ?>


Kod wygenerowany przez: http://propel.jondh.me.uk/ Halo? Mieliśmy sobie ułatwiać pracę i skracać czas.

Ale tak jak mówię. Nie używałem Propela więc cieżko jest mi coś więcej powiedzieć. Używam natomiast Doctrine i uważam to za świetne narzędzie. Polecam zerknąć do dokumentacji, poczytać.
athabus
Doctrine nie używałem więc trudno mi porównać prostotę pisania. Ale skłonię się ku opinii Sedziwoja. Dla mnie w Propelu największym plusem są właśnie klasy "szkieletowe" z możliwością ich rozbudowania. Najwięcej czasu w projekcie zawsze traciłem na tworzeniu prostych zapytań. Jest to (obok formularzy) jedna z najbardziej monotonnych części projektu.
Propel generuje w zasadzie wszystko co się da zrobić z automatu, a programiście pozostaje tylko dopisanie ewentualnych nakładek i dodatków.

Genialną zaletą Propela jest właśnie podpowiadanie składni (propel pozwala opcjonalnie nawet na dodanie komentarz phpDoc więc w PDT podpowiadanie działa nawet do zagnieżdżonych obiektów). Dzięki podpowiadaniu składni, nawet po powrocie do projektu po kilku miesiącach łatwo jest ogarnąć operacje na bazie.

Wady propela jak dla mnie są dwie:
- dosyć skomplikowane tworzenie niektórych zapytań (np. gdy przychodzi do łączenia Criterion'ów to do tej pory muszę czasami zaglądać do manuala)
- wydajność (chodzi o samo php, bo zapytania są raczej standardowe) - choć tak na prawdę wydajność to taki problem "urojony", bo w przeciętnej wielkości stronie, i tak nie ma to aż tak dużego znacznie. Gdybym pisał aplikację pod bardzo duże obciążenie to może bym się tym przejmował.
Cysiaczek
Nie używałem Doctrine, ale Propela owszem i rzeczywiście - bardziej złożone zapytania wyglądają jeszcze bardziej zawile w propelu niż w gołym SQL. Trzeba jednak zauważyć dwie rzeczy
1. Bardzo złożone zapytania można również napisać ręcznie, a potem na podstawie wyniku wypełniać obiekty. Propel ma do tego wsparcie.
2. Złożone zapytania stanowią w większości systemów margines. Są to wszelkiego rodzaju wyszukiwania wg. złożonych kryteriów, którym nie podoła żadna forma obiektowa (w sensie zachowania prostoty).

Mitem jest, że Propel ma słabą wydajność. Relacje są ustawiane sztywno w wygenerowanych klasach, a wysyłane zapytania niczym sie nie różnią od normalnych zapytań. Późniejsze wypełnienie obiektów trwa tyle samo, ile by zajęło zrobienie tego ręcznie. Można jednie polemizować, czy operacje na 1000 rekordów należy wykonywać z pominięciem kreacji obiektów, czy nie.

Wadą, którą widzę w Doctrine jest to, że trzeba pisać kod php dla każdej tabeli. Nie ma żadnego generatora? Naprawdę bardzo fajnie koduje się strukturę z XML, czy nawet w YAML (o to nawet polubiłem). Już nie wspomnę i łatwiejszej edycji takiej struktury:)

Pozdrawiam.
athabus
No niestety sama wydajnośc propel to nie do końca mit. Popatrz chociażby na ilość kodu klas generowanych przez propela. Samo załadowanie takiej ilości kodu to już niezłe obciążenie. Niektórych przypadkach propel też nie grzeszy wydajnością np. notka na blogu splatcha.

Ale tak jak pisałem wcześniej - to nie jest problem przy standardowej, dobrze napisanej stronie. Problemem może się natomiast okazać gdy na jednym hostingu próbujesz upchnąć 10-15 stron klientów itp., ale dla mnie to nie jest problem.
destroyerr
Więc Doctrine ma możliwość definiowania schematu w pliku YAML (w przeciwieństwie do propela). Dodatkowo ma jeszcze wbudowany mechanizm migracji.
Tak jak pisał athabus, najwięcej czasu zajmuje napisanie tych prostych zapytań. Kiedyś sobie tesowałem, i wyszło mi, że szybciej (i krócej) jestem w stanie napisać takie zapytanie w Propelu niż w Doctrine.
Dodatkowo Propel (oczywiście w edytorze z podpowiadaniem składni) nie pozwala nam popełnić literówki, Doctrine jednak tak. Ale racją jest, że trudne zapytania w Propelu to duży problem.
Jeśli chodzi o wydajność to Propel 1.2 jest generalnie wolniejszy od Doctrine, ale już Propel 1.3 jest szybszy (oczywiście nikt nie musi zgadzać się z tym benchmarkiem.
splatch
Jeśli idzie o szybkość Propela w wersjach <= 1.2 to rzeczywiście nie było z nią najlepiej. Wszystko było spowodowane nienajlepszą konstrukcją "bindowania" z wyniku zapytania do obiektów. Zbędne iteracje i porównania robiły swoje, w wersji 1.3 całość wygląda znacznie lepiej.

Zapytania - Panowie zapominacie o najważniejszej zalecie Criterii. Można w bardzo prosty sposób stworzyć mechanizm tworzący na bazie wysłanego formularza kryteria do wyszukiwania i sortowania. Kiedyś taki mechanizm stworzyłem, wystarczyło stworzyć formularz a po stronie serwera powiedzieć które tabele będą używane. Mechanizm na podstawie nazw pól tworzył wyniki (porównania, mniejszy-większy, like, plus ograniczenia na relacje). Następnie warunki wędrowała do sesji (tablice o określonej strukturze), gdy ktoś wracał na stronę z wynikami trafiał dokładnie w to samo miejsce gdzie był np. przed edycją, bo stworzenie Criteria z tablicy było tylko formalnością. Z takim mechanizmem tworzenie widoków z listami zajmowało mi około 15 minut (formularze do wyszukiwania plus wyświetlanie wyników). Rezultatem tego było to, że później widoki (listy) mogła robić osoba, która miała pojęcie o html i smarty. smile.gif

Wykorzystajcie Criterię nie tylko do tworzenia zapytań, na prawdę warto zainwestować w jakiś automatyczny mechanizm jeśli jeszcze go nie macie. Parę komponentów do warstwy prezentacji, parę klas, kilka pętli a zysk czasowy na prawdę znaczny.
Sedziwoj
Do tego skomplikowane zapytania można oprzeć na widokach, a zdefiniować takie tabele w XML/YAML jako tylko do odczytu. Wtedy nie ma tego kodu po stronie PHP. @splatch dokładnie, wystarczy mały generatorek Criteria i mamy właściwie od ręki listy z filtrowaniem i stronicowaniem. Wystarczy powiedzieć jakie pole odpowiada któremu w bazie i jakie warunek porównania.

Ale tak jeszcze podkreślę, pamiętajcie że baza ma też coś więcej niż tabelki, więc wykorzystujcie te mechanizmy aby ułatwić sobie życie.
Strzałek
Cytat
Wadą, którą widzę w Doctrine jest to, że trzeba pisać kod php dla każdej tabeli. Nie ma żadnego generatora? Naprawdę bardzo fajnie koduje się strukturę z XML, czy nawet w YAML (o to nawet polubiłem). Już nie wspomnę i łatwiejszej edycji takiej struktury:)


Oczywiście że jest. Można zdefiniować to w YAML, albo wygenerować sobie gotowe rekordy od razu z bazy danych.

Czy mówiąc o prostych zapytaniach macie na myśli to Doctrine User Manual::Magic Finders ?

Polecam poczytać dokumentacje. Doctrine oferuje nam naprawdę bardzoooo dużo.
Sedziwoj
@Strzałek tylko powiedz w czym to jest lepsze od Propela? Bo jak już mówiłem to porównanie jest ważne, aby wykazać co jest lepsze. Bo ciągle jako porównanie bierzesz system bez ORM (źle się pisze bez klawiatury)
Cysiaczek
Uh, jak mówiłem - nie używałem Doctrine. Jak jest generator, to ok smile.gif. W takim wypadku kwestia wyboru pomiędzy Propelem, a Doctrine, to jak wybór pomiędzy różnymi systemami szablonów ;] Jak będę miał czasa to zerknę na Doctrine i zobaczę co tak wychwalacie ;p

Pozdrawiam.
Sedziwoj
Cytat(Cysiaczek @ 15.03.2008, 20:26:32 ) *
Uh, jak mówiłem - nie używałem Doctrine. Jak jest generator, to ok smile.gif. W takim wypadku kwestia wyboru pomiędzy Propelem, a Doctrine, to jak wybór pomiędzy różnymi systemami szablonów ;] Jak będę miał czasa to zerknę na Doctrine i zobaczę co tak wychwalacie ;p


Cyba nie czytasz dokładnie, w Doctrine nie ma wsparcia do środowisk programistycznych, więc musisz pamiętać jakie masz pola w "tabelach"

(jeszcze raz rozbieram klawiaturę i czyszczę jeśli nie pomoze to kupuje nową, bo klawisze mi nie działają wszystkie )

EDIT:
No to będzie zakup nowej klawiatury :|
Cysiaczek
Oj tam smile.gif
Mi podpowiadanie składni w eclipse działa jak mu się podoba i to w momentach, gdy nie jest mi potrzebne, więc nie przekonuje mnie ten argument. Bardziej patrzę na funkcjonalność samej biblioteki.

Pozdrawiam.

p.s
Ja pisze z nowej klawiatury - dwa dni temu kupiłem snitch.gif
Sedziwoj
Cytat(Cysiaczek @ 15.03.2008, 22:22:26 ) *
Oj tam smile.gif
Mi podpowiadanie składni w eclipse działa jak mu się podoba i to w momentach, gdy nie jest mi potrzebne, więc nie przekonuje mnie ten argument. Bardziej patrzę na funkcjonalność samej biblioteki.


Tylko że to jest duże funkcjonalne udogodnienie, a z podpowiadaniem to było na którymś blogu, do tego Ctrl+Spacja zawsze zadziała. (tylko aby obiekty propela były w projekcie)

Cytat
p.s
Ja pisze z nowej klawiatury - dwa dni temu kupiłem snitch.gif


A pochwal się jaką? Bo ja nie mogę się zdecydować...

--- cysiaczek---
Wybacz, że tu, ale nie chce spamic
http://merlin.pl/Klawiatura-TRACER-Ibiza-T...208,556750.html
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.