Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

3 Stron V   1 2 3 >  
Reply to this topicStart new topic
> [PHP]OOP Ucze się... konstruktor
cykcykacz
post 20.04.2011, 18:44:30
Post #1





Grupa: Zarejestrowani
Postów: 550
Pomógł: 9
Dołączył: 29.05.2009
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


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ł'
?>
Go to the top of the page
+Quote Post
mat-bi
post 20.04.2011, 19:13:59
Post #2





Grupa: Zarejestrowani
Postów: 690
Pomógł: 92
Dołączył: 6.02.2011

Ostrzeżenie: (0%)
-----


Ludzie...

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

Naucz się podstaw, potem poagadamy
Go to the top of the page
+Quote Post
cykcykacz
post 20.04.2011, 19:39:27
Post #3





Grupa: Zarejestrowani
Postów: 550
Pomógł: 9
Dołączył: 29.05.2009
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
thek
post 20.04.2011, 20:07:51
Post #4





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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. }


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
Crozin
post 20.04.2011, 20:47:55
Post #5





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@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.
Go to the top of the page
+Quote Post
cykcykacz
post 20.04.2011, 21:23:32
Post #6





Grupa: Zarejestrowani
Postów: 550
Pomógł: 9
Dołączył: 29.05.2009
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
everth
post 20.04.2011, 22:07:21
Post #7





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

Ostrzeżenie: (0%)
-----


@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.


--------------------
Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]!
Go to the top of the page
+Quote Post
thek
post 21.04.2011, 09:43:35
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
Crozin
post 21.04.2011, 10:15:43
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@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.
Go to the top of the page
+Quote Post
cykcykacz
post 21.04.2011, 19:13:02
Post #10





Grupa: Zarejestrowani
Postów: 550
Pomógł: 9
Dołączył: 29.05.2009
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


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ć.

Ten post edytował cykcykacz 21.04.2011, 19:13:46
Go to the top of the page
+Quote Post
mat-bi
post 21.04.2011, 19:20:02
Post #11





Grupa: Zarejestrowani
Postów: 690
Pomógł: 92
Dołączył: 6.02.2011

Ostrzeżenie: (0%)
-----


W konstruktorze nie robimy zwykle takich rzeczy jak mysql_query, mysql_fetch_assoc etc., przerzuca się to do innych funkcji w klasie

Ten post edytował mat-bi 21.04.2011, 19:21:55
Go to the top of the page
+Quote Post
thek
post 21.04.2011, 21:55:17
Post #12





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
everth
post 21.04.2011, 22:15:33
Post #13





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

Ostrzeżenie: (0%)
-----


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)


--------------------
Już mi się ani wiedzieć, ani tym bardziej myśleć nie chce.
[Think different]!
Go to the top of the page
+Quote Post
Crozin
post 21.04.2011, 22:49:35
Post #14





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@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.
Go to the top of the page
+Quote Post
thek
post 22.04.2011, 01:44:36
Post #15





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
Crozin
post 22.04.2011, 10:52:30
Post #16





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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. }
Go to the top of the page
+Quote Post
thek
post 22.04.2011, 11:47:46
Post #17





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




[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.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
Crozin
post 22.04.2011, 12:38:25
Post #18





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
thek
post 22.04.2011, 17:08:53
Post #19





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




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


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
Crozin
post 22.04.2011, 17:33:02
Post #20





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post

3 Stron V   1 2 3 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 7.06.2025 - 17:43