Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]OOP Ucze się... konstruktor
Forum PHP.pl > Forum > Przedszkole
cykcykacz
Witam,
nie umiem ogarnąć konstruktora kiedy go używamy i po co?
Może ktoś mi wytłumaczy?
W poniższym przykładzie mamy klasę dog w której mamy publiczny dostęp do atrybutu $name oraz konstruktora.
Z tego co rozumiem konstruktor jest to metoda która w chwili powstania obiektu nadaje mu jakiś właściwości?
Ale po co i kiedy tego mam używać?
klasa
Kod
<?php
class Dog{
    public $name;//atrybut przechowujący imię psa

    /*konstruktor*/
    public function __construct($name){
        $this->name = $name;
    }
    public function roar(){
        echo 'chał chał';
    }
    //ciach
}
?>

obiekt
Kod
<?php
require('class.dog.php');
$reksio = new Dog('Reksio');
echo $reksio->name; //atrybut "name" publiczny, więc wyświetlone zostanie 'Reksio'
$reksio->roar(); //metoda roar() publiczna, więc wyświetlone zostanie 'chał chał'
?>
mat-bi
Ludzie...

http://museum.webcity.pl/webcity/artykuly.php/t/59

Naucz się podstaw, potem poagadamy
cykcykacz
Już miej więcej się domyśliłem, że konstruktora używamy do takich akcji jak np: połączenia się z bazą danych podanie nazwy użytkowanika, hasło.
Incjalizujemy połączenie z bazą danych.
Tak?
thek
Ech... Konstruktor to SPECJALNA metoda, która ZAWSZE sama się uruchamia, gdy tworzony jest obiekt tej klasy. Jeśli więc ma ona posiadać jakieś wartości od razu na starcie, to używamy do tego konstruktora. Klasa bowiem sama nie powinna mieć z góry ich narzuconych, czyli:
  1. class Jakas_tam {
  2. private $property = 'Tu wartość domyślna';
  3. }

to błąd, gdyż powinno być:
  1. class Jakas_tam {
  2. private $property;
  3.  
  4. public function __construct() {
  5. $this->property = 45;
  6. }
  7. }
Crozin
@thek: A to niby czemu coś takiego miałoby być błędem?

Zadaniem konstruktora jest przygotowanie obiektu do pracy. W nim wykonuje się to wszystko co jest potrzebne do tego by obiekt w ogóle był zdatny do użytku. Przykładowo jeżeli mielibyśmy obiekt typu File moglibyśmy w konstruktorze jako argument podać URL (np. ścieżkę w systemie plików) pliku. Taki konstruktor mógłby pobrać od razu informacje o tym czy plik już istnieje.
Przez konstruktor możemy przekazać też różne dane, które są potrzebne do działania obiektu, przykładowo może to być wspomniany obiekt pozwalający na komunikację z bazą danych.
cykcykacz
Odbiegając od tematu ciężko się nauczyć mi osobiście początkującemu programiście Programowani obiektowego z kliku powodów:
1)- korzystam z książki Zaaansowane programowanie plus , http://pl.wikibooks.org/wiki/PHP/Czym_jest...ie_obiektowe%3F, http://php.pl/phppl/Wortal/Artykuly/PHP/Po...lasa-Co-to-jest, http://php.pl/Wortal/Artykuly/PHP/Podstawy...poczatkujacych5 w każdym źródle wiedzy jest to trochę inaczej opisane ... haha.gif
2) na początku programowałem strukturalnie, i teraz natłok nowych pojęć też jest barierą
3) nie mam kontaktu z żadnym koderem, który zarabia pisząc w ten sposób

Ale to tak tylko napisałem od siebie snitch.gif
Pozdrawiam
everth
@Crozin - błąd nie ale thek ma trochę racji, w podejściu do domyślnych właściwości obiektów jest trochę niekonsekwencji. Np. mogę im przypisać w deklaracji typ prosty ale już nie złożony obiekt (co jest sensowne, choć niekonsekwentne). I te ostatnie inicjuje się w konstruktorach. Jak dla mnie to co powiedział thek jest po prostu konsekwentnym stosowaniem pewnej zasady.
thek
Może wyjaśnię o co mi chodzi, bo everth "widzi" o co mi biega smile.gif Klasa to tak naprawdę jedynie szablon, na podstawie którego buduje się obiekty, a więc nie powinna o nich w sumie nic, lub naprawdę niewiele wiedzieć. To pieczątka, która wali nieskończoną (no chyba że to singleton wink.gif ) ich ilość od matrycy. Tymczasem obiekty mogą być różnie inicjowane właśnie konstruktorem i to on powinien ustawiać wedle swoich możliwości właściwości obiektu, a nie klasa. Weźmy klasę Samochód... Czy jest dla nas istotne czy jest on 3-, 4-, 5-drzwiowy w momencie deklaracji? Nie! To staje sie istotne dopiero gdy obiekt ma zostać utworzony. I to samo tyczy innych własności klasy. My mamy być tylko świadomi ich istnienia, ale dopiero podczas tworzenia obiektu powinno nastąpić przypisanie im wartości. Do tego czasu może tam być cokolwiek. Klasa nie powinna nawet typów prostych im przypisywać. To zadanie konstruktora i nie powinno się go w tym wyręczać. Jeśli byłoby takie działanie pożądane, to coś takiego jak konstruktor by nie powstało. Bo jaki ma sens ta metoda, skoro i tak można by było zainicjalizować klasę wartościami. Konstruktor stał by się zbędny. De facto konstruktor i destruktor to pozostałości OOP z C++. Tam ich sens jest o wiele ważniejszy gdy następuje dynamiczne przydzielanie pamięci chociażby. Ogólnie ich użycie w środowisku web jest mocno ograniczone funkcjonalnie z racji bezstanowości, ale w aplikacji desktopowej ich użycie daje kilka fajnych możliwości w czasie rzeczywistym. W sieci, w której żądania są z natury rzeczy krótkie, "zabawa" z konstruktorami została mocno ograniczona. A szkoda, bo już same przeciążanie konstruktorów to fajna rzecz.

EDIT: Byłbym zapomniał... Osobiście czasem naginam to i mam jeden, jedyny wyjątek od tej reguły: stała i niezmienna wartość mająca być widoczna dla wszystkich obiektów danej klasy. Coś widocznego tylko dla tejże klasy i zazwyczaj też staram się tę zmienną zabezpieczyć przed przypadkowym nadpisaniem stosując const smile.gif To jedyny wyjątek, kiedy przewiduję, że można nadać wartość własności klasy już na etapie jej definicji.
Crozin
@thek: jak zwykle nie zawiódł. Ładny wywód i trzykrotne odejście od tematu zamiast krótkiej i precyzyjnej odpowiedzi. wink.gif

Rozumiem co masz na myśli, nie mniej jednak trudno mi się w pełni zgodzić ponieważ nie dostrzegam jakiś zagrożeń czy niedogodności związanych z bezpośrednim definiowaniem wartości przy deklaracji właściwości obiektu (pomijamy tutaj aspekt kolejnej ułomności PHP, które pozwala tylko na przypisanie prostych wartości). Dlatego proszę o podanie jakiegoś przykładu demonstrującego.

Napisałeś, że przypisywanie domyślnych wartości to zadanie obiektu, nie klasy. Trzeba jednak pamiętać jaka jest kolejność działań interpretera przy tworzeniu obiektu (tutaj akurat odniesienie do Javy ale jestem niemalże pewien, że PHP działa dokładnie tak samo - niestety nie da się w nim tego tak łatwo sprawdzić).

0. Uruchomienie bloku static - w PHP tego nie ma.
1. Utworzenie obiektu.
2. Zainicializowanie wszystkich właściwości.
3. Uruchomienie konstruktora.
( http://ideone.com/XPG8N )

Także przypisanie domyślnych wartości bezpośrednio przy ich deklaracji można w przypadku obiektów traktować jako prosty "skrót". Bo w sumie działa to tak jakbyś te przypisania dał na sam początek konstruktora.

Jednakże tak jak napisałem, proszę o jakiś przykład gdzie takie postępowanie mogłoby prowadzić do jakiś problemów. Przykład nie koniecznie musi być z PHP.
cykcykacz
Stworzyłem klasę, która łączy się z bazą oraz pobiera dane.
klasa:
Kod
<?php
class database {

    private $id;
    private $name;
    private $description;
    private $age;
    private $con;
    
    public function __construct($widgetID) {
        
        $this->con = mysql_connect("localhost","root","");
        if (! is_resource($this->con))
        {
            throw new Exception('Could not connect: ' . mysql_error());
        }
        
        
        
        $db_selected = mysql_select_db("my_db", $this->con);
        if (!$db_selected) {
            die ('Nie można ustawić foo : ' . mysql_error());
        }
        
        $sql = mysql_query("SELECT * FROM Persons WHERE personID='$widgetID'");
        
        if(! is_resource($sql)) {
            throw new Exception("Błąd przy wykonywaniu instrukcji wyboru");
        }
        
        $data = mysql_fetch_array($sql);
        $this->id = $widgetID;
        $this->name = $data['FirstName'];
        $this->description = $data['LastName'];
        $this->age = $data['Age'];
    }
    
    public function getName() {
        return $this->name;
    }
    
    public function getDescription() {
        return $this->description;
    }
    
    public function getAge() {
        return $this->age;
    }
    
    public function __destruct() {
        mysql_close($this->con);
    }
}
?>

Wyświetlenie danych:
Kod
<?php
    require_once('class.database.php');
    
    try {
        $objWidget = new database(2);
        
        print "Imie: ". $objWidget->getName() . "<br>\n";    
        print "Nazwisko: ". $objWidget->getDescription() . "<br>\n";
        print "Wiek: ". $objWidget->getAge() . "<br>\n";
        
        } catch(Exception $e) {
            die("Wystąpił problem: " . $e->getMessage());
        }
?>

Wydaje mi się że kod jest poprawny. Teraz mogę sobie dodać tutaj dodawanie, edytowanie oraz usuwanie danych smile.gif .
Co do konstruktora, rozumiem że jest on uruchamiany w momencie stworzenia obiektu czyli od razu jesteśmy połączeni z bazą danych,
Kod
$objWidget = new database(2);

i mamy ustawioną właściwość 2 czyli wiersz w bazie na którym chcemy pracować.
mat-bi
W konstruktorze nie robimy zwykle takich rzeczy jak mysql_query, mysql_fetch_assoc etc., przerzuca się to do innych funkcji w klasie
thek
Spróbuj w C/C++ tak zrobić, to kompilator Ci się na starcie od razu oburzy. Język ten nie pozwala mieszać definicji, deklaracji i inicjalizacji w wielu wypadkach w jeden wielki mix. Ogólnie nie jest to jakiś błąd, który powowdowałby problemy, ale przypuśćmy, że można w klasie na etapie definicji podać i przypisać jako własność składową wskaźnik/uchwyt do pliku. Dajmy na to o składni fopen('nazwa.rozszerzenie', 'w'); i nie wiem czy zauważysz co się wtedy dzieje gdy zechcemy zmienić plik w późniejszym etapie... Plik zostanie otwarty, wyczyszczony i będzie czekał. Jeśli w tym momencie zechcesz zmienić plik otwarty na inny to mamy bajzel poprzez otwarty niewłaściwy plik, na dodatek jest on wyzerowany flagą "w" i musimy najpierw go zamknąć zanim tej właściwości przypiszemy wskaźnik do nowego pliku. A tak moglibyśmy nazwę pliku podawać dopiero na etapie konstruktora, przy czym jakiś plik byłby domyślny. Rozwiązanie znacznie bardziej eleganckie. Oczywiście PHP na fopen i przypisanie uchwytu do pliku w deklaracji klasy nie pozwala ( właściwie to nie testowałem tego, ale zapewne nie pozwala tongue.gif ). Ale może istnieje język na to pozwalający. W końcu miałem tylko możliwy przykład podać, gdzie to byłoby działanie niepożądane wink.gif

Mat-bi...Czemu nie? Klasa Database, która jako statyczną własność "trzymie" identyfikator połączenia to nie jest takie złe rozwiązanie. Potem jej tylko używasz gdzie chcesz, nie martwiąc się o nic smile.gif

Oczywiście mówię tu tylko o ustanowieniu ,skonfigurowaniu połączenia w konstruktorze i nic więcej.
everth
Tak mnie naszło - czy PHP w trakcie inicjowania obiektów rzeczywiście inicjuje wszystkie właściwości? Czy może robi to w momencie pierwszego odwołania do nich? Bo w zasadzie klasa może być przez PHP inicjowana jako "czysta" - skoro można dynamicznie dodawać właściwości to dlaczego wymuszać ich alokację w momencie tworzenia obiektu?

W takim wypadku przestaje mieć znaczenie gdzie nastąpi zainicjowanie właściwości obiektu - czy w definicji klasy, czy w konstruktorze - i tak realnie nastąpi to w momencie użycia. Pozostaje więc jedynie kwestia formalna (czyli że klasa to szablon struktury i nie powinna zawierać danych)
Crozin
@thek: A jakiś argument przeciw, ale nie bazujący na błędnym kodzie? Bo pokazałeś przykład, gdzie jako domyślne wstawia się coś co w cale nie musi być domyślne czy też "wymagane".

@everth: Musiałbyś albo zgłębić źródła albo zrobić jakieś testy (np. zużycia pamięci), ale obstawiam, że przy tworzeniu obiektu tworzone są od razu wszystkie właściwości, a ich wartości są inicjowane.
thek
Czy ja wiem czy takie nie domyślne? Mam klasę w Kohanie, która loguje różne operacje nie będące błędami aplikacji, ale niedozwolonymi użytkownikowi (próby ataków głównie) i domyślnie ona zapisuje do tego samego pliku zawsze. Oczywiście gdyby php na to pozwalał, mógłbym od razu uchwyt do pliku walnąć przy definicji i to jest ta sytuacja, o której pisałem. Teoretycznie nie byłby to błąd, ale z automatu pojechaliśmy ostro po jej reusability. Co do niedogodności, to można by nieco zahaczyć o "widoczność". Użytkownik/programista bez spoglądania do wnętrza klasy nie będzie świadom istnienia tej właściwości i jej wartości. Zostaje ona bowiem ustawiona bez jego udziału. Jeśli na etapie tworzenia obiektu od tej własności może zależeć jakiś wynik, to sytuacja ta może prowadzić do zafałszowanych rezultatów. Przykład z plikami jest tutaj dobry ponieważ próba wywolania choćby po raz drugi obiektu zwróci wartość nieoczekiwaną. Pierwsza instancja zwinie plik i go zablokuje, a druga będzie próbowała dobrać się do zablokowanego pliku i zrobi zonka i zakleszczy się lub co gorsze - nadpiszą swoje wyniki, bo przecież użytkownik nie wie z jakim plikiem i w jakim trybie otwarcia ma do czynienia. Informacje te powinien sam użytkownik jawnie podać w konstruktorze. Problem mogą sprawić zadeklarowane wartości dla właściwości statycznych, które przecież choć wspólne dla klasy mogą mieć w wyniku działania programu inną wartość niż zadeklarowana w klasie, co będzie mylące podczas analizy kodu. Ogólnie właśnie zmienne statyczne to jest tutaj możliwe źródło pomyłek.
Crozin
Temat wiąże się z OOP więc proszę mi tutaj Kohany nie mieszać... tongue.gif

A wracając do tematu, podany przez Ciebie przykład nie powinien nigdy w ogóle się pojawić. Przecież coś tak "dynamicznego" jak ścieżka do jakieś pliku może nawet nie być jednolita w obrębie jednego projektu - o różnych nie wspominając. Temat dotyczy takich sytuacji:
  1. class User {
  2. private $active = false;
  3.  
  4. // VS
  5.  
  6. private $active;
  7.  
  8. public function __construct(...) {
  9. $this->active = false;
  10.  
  11. ...
  12. }
  13. }
  14.  
  15. class Logger {
  16. const WARNING = 1;
  17. const ERROR = 2;
  18. const FATAL_ERROR = 4;
  19.  
  20. const ALL = 7;
  21.  
  22. private $level = self::ALL;
  23.  
  24. // VS
  25.  
  26. private $level;
  27.  
  28. public function __construct(...) {
  29. $this->level = self::ALL;
  30.  
  31. ...
  32. }
  33. }


I trzeba rozróżnić to co w ogóle może być domyślne, od tego co jest bardziej "dynamiczne" i nie ma wartości domyślnej:
  1. class SomeClass {
  2. private Random random = new Random(); // OK
  3. private BufferedReader stdin = new BufferedReader(...("/ścieżka/do/pliku/z/przykładowo/logami.log")); // BŁĘDNE
  4. }
thek
[offtop]No nie mów, że Kohana to nie OOP? wink.gif Ja rozumiem, że to nie MVC, ale akurat OOP można ją nazwać biggrin.gif [/offtop]

Co do przykładu to akurat bardziej miałem na myśli sytuację, gdzie własność może być różnego typu i jej ustawienie jest na poziomie tworzenia obiektu. Przykładowo poprzez różne wersje konstruktora inicjalizuje się ona raz obiektem, raz tablicą, a raz skalarem lub w sytuacji bardziej subtelnej - reaguje inna wartością tego samego typu na tworzenie z poziomu www i CLI.
Crozin
Ale przecież oczywistym jest, że jeżeli ustalenie czegoś nie jest tak trywialne, nie stosuje się wartości domyślnych. Tutaj mowa jest o przypadkach, gdy domyślna wartość jest używana przykładowo wyłącznie na potrzeby obiektu (patrz przykład z Randomem) czy też jej zmiana nie niesie za sobą żadnych komplikacji (patrz przykład ze stanem użytkownika czy poziomem zapisywanych błędów).

Tak więc czy poza jakąś niezbyt jasną i mało popularną konwencją w przykładach z klasami User i Logger z mojego wcześniejszego postu jest coś nie tak? Czy preferowany przeze mnie pierwszy zapis może prowadzić do czegoś "niewygodnego"?

Cytat
[offtop]No nie mów, że Kohana to nie OOP? Ja rozumiem, że to nie MVC, ale akurat OOP można ją nazwać [/offtop]
Nie będziemy ciągnąć tutaj kolejnego offtopicku - zapraszam na PW / nowy wątek - ale mogę się zgodzić na nazwanie Kohany frameworkiem OOP gwałcącym większość podstawowych zasad OOP. wink.gif
thek
Cytat
jeżeli ustalenie czegoś nie jest tak trywialne, nie stosuje się wartości domyślnych
To akurat sprawa dyskusyjna. Dla różnych osób różne rzeczy mogą być trywialne wink.gif To z randomem akurat moim zdaniem nie jest dobry przykład, ponieważ dostajemy i tak coś "przewidywalnego" co do typu i wartości, a więc możemy to obsłużyć prosto bez ingerowania zarówno we własności klasy jaki i metody implementowane przez nią. Klasa nie powinna nic wiedzieć o swoich obiektach a jedyne wartości powinny być jej przekazywane z zewnątrz lub być jako domyślne przekazywane w liście argumentów. W sumie więc w przykładzie podanym a tyczącym poziomów oba przypadki uznaję za nieprawidłowe. Zarówno:
  1. private $level = self::ALL;

jak i
  1. private $level;
  2. public function __construct(...) {
  3. $this->level = self::ALL;
  4. ...
  5. }
są nieprawidłowe, gdyż na sztywno ustawiają albo w klasie albo w obiekcie pewne wartości, a jak wspomniałem, powinny one być do obiektu przekazane z zewnątrz, tak więc metodą poprawną byłoby użycie:
  1. public function __construct( ..., $level = 7) {
  2. $this->level = $level;
  3. ...
  4. }
gdyż zarowno klasa nie zna wybranego poziomu obiektu, jak i do czasu utworzenia instancji oraz wywołania konstruktora także nie jest to narzucane, a dodatkowo nie modyfikujemy logiki samego konstruktora specjalnie pod przypadek domyślny. Niezależnie czy wywołany zostanie konstruktor domyślny czy nie, zostanie on obsłużony identycznie, gdyż różnić się będzie jedynie parametrami. To co jest w php a co Ty popierasz, to zwyczajnie przesunięcie tego parametru domyślnego z listy wprost do definicji, co według mnie nagina w pewien sposób abstrakcyjność klasy.

EDIT: Byłbym zapomniał... Wątku o OOP w przypadku Kohany i wszelkich frameworków nie musimy ruszać, gdyż chyba oboje jesteśmy świadomi, że chyba każdy go w mniejszym lub większym stopniu narusza smile.gif
Crozin
Ależ Ty mącisz... wink.gif Wymieszałeś prywatne sprawy obiektu z zewnętrznymi zależnościami, domyślne wartości z czymś na styl stałych itd.

  1. class Logger {
  2. const LOG_NOTICE = 1;
  3. const LOG_WARNING = 2;
  4. const LOG_ERROR = 4;
  5.  
  6. public function setLogLevel($level) {
  7. $this->level = $level;
  8. }
  9.  
  10. // I teraz w czym jest cały "problem" (wartość domyślna ułatwiająca pracę z kodem)
  11. private $level;
  12.  
  13. public function __construct() {
  14. $this->level = slef::LOG_ERROR;
  15. }
  16.  
  17. // VS
  18.  
  19. private $level = self::LOG_ERROR;
  20.  
  21. public function __construct() {
  22. }
  23. }
W obu przypadkach jak Ci nie pasuje domyślne ustawienie pokrywające powiedzmy 90% przypadków użycia możesz zmienić sobie poziom logowany błędów:
  1. $loggger = new Logger();
  2. $logger->setLogLevel(Logger::LOG_WARNING | Logger::LOG_ERROR);


Uznałeś, że drugi zapis jest przynajmniej częściowo niepoprawny. Ja się pytam dlaczego? Jakie niebezpieczeństwa czy problemy mogą wynikać z takiego zapisu?

Cytat
EDIT: Byłbym zapomniał... Wątku o OOP w przypadku Kohany i wszelkich frameworków nie musimy ruszać, gdyż chyba oboje jesteśmy świadomi, że chyba każdy go w mniejszym lub większym stopniu narusza
Każdy większy projekt ma jakieś delikatne defekty. Nie da się napisać kodu doskonałego z jakąś tam ideologią. Ale nie każdy projekt tak gwałci OOP jak Kohana.
thek
Ależ nie mieszam... Zauważ co uznaję za prawidłowe podejście:
1. Nie ustawianie w definicji klasy wartości domyślnej na sztywno - stąd odpadł Twój pierwszy przypadek
2. Nie ustawianie w konstruktorze wartości domyślnej na sztywno z powietrza by być może nie została ona potem zamieniona na inną w trakcie działania konstruktora.
3. Ustawianie wartości domyślnej w klasie podczas tworzenia obiektu poprzez konstruktor.

Właśnie dlatego jedyną dla mnie w pełni naturalną formą jest ustawianie atrybutów poprzez domyślną wartość parametru konstruktora, czyli niejako uczynienie go z automatu jego parametrem opcjonalnym. To sprawia, że klasa nie wie jak zainicjalizowany będzie obiekt, obiekt także tego nie wie, ale może to obsłużyć, ponieważ nawet w przypadku braku tego parametru z zewnątrz, ma on go ustawionego na poziomie definicji metody. Dzięki temu nie musimy ingerować zarówno w kod klasy jak i kod samej metody. Ich implementacje pozostają nienaruszone, zmienia się jedynie lista parametrów, a więc praktycznie nie ingerujemy w nic.

Dlatego nie traktuj tego co piszę jako błędu czy problemu, ale pewien "paradygmat" czy może bardziej konwencję jak maksymalnie odseparowywać pewne warstwy od siebie. W tym przypadku jak odizolować deklarację od definicji.

Zauważ, że jest różnica pomiędzy:
function metoda( $param, $param2 )
function metoda( $param = 'default1', $param2 = 'default2' )

Pierwsza zupełnie nie sugeruje tego, że wartości parametrów są domyślne, a co gorsze, wewnątrz metody musisz i tak dodatkowo ich obsługę dopisać, gdyż konieczne jest sprawdzenie czy parametry przekazano, a jeśli nie, by użyto wartości domyślnych. Rozwiązaniem tego problemu jest:
a) ustawienie wartości zanim ruszy konstruktor (czyli na poziomie definicji klasy),
cool.gif napisanie konstruktora domyślnego czyli innymi słowy sięgnięcie po polimorfizm.
Jako że cool.gif w PHP nie jest możliwe w znany z języków silnie typowanych sposób, to sam widzisz czemu zezwolono na "brudzenie" definicji klasy.
everth
[bezzwiazkuztematem]
Nie wiem czy zauważyliście ale to jest przedszkole wink.gif Pewnie zakładający ten temat już dawno uciekł przerażony waszą dyskusją. Może przenieście to do bardziej adekwatnego miejsca?
[bezzwiazkuztematem]

Sprawdziłem - ZE zawsze inicjuje domyślne właściwości w szablonie klasy. Ostatecznie zostaje przy swoim - typy proste w definicji, tablice i obiekty w konstruktorze, narzut sztywnego wywołania nie powinien być problemem.
Crozin
Cytat
Właśnie dlatego jedyną dla mnie w pełni naturalną formą jest ustawianie atrybutów poprzez domyślną wartość parametru konstruktora
Czyli na dobrą sprawę przenosisz jedynie sztywno zapisaną wartość domyślną z miejsca deklaracji właściwości w miejsce deklaracji argumentu dla konstruktora, tak? Przecież to nie zmienia kompletnie niczego. Klasa nadal wie jak obiekt może zostać skonstruowany (chociaż nie bardzo wiem co złego z tego faktu wynika). Dodatkowo możesz skończyć z paskudnym konstruktorem posiadającym powiedzmy trzy normalne, wymagane argumenty (ok) i jeszcze sześć opcjonalnych (niezbyt fajna sprawa).

Na dobrą sprawę jedyne co wg mnie możesz przy takim podejściu zyskać to pozbycie się jakiś nadmiarowych przypisań wartości. Ale nie oszukujmy się... nie jest to nawet warte rozpatrzenia, bo wartości domyślne stosuje się tam gdzie:
1. Pokrywają one zdecydowaną większość przypadków użycia.
2. Są "lekkie". Raczej nie daje się jako domyślnych obiektów które potrzebują 10 MiB pamięci i 2 sekund na sam start. A w normalnym przypadku (gdy jest to powiedzmy przykładowo wartość logiczna) domyślne przypisanie wartości powiedzmy false tylko po to by zaraz potem czy to przez konstruktor czy jakiegoś settera zmienić tą wartość na true nie kosztuje nic.
thek
Jak najbardziej masz rację Crozin. To nie zmienia niczego jeśli chodzi o efekt i złego nic nie czyni, ale to już napisałem ciut wyżej w poście. Tutaj chodzi bardziej o trzymanie się paradygmatów OOP. Php pozwala je nieco nagiąć i robi to w sposób dający pewną wygodę. To ile parametrów ostatecznie trafi do konstruktora to akurat drobiazg jak sam wiesz. To co moim zdaniem jest problemem w takim wypadku to "zgubienie" od strony usera "przejrzystości". Czemu? Sam popatrz... Jeśli coś ustawiam domyślnie w klasie to i tak muszę to udostępnić do zmiany w konstruktorze lub kolejnej metodzie klasy. Innymi słowy mam sytuację:
a) mam takie coś jak ja używam i widzę po konstruktorze co jest wymagane, a co opcjonalne (wartości domyślne)
b) ustawiam w klasie wartości domyślne, a konstruktor i tak musi mieć tę samą listę argumentów co w a) by można było je jakoś ustawić w przypadku użycia czegoś innego niż defaultowe wartości. Tutaj nie da się zrobić "na skróty" nic, ponieważ musisz dać użytkownikowi możliwość "w jakiś sposób" i tak zmienić te wartości.
c) mamy krótki konstruktor bez parametrów domyślnych, ale musimy sami zadbać o kolejne metody zmiany tych własności, gdy trzeba użyć wartości innych niż domyślne. Innymi słowy zamiast samego konstruktora kończymy z konstruktorem i nadmiarowymi metodami do obsługi własności z ustawionym default.

Jaki z tego wniosek? Ustawianie wartości w klasie powoduje:
a) bez znajomości wnętrza klasy gubimy informację o tym co jest opcjonalne, a co nie.
b) musimy pisać nadmiarowy kod, gdyż i tak musimy dać możliwość zmiany tych parametrów na wypadek gdyby trzeba ustawić własności inaczej niż domyślnie. Albo więc kod jest identyczny jak w przypadku mojego podejścia, tylko że masz w klasie dodatkowo na sztywno już je ustawione (a nie w parametrach), albo piszesz dodatkowo nadprogramowe metody poza konstruktorem lub kombinujesz na inne sposoby jak je ustawiać.

Jak widzisz to co uważasz za "fajne" jest mniej "elastyczne" jak i kończyć się może pisaniem nadprogramowego kodu by obsługiwać sytuacje, gdy ktoś zmienia parametry domyślne. Jak widzisz, paradoksalnie to co uważasz za wygodniejsze, nie jest do końca takie idealne w ostatecznym rozrachunku. W idealnym przypadku moje i Twoje podejście to tylko wspomniane przez Ciebie "przeniesienie" nadania wartości z definicji klasy do listy parametrów, ale już to owocuje tym, co wspomniałem w podpunkcie a) i sprawia, że generując choćby API sobie, musisz dodatkowo pisać, które z parametrów są defaultowe, ponieważ tak sobie zdefiniowałeś we wnętrzu klasy. W moim podejściu masz to jak na dłoni. Jeśli projekt jest duży to niestety użycie generatora, który po prostu zrzuca nagłówki funkcji nic nie powie, a dodatkowo musisz w phpDoc czy innym generatorze dokumentacji napisać, że parametr jest domyślny z taką a taką wartością, bo generator zapewne sam tego nie wychwyci.
everth
@thek trochę masz dziwne podejście z tymi argumentami w konstruktorze - zawsze przecież można zrobić to tak:
  1. class Cos
  2. {
  3. protected $wlasciwosc = false; //tablica, obiekt, cokolwiek innego
  4. protected $wlasciwosc1 = false; // jw.
  5.  
  6. public function __construct(Profile $profile = null)
  7. {
  8. $profile = ($profile) ? $profile:Profile::get('Cosdomyslne');
  9. // kod ustawiający według profilu
  10. }
  11. }
  12.  
  13. $w1 = Cos(); // Cos skonfigurowane domyslnie
  14.  
  15. $w2 = Cos(Profile::get('Rzecz')); // według profilu rzecz
  16.  
  17. $w3 = Cos(Profile::get('Rzecz')
  18. ->setWlasciwosc('YHM, EHM')
  19. ->setWlasciwosc1(new JakisObiekt())
  20. ); // cos według zmodyfikowanego profilu rzecz

Konfigurator przenosisz po prostu w inną klasę - tam już dowolnie możesz je ustawiać. Nie sądzę by był to jakiś duży problem w wydajności takiego rozwiązania, klasa Profile może zawierać różne ustawienia dla tych samych parametrów a zapis czegoś takiego wydaje mi się bardziej intuicyjny niż setka argumentów w konstruktorze.
darko
~cykcykacz kontynuujesz temat po prawie dwóch latach? Klasa bazy danych raczej powinna być singletonem, gdyż w całej aplikacji nie ma potrzeby tworzenia za każdym razem osobnej instancji, po prostu wystarczy jeden jedyny egezmplarz. Jeśli chodzi o Waszego offtopa, to ja również korzystam ze sposobu bliższemu filozofii ~theka, chociaż nie uważam, żeby przypisywanie domyślnych wartości pól od razu było czymś złym. To, o czym tu polemizujecie, to - moim zdaniem - należy do kwestii wypracowanego stylu kodowania, a nie jakichkolwiek aspektów wydajnościowych czy logiki programowania. Zresztą można to na upartego sprawdzić.
cykcykacz
~darko faktycznie masz mnie smile.gif nawet zapomniałem o tamtym temacie. W sumie to od dwóch lat uczę się PHP. Pierwszą książką było "PHP i MySQL. Tworzenie stron WWW. Vademecum profesjonalisty". Wydanie trzecie, jednak szybko okazało się że to jednak jest troszkę mało aby dostać się do pracy jako Młodszy programista PHP, więc kupiłem sobie książkę "PHP5. Zaawansowane programowanie". Oczywiście po pierwszym przeczytaniu nie ogarniałem tematu kompletnie. Później przeczytałem tą książkę "Wzorce projektowe. Inżynieria oprogramowania" z tej książki zrozumiałem tyle, że warto stosować wzorce projektowe. A że za bardzo nie trybie jak stosować te wzorce w projektach, zacząłem uczyć się Frameworka, ponieważ mają w sobie już gotowe wzorce projektowe.Wybrałem Zend Frameworka, z czasem okazało się że jest to niezły kombajn rolleyes.gif , pewnie jak na moje umiejętności źle wybrałem ale trudno. Dalej w mojej kampanii uczenia się PHP wpadłem na pomysł aby ktoś mi dał Korepetycje i nie żałuje rolleyes.gif . Teraz właśnie mam zamiar uczyć się programowani obiektowego ponieważ wcześniej przed korepetycjami uczyłem się Zenda z internetowych tutorialii, oraz cześć z dokumentacji(tyle ile zrozumiałem). Teraz na to patrze z innej perspektywy bo wiem że źle zrobiłem ponieważ uczenie się jakiegokolwiek Frameworka do PHP bez umiejętności programowania obiektowego mija się z celem rolleyes.gif . Więc uczę się teraz programowani obiektowego.
Co trzeba umieć aby dostać się do firmy na Młodszego programiste PHP?
Umiem XHTML, CSS.
Uczę się wiadomo PHP właśnie robię taki projekt w Zend Framework, oczywiście będzie miał nowy layout jednak funkcjonalność już jest zrobiona możecie sobie poklikać jak się wam chce http://sale.sajmon.nazwa.pl/ user=php@test.pl, password=54jmon.
Druga strona jaką tworzę w zendzie to http://elementywww.pl/.
A więc co trzeba umieć aby starać się o pracę jako młodszy programista PHP?
Ps: jak przyspieszyć naukę da się jakoś? rolleyes.gif
r4xz
no na pewno aby przyśpieszyć naukę przyda się przerobić jak największą liczbę lektur (wiadomo, nie ma artykułu idealnego w którym byłoby wszystko opisane).
polecam http://www.phpro.org/tutorials/Object-Orie...g-with-PHP.html
w połączeniu z artykułem o mvc (także na tej stronie) można to zrozumieć w miarę przystępnie i na dobrym przykładzie.
darko
~cykcykacz jeśli chodzi o wymagania pracodawców na stanowisko młodszego programisty to najlepiej byłoby zorientować się samemu studiując i porównując aktualne oferty pracy. Takich portali jest wiele, z większych np. infopraca.pl, pracuj.pl czy gazeta.praca.pl Rynek zmienia się niemal z miesiąca na miesiąc, są jakieś ogólne tendencje, ale jest to a tyle dynamiczna dziedzina wiedzy, że wymagania stawiane pracownikom - przykładowo - sprzed trzech miesięcy - teraz mogą być już nieaktualne. Może to, co dalej napiszę nie będzie przyjemne, ale ja, osobiście gdybym nie był w stanie w ciągu około dwóch lat opanować jakiegoś wiodącego na rynku rozwiązania (frameworka) w stopniu umożliwiającym w miarę swobodne poruszanie się w nim oraz poprawne implementowanie przynajmniej podstawowej funkcjonalności (mam na myśli operacje CRUD + realizacja standardowych zadań od pracodawcy) zgodnej z architekturą frameworka, to po prostu zastanowiłbym się czy to jest obszar działalności twórczej, w której mogę się sprawdzić. Mówiąc bez ogródek: zastanawiałbym się czy nadaję się na programistę. To jest niestety (albo i stety) jeden z zawodów, obok prawnika czy lekarza, który wymaga ciągłego rozwoju i nauki w tempie przynajmniej pozwalającym śledzić aktualne trendy na rynku, który jest maga-dynamiczny. Rozwiązania sprzed kilku miesięcy są już przestarzałe. Trzeba dużo czytać, śledzić różnego rodzaju nowinki, nie zamykać się w tylko jednym języku programowania, po prostu trzeba być z tymi zmianami na bieżąco jeśli myśli się poważnie o swojej przyszłości jako programista.
Odnośnie "przyśpieszenia nauki", to mogę jedynie podzielić się swoimi doświadczeniami. Uważam, że ucząc się programowania obiektowego trzeba mieć zawsze świadomość faktu, że pisząc kod obiektowy próbujemy naśladować rzeczywistość, która nas otacza. Na tym polega programowanie obiektowe (pomijając pewien stopień abstrakcji, z jakim mamy do czynienia przekładając rzeczywistość na taki czy inny język programowania). I z tą myślą w głowie jest dużo łatwiej zachować właściwy logiczny porządek (hierarchia obiektów jak najbliżej rzeczywistości). Moje początki, zanim jeszcze powstała jakakolwiek linijka kodu, wyglądały tak, że najpierw powstawał pewien szkic, który modelował jeden wielki problem do rozwiązania na poszczególne małe podproblemy, następnie każdy z tych podproblemów dzieliłem na ileś tam klas, z których każda miała pewną określoną rolę i stanowiła w miarę, jak to tylko było możliwe - niezależny byt. W ten sposób powstawał mój plan działania. Na końcu siadałem do właściwej części - czyli pisania kodu z planem w ręku. Pozwoliło mi takie podejście oszczędzić mnóstwo czasu, a moje projekty z czasem stawały się zbiorem całkiem niezłej "narzędziówki", z której korzystam jeszcze do tej pory i wiele razy uratowała mi projekt smile.gif (no może niedosłownie, ale oszczędziłem bardzo dużo czasu). Wartością dodaną takiego podejścia było to, że dzięki takiemu sposobowi programowania wyrobiłem sobie nawyk planowania i analizowania problemów, które mój kod ma rozwiązywać, dodatkowo studiując którąś już z kolei książkę o wzorcach zauważyłem, że praktycznie większość z nich używałem do tej pory nie zdając sobie tego sprawy. Dzięki nauce wzorców udało mi się tylko tę całą wiedzę uporządkować i poznać jeszcze kilka ciekawych rozwiązań znanych mi wcześniej problemów. Tak czy siak szczerze życzę powodzenia w dalszej edukacji i sukcesów zawodowych.
cykcykacz
~darko
Cytat
Może to, co dalej napiszę nie będzie przyjemne, ale ja, osobiście gdybym nie był w stanie w ciągu około dwóch lat opanować jakiegoś wiodącego na rynku rozwiązania (frameworka) w stopniu umożliwiającym w miarę swobodne poruszanie się w nim oraz poprawne implementowanie przynajmniej podstawowej funkcjonalności (mam na myśli operacje CRUD + realizacja standardowych zadań od pracodawcy) zgodnej z architekturą frameworka, to po prostu zastanowiłbym się czy to jest obszar działalności twórczej, w której mogę się sprawdzić. Mówiąc bez ogródek: zastanawiałbym się czy nadaję się na programistę.

Frameworka Zend uczę się tak na poważnie od 5 mieśięcy wydaje mi się że umiem CRUD.
Cytat
Moje początki, zanim jeszcze powstała jakakolwiek linijka kodu, wyglądały tak, że najpierw powstawał pewien szkic, który modelował jeden wielki problem do rozwiązania na poszczególne małe podproblemy,

Robię podobnie zawsze sobie coś na kartce w zeszycie rozrysuje i obmyślę.

Od nie dawna zacząłem zapisywać sobie rzeczy, których uczę się tworząc projekty aby później je wykorzystać.
Mam świadomość, że jest to dziedzina która rozwija się bardzo szybko i trzeba cały czas się rozwijać uczyć nowych rzeczy jak np:prawnik.
Jest to dość ciężki tak naprawdę kawałek chleba.

Czy się nadaję czy się nie nadaję to się okaże jak zacznę szukać pracy.
Chcę się tylko do tego dobrze przygotować, z tego co się dowiedziałem od was to trzeba umieć:

1) programowanie obiektowe rolleyes.gif
2) korzystać dobrze z któregoś z frameworków(w zależności co pracodawca wymaga) rolleyes.gif
3) korzystać z jQuery rolleyes.gif
4) znać SQL dobrze rolleyes.gif
5) mieć swoje konkretne projekty

Myślę że jak się spełni te wymagania pracodawca da szansę...

A tak z ciekawości ~darko ile zajęło ci nauczenie się PHP jakiegoś Frameworka, javascriptu, SQL?
darko
Php uczyłem się 4 miesiące znając już języki: c, c++ i javę, więc było mi znacznie łatwiej niż miałbym uczyć się od podstaw. Wtedy wydawało mi się, że już się nauczyłem php. Wydawało mi się. Tak na prawdę php uczę się cały czas i dalej są rzeczy, których nie umiem zrobić i nie znam wszystkich funkcji na pamięć, ale po to jest dokumentacja, książki i forum, jak to, żeby zgłębiać Snorkle.gif temat, a nikt nie każe Ci znać wszystkiego na pamięć, ważne żebyś rozumiał swój i czyjś kod, a jak czegoś nie będziesz wiedział - ważne jest żebyś umiał to znaleźć i się tego czegoś nauczyć. Javascriptu uczyłem się już dawno, chodząc jeszcze do liceum i z perspektywy czasu już nie pamiętam ile trwała moja nauka, w każdym razie nauczyłem się go na tyle, żeby jak czegoś nie wiem tylko poszukać, a wiem gdzie szukać medieval.gif Zenda uczę się od ponad dwóch lat, w tym momencie od dwóch miesięcy w postaci Magento i przyznam, że nie jest łatwo, ale warto to poznać. SQLa znam najsłabiej ale na tyle, żeby radzić sobie z zapytaniami złożonymi z kilkunastu joinów i na razie mi to wystarczy. Bardziej poznaję inne technologie związane z rynkiem sklepowym np. silniki wyszukiwania jak javowy Apacje Solr czy napisany w C++ Sphinx itd. Muszę Ci jeszcze powiedzieć, że takie podawanie czasu, kto ile się uczył trochę mija się z celem, bo każdy ma swoje tempo, a należy pamiętać, że sama teoria bez praktyki nic nie daje. W sumie w tym momencie nie bardzo mam czas na naukę, chociaż staram się tak nim gospodarować, żeby znaleźć przynajmniej 2 godziny tygodniowo na poznawanie nowych rzeczy. Ważne żebyś myślał nad stosowanymi rozwiązaniami, cały czas dążył do ich ulepszania, uczył się dużo, analizował i wyciągał wnioski i najważniejsze - żebyś był otwarty na inne pomysły i inne rozwiązania. To daje moc biggrin.gif
cykcykacz
To ja dalej zasiadam do nauki PHP i nie tylko smile.gif
Dzięki za odpowiedzi wszystkim w tym temacie.
Pozdrawiam.
Crozin
@thek: Uczepiłeś się jednego konkretnego przypadku użycia... wink.gif Dla przypomnienia podstawa naszej dyskusji:
  1. // Pozwoliłem sobie na Java'owy przykład by pokazać coś realnego (PHP uniemożliwia podanie jako wartość przykładowo obiektów).
  2. // Nie mniej jednak w PHP sprawa ma się tak samo.
  3.  
  4. public class SomeClass {
  5. private List<AnotherClass> list = new LinkedList<AnotherClass>();
  6. private boolean enabled = true;
  7.  
  8. public SomeClass() {
  9. // Jakiś kod
  10. }
  11.  
  12. // Jakiś kod
  13. }
  14.  
  15. // VS
  16.  
  17. public class SomeClass {
  18. private List<AnotherClass> list;
  19. private boolean enabled;
  20.  
  21. public SomeClass() {
  22. list = new LinkedList<AnotherClass>();
  23. enabled = true;
  24.  
  25. // Jakiś kod
  26. }
  27.  
  28. // Jakiś kod
  29. }
Żeby ukrucić bezsensowną dyskusję o argumentach konstuktora i domniemanym dodadkowym kodzie (notabene w praktyce by go nie było) obie właściwości służą wyłącznie jakiemuś bliżej nieokreślonemu użytkowi obiektu.

Uznałeś, że pierwszy przykład - faworyzowany przeze mnie - narusza jakieś paradygmaty obiektówi, że jest nienaturalny. Nie będę bronić pierwszego przykładu, ani atakować drugiego. Chciałbym tylko dowiedzieć się co konkretnie może wynikać z różnic w tych zapisach. Jakie paradygmaty mogą tutaj, w tym konkretnym przypadku (jeżeli będziesz omawiać inny proszę dołącz kod).

Bo póki co to mamy ładnych kilka ścian tekstu, w których co prawda jest nieco racji, ale opeirają się one na innych przypadkach użycia, co sprawia że są za przeproszeniem gówno warte. wink.gif

-----------------------------------------

@darko: Obiekt odpowiedzialny za komunikację baza danych <-> PHP w żadnym wypadku nie powinien być singletonem, bo raz że wcale nie musi być jednego połączenia, dwa że tworzy to niebezpieczeństwo w postaci gobalnego obiektu - a przestrzeń globalna to przestrzeń zła. W ogóle to w aplikacjach WWW działających tak jak działa PHP nie ma zbyt wiele miejsca dla singletona.
darko
~Crozin zgadza się, że przestrzeń globalna jest zła i nie należy z niej korzystać, jednak sam przyznasz, że w niemal wszystkich popularnych frameworkach obiekt dostarczający funkcjonalności obsługi bazy danych jest właśnie singletonem a frameworki nie udostępniają możliwości tworzenia kilku połączeń do tej samej bazy jednocześnie.
Uznałem, że to
Cytat
-----------------------------------------

odcięło mnie od Waszej dyskusji z thekiem medieval.gif
Jedyną wadą podejścia pierwszego jest to, że jakoś tak bardziej intuicyjne jest nadpisanie konstruktora rodzica i zainicjalizowanie wartości pól innym typem danych niż najpierw wywołanie konstruktora rodzica, a następnie ustawienie nowej wartości dla pola, które chcemy, żeby miało przypisany inny typ danych. Mam na myśli sytuację, w której pola dziedziczymy (nie jak tutaj są prywatne) i chcemy zmienić typ przypisywanych do pola danych np. z LinkedList na np. ArrayList. Ale to wszystko to znowu kosmetyka nic nie znacząca w sumie. Tak czy siak moim skromnym zdaniem nie ma żadnej różnicy pomiędzy bezpośrednią definicją, a przypisaniem w konstruktorze, poza tym jednak, że jeśli mamy dużo pól do takiego ustawienia, to tworzy nam się konstruktor z bardzo, baaaardzo długą listą argumentów domyślnych.
everth
Paradygmat pewnie żaden, ale czy kosmetyka? Jeśli klasa bazowa używa powiedzmy kilkudziesięciu właściwości (albo i więcej) domyślnie inicjowanych a klasa potomna z jakichś powodów tylko kilku to mamy problem - bo albo musimy wszystkie nadpisać, albo uznać że narzut jest pomijalny - ale jeśli taki obiekt jest tworzony kilkaset (albo i kilka tys.) razy w czasie wykonania to narzut może być zauważalny, pomijając fakt że to marnotrawstwo. Przykład (dość abstrakcyjny).

W Javie pewnie i tak nie ma różnicy bo HotSpot jest trochę bardziej wysublimowany niż to co mamy w PHP i takie przykłady jak Crozina czy mój powyższy zostałyby pewnie zoptymalizowane i wykonywałyby się tak samo bez znaczenia na miejsce inicjowania.
thek
@Crozin: Nie wiem czy zauważyłeś, ale to o czym ja piszę jest jeszcze nne niż to co podałeś w obu przypadkach w swoim ostatnim poście i co chcesz bym porównał. To o czym ja piszę to pewna odmiana tego, co podałeś w 2 wersji. To co podałeś jako pierwsze to ustawienie na sztywno podczas definicji, drugie to ustawienie na sztywno w konstruktorze, a ja mówię o jeszcze nieco innym podejściu - atrybuty klasy inicjalizowane parametrami konstruktora, czyli gdyby Twój przykład wykorzystać to konstruktor w podejściu o którym mówię byłby mniej więcej postaci:
  1. public SomeClass( (string) $NazwaKlasy, (bool) $state = true ) {
  2. $list = new SplDoublyLinkedList(); //w zasadzie php tego nie ma (brak typowania silnego), ale tu powinno być coś jak: new ($NazwaKlasy) SplDoublyLinkedList()
  3. $enabled = $state;
  4. // Jakiś kod
  5. }
Zauważ, że w tym podejściu klasa na starcie jest goła i nic nie wie, jest pusta. Sam konstruktor też nie ustawia sam z siebie niczego na sztywno. Wszystko jest do niego przez parametry przekazywane podczas inicjalizacji. Sam w sobie ma jedynie informację, że jeśli czegoś nie ma, to ma się posłużyć wartością domyślną, ale nie jest to dla niego nic ponad reakcję na sytuację przewidywaną. Pokaż gdzie w Twoim przykładzie masz możliwość nadpisania wartości domyślnej inną? Zauważ, że to nie istnieje. Wszystko jest u Ciebie na pałę ustawiane, tak jakby nie było możliwości ustawienia inaczej niż tak jak zamyśliłeś sobie. Zrzuciłeś wszystko na programistę by się tym zajął, a klasa nie ma żadnej elastyczności. Aby było to funkcjonalne, musiałbyś napisać kolejny konstruktor lub większą ich ilość, tym razem obejmujące możliwe wystąpienie wartości innych niż domyślne lub napisać metody ustawiające atrybuty zanim przystąpiłbyś do faktycznej pracy z obiektem. Widzisz teraz w którym miejscu ja widzę problem? Na ten moment przykład jaki podałeś jest mało użyteczny i ograniczony. Brakuje Ci kodu do obsługi tego przypadku. To o co mi chodzi zauważył everth: obiekt oraz klasa są gołe i wesołe do czasu ruszenia konstruktora, który zawsze korzysta z tego co mu dają i reaguje jedynie nadawaniem wartości domyślnych gdy nie znajduje atrybutu wśród parametrów. Nie ustawia sobie z powietrza niczego wcześniej i nie zmienia później. Gdybym się miał już uprzeć na coś co ma ograniczoną listę a działa w sposób jaki powinno to byłoby to coś w stylu jaki zaprezentował everth z Profile i IFem na poziomie konstruktora, sprawdzającym wystąpienie. Logiczniejsze i moim zdaniem bardziej eleganckie.

@everth: to jest właśnie idea tego o co mi chodzi. Nie mówię, że trzeba każdą rzecz walić osobno jako parametr, ale chodzi mi o miejsce przypisania i sposób. Crozin ustawia albo na sztywno w definicji klasy albo na sztywno w konstruktorze. Tym samym pozbawia się możliwości wprowadzenia tam czegokolwiek innego niż wartość domyślna (zauważ, że niemal nigdzie nie daje konstruktorowi parametrów, które by to mogły zrobić) lub wprowadza dodatkowe, niepotrzebne przypisania (najpierw konstruktor ustawia to co ma w definicji klasy lub swojej na pałę, a potem ewentualnie zmieniłby jeśli parametr wystąpiłby ).
Crozin
@darko: Nie wiem z jakich Ty to FW korzystasz, ale każdy z jakim miałem do czynienia umożliwiał tworzenie wielokrotnych połączeń do tej samej bazy danych. I nie, nie spotakłem się z tym by połączenie było singletonem.

@everth: Pomijając fakt, że do czegoś takiego raczej nie powinno dochodzić to:
1. Trzeba znać umiar we wszystkim, a metody dobierać do sytuacji.
2. Nadpisanie w klasie potomnej wiele nie zmieni bo przy tworzeniu obiektu wartości w kasie narzędnej i tak muszą zostać zainicjalizowane.

@thek: Ehhh... nadal się nie rozumiemy. wink.gif Twój post od którego zaczęła się cała ta dyskusja: http://forum.php.pl/index.php?showtopic=17...mp;#entry856988
Nie chodzi o przypadek, gdzie jakieś dane mogą być konfigurowane z zewnątrz czy coś takiego. Bo jest to zupełnie co innego, inna sytuacja, a więc i użycie innych metod.
thek
Widać sam nie zauważyłem, że w czasie pisania skróciłem za bardzo. Myślałem w owym poście o:
  1. <?php
  2. class Jakas_tam {
  3. private $property;
  4.  
  5. public function __construct( $val = 45 ) {
  6. $this->property = $val;
  7. }
  8. }
. Mae culpa i przepraszam Crozin za napisanie czegoś innego niż miałem na myśli, a tym samym wprowadzenie Cię w błąd. Mam nadzieję, że teraz podany kod już w 200% pokaże o co mi chodzi z tym "każdy goły i wesoły".
everth
@thek
Ciekawy art na temat umieszczania argumentów w konstruktorach. W każdym razie autorzy uważają że czytelniej jest ustawiać parametry poprzez odpowiednie metody niż poprzez argumenty konstruktora.
darko
Cytat(Crozin @ 26.04.2011, 13:26:48 ) *
@darko: Nie wiem z jakich Ty to FW korzystasz, ale każdy z jakim miałem do czynienia umożliwiał tworzenie wielokrotnych połączeń do tej samej bazy danych. I nie, nie spotakłem się z tym by połączenie było singletonem.

Eh nie zrozumieliśmy się, a i ja też się mocno zagalopowałem w poprzednim poście. Miałem na myśli to, że obiekt bazy danych przechowywany jest w rejestrze czyli w przestrzeni globalnej aplikacji, do której mamy dostęp z każdego miejsca.
thek
@everth: faktycznie fajny, ale szkoda, że na wąskiej grupie. Na dodatek skupionej wokół określonych technologii, przez co można wyciągnąć wniosek, że ich podejście było kształtowane w podobny sposób, z użycie tych samych narzędzi i tym samym robili to w sposób wynikający z przyzwyczajenia. Ja swoje nawyki mam wynikające z C i C++ oraz jego wizji obiektówki i to się za mną ciągnie, o czym doskonale wiem. Ogólnie podoba mi się to w jaki sposób zadania im dano i wnioski tyczące samej analizy kodu oraz jego powstawania.
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.