Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php Kanał ATOM (tag: php)

Autor wpisu: Łukasz Socha, dodany: 13.08.2012 09:54, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Budowniczy jest wzorcem, gdzie proces tworzenia obiektu podzielony jest na kilka mniejszych etapów, a każdy z nich może być implementowany na wiele sposobów. Dzięki takiemu rozwiązaniu możliwe jest tworzenie różnych reprezentacji obiektów w tym samym procesie konstrukcyjnym.

Diagram klas wzorca Builder

Standardowo wzorzec składa się z dwóch podstawowych elementów. Pierwszy z nich oznaczony jest jako Builder – jego celem jest dostarczenie interfejsu do tworzenia obiektów nazywanych produktami (product). Drugim elementem jest obiekt oznaczony jako ConcreteBuilder, a jego celem jest tworzenie konkretnych reprezentacji produktów przy pomocy zaimplementowanego interfejsu Builder. W ConcreteBuilder zawarte są procedury odpowiedzialne za konstrukcje i inicjalizację obiektu. Strukturę wzorca uzupełnia obiekt Director (zwany także czasem kierownikiem, nadzorcą – tak jak na budowie ;) ), który zleca konstrukcję produktów poprzez obiekt Builder dbając o to, aby proces budowy przebiegał w odpowiedniej kolejności.

Diagram sekwencji wzorca Builder

Przykładowa implementacja

<?php

class Product {

    private $part1;
    private $part2;

    public function setPart1($part1) {
        $this->part1 = $part1;
    }
    public function getPart1() {
        return $this->part1;
    }
    public function setPart2($part2) {
        $this->part2 = $part2;
    }
    public function getPart2() {
        return $this->part2;
    }

}

interface Builder {
    public function buildPart1();
    public function buildPart2();
}

class ConcreteBuilder implements Builder {
    private $product;

    public function __construct() {
        $this->product = new Product();
    }
    public function buildPart1() {
        $this->product->setPart1("1. faza budowy");
    }
    public function buildPart2() {
        $this->product->setPart2("2. faza budowy");
    }
    public function getProduct() {
        return $this->product;
    }

}

class Director{
    private $builder;
    
    public function __construct() {
        $this->builder = new ConcreteBuilder();
    }
    public function construct() {
        $this->builder->buildPart1();
        $this->builder->buildPart2();
    }
    public function getResult() {
        return $this->builder->getProduct();
    }
}

// testy
$director = new Director();
$director->construct();
$product = $director->getResult();
echo $product->getPart1(); // wyswetli "1. faza budowy"
echo $product->getPart2(); // wyswieli "2. faza budowy"

?>

Przykład z życia wzięty

Tworząc serwis udostępniający filmy wideo chcemy mieć możliwość wyboru technologii do generowania odtwarzacza wideo. Możemy użyć do tego budowniczych.

<?php 
class Player {
    private $player;
    
    public function setplayer($player) {
        $this->player = $player;
    }
    public function render() {
        return $this->player;
    }
}

interface Builder {
    public function buildPlayer();
    public function getPlayer();
}

class FlashBuilder implements Builder {
    private $player;

    public function __construct() {
        $this->player = new Player();
    }
    public function buildPlayer() {
        $this->player->setPlayer("Player w Flash");
    }
    public function getPlayer() {
        return $this->player;
    }
}

class HTMLBuilder implements Builder {
    private $player;

    public function __construct() {
        $this->player = new Player();
    }
    public function buildPlayer() {
        $this->player->setPlayer("Player w HTML5");
    }
    public function getPlayer() {
        return $this->player;
    }
}

class Director{
    private $builder;
    
    public function __construct(Builder $builder) {
        $this->builder = $builder;
    }
    public function construct() {
        $this->builder->buildPlayer();
    }
    public function getResult() {
        return $this->builder->getPlayer();
    }
}

// testy
$html = new HTMLBuilder();
$flash = new FlashBuilder();
$director = new Director($flash);
$director->construct();
$player = $director->getResult();
echo $player->render(); // wyswietli "player w flash"

$director2 = new Director($html);
$director2->construct();
$player2 = $director2->getResult();
echo $player2->render(); // wyswietli "player w HTML5"

?>

Dwaj budowniczy FlashBuilder i HTMLBuilder mają za zadanie stworzyć obiekt Video z uwzględnieniem wykorzystanej technologii. Z kolei Director „pilnuje” poprawnej kolejności wywoływania metod. Dzięki wykorzystaniu Dependency Injection możemy łatwo dodawać kolejnych budowniczych.

Zalety i wady

Zalety:

  • Duża możliwość zróżnicowania wewnętrznych struktur klas.
  • Duża skalowalność (dodawanie nowych reprezentacji obiektów jest uproszczone).
  • Większa możliwość kontrolowania tego, w jaki sposób tworzony jest obiekt (proces konstrukcyjny jest niezależny od elementów, z których składa się tworzony obiekt.

Wady:

  • Duża liczba obiektów reprezentujących konkretne produkty.
  • Nieumiejętne używanie wzorca może spowodować nieczytelność kodu (jeden produkt może być tworzony przez zbyt wielu budowniczych).

Zastosowanie

Wzorzec budowniczego stosowany jest do oddzielenia sposobu tworzenia obiektów od tego jak te obiekty mają wyglądać. Przykładem jest oprogramowanie konwertujące tekst z jednego formatu na drugi. Algorytm odczytujący i interpretujący dane wejściowe jest oddzielony od algorytmu tworzącego dane wyjściowe. Dzięki takiemu rozwiązaniu możliwe jest zastosowanie jednego obiektu odczytującego dane wejściowe oraz wielu obiektów konwertujących odczytane dane do różnych formatów (ASCII, HTML, RTF, itp.), co zwiększa skalowalność rozwiązania.

Innym zastosowaniem może być stworzenie narzędzia, które będzie miało różną implementację zależnie od użytej technologii – tak jak w omawianym przykładzie odtwarzacz wideo.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Śpiechu, dodany: 11.08.2012 13:48, tagi: php

Od jakiegoś miesiąca definitywnie przesiadłem się na PHP 5.4. Napiszę dzisiaj o kilku ciekawostkach i nowych funkcjach, które ułatwią nam programistyczne życie (mówię „nam” z tej okazji, że od 1 sierpnia zmieniłem pracę i jestem oficjalnie zawodowym programistą :-) Zacznę jednak od nie do końca zrozumiałego skróconego operatora trójargumentowego dostępnego od wersji 5.3.

Wszyscy na pewno znacie typowy operator trójargumentowy (ang. ternary operator): (warunek) ? (gdy prawda) : (gdy fałsz). Nie wszyscy jednak korzystają z uproszczonej wersji (ang. shorthand TO): (warunek) ?: (gdy fałsz). Jest to rzecz często spotykana w kodzie źródłowym Symfony 2.

Zazwyczaj spotykamy taką konstrukcję:

$var = true;
$var = $var === true ? 'true' : 'false';
// wynik to oczywiscie 'true'

Co jeżeli chcemy skorzystać z uproszczonej wersji?

// jesli $var ma wartosc false, '', null, []
// to wynikiem nastepnej operacji bedzie 'default value'
$var = $var ?: 'default value';

Jest to przydatna konstrukcja jeśli chcemy mieć pewność, że zmienna ma zawsze jakąś ustaloną wartość. Chroni nas to przed setkami instrukcji sprawdzających czy mamy jakieś nulle, falsy i puste stringi :-)

Wywoływanie metod bezpośrednio po instrukcji new ma częste zastosowanie np. wtedy, gdy właściwie nie potrzebujemy samej instancji obiektu, a tylko wynik konkretnej metody. Przykład:

(new DateTime())->format('Y-m-d');

W jednej linijce załatwiamy sprawę. Warunek to otoczenie new nawiasami okrągłymi.

Kolejna nowa możliwość 5.4 to bezpośrednie dobranie się do rezultatu działania funkcji zwracającej tablicę. Przypuśćmy, że nie interesuje nas wynik działania funkcji, a tylko fakt czy pojawił się jakiś błąd, np.

function foo() {
return ['result' => 'some result',
        'error'  => 'some nasty error'];
}
echo foo()['error'];
// wynik to 'some nasty error'

Wg mnie ta konstrukcja potencjalnie zaciemnia zrozumienie działania kodu, gdyż może nam umknąć, że wynik funkcji został „przycięty” do jednego klucza. Poza tym może sugerować, że funkcja jest źle zaprojektowana skoro często odwołujemy się tylko do części jej „produktu”.

Od 5.4 możemy wymusić typ callable argumentu przekazywanego do funkcji. Dodatkowo zademonstruję kilka sposobów wywoływania:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: bastard13, dodany: 10.08.2012 14:12, tagi: php, design, oop

wstęp

Abstrahując od tego, na co pozwala nam dany język programowania (np. PHP pozwala niestety na wszystko), to czy w interfejsie jest sens posiadać deklarację konstruktora? A co w przypadku klas abstrakcyjnych? Jak sądzicie, taka funkcjonalność może się przydać, czy raczej jest to coś zbędnego, czego najprawdopodobniej nigdy byście nie wykorzystali? Czytaj więcej »

Autor wpisu: Łukasz Socha, dodany: 05.08.2012 21:59, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Wzorzec adapter (znany także pod nazwą wrapper) służy do przystosowania interfejsów obiektowych, tak aby możliwa była współpraca obiektów o niezgodnych interfejsach. Szczególnie przydaje się przypadku wykorzystania gotowych bibliotek o interfejsach niezgodnych ze stosowanymi w aplikacji. W świecie rzeczywistym adapter to przejściówka, np. przejściówka do wtyczki gniazdka angielskiego na polskie.

Diagram klas wzorca Adapter

Struktura wzorca składa się z elementów takich jak: Target, Adaptee, Adapter oraz Client. Target jest abstrakcją (zazwyczaj interfejsem), jakiej oczekuje klient. Elementem dostarczającym żądanej przez klienta funkcjonalności jest Adaptee (np. zewnętrzną biblioteką). Rolą adaptera, który implementuje interfejs Target, jest „przetłumaczenie” wywołania metod należących do interfejsu Target poprzez wykonanie innych, specyficznych metod z klasy Adaptee.

Przykładowa implementacja

<?php 
interface Target {
    public function  methodA();
}
class Adaptee {
    public function methodB() {
        echo "Metoda B";
    }
}
class Adapter implements Target {
    public function methodA() {
        $adaptee = new Adaptee();
        $adaptee->methodB();
    }
}

//test
$client = new Adapter();
$client->methodA(); // wyswietli "metoda B"
?>

Przykład z życia wzięty

Przejmujemy administrację nad jakimś większym projektem i istnieje potrzeba wymiany starej biblioteki XML na nową. Oczywiście nazwy metod różnią się diametralnie. Zamiast poprawiać nazwy metod w całym projekcie możemy napisać adapter.

<?php 
interface OldXML {
    public function  writeXml();
}
class NewXML {
    public function xml() {
        echo "Kod XML";
    }
}
class XML implements OldXML {
    public function writeXml() {
        $adaptee = new NewXML();
        $adaptee->xml();
    }
}

//test
$client = new XML();
$client->writeXml(); // wyswietli "Kod XML"
?>

Interfejs OldXML zawiera zestaw metod starej biblioteki. NewXML jest klasą nowej biblioteki. Natomiasr klasa XML jest swoistą przejściówką pomiędzy dwoma wersjami klas.

Zastosowanie

Wzorzec adaptera stosowany jest najczęściej w przypadku, gdy wykorzystanie istniejącej klasy jest niemożliwe ze względu na jej niekompatybilny interfejs. Drugim powodem użycia może być chęć stworzenia klasy, która będzie współpracowała z klasami o nieokreślonych interfejsach.

Powiązane tematy

Autor wpisu: Łukasz Socha, dodany: 24.07.2012 21:19, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Wzorzec metody wytwórczej dostarcza abstrakcji do tworzenia obiektów nieokreślonych, ale powiązanych typów. Umożliwia także dziedziczącym klasom decydowanie jakiego typu ma to być obiekt.

Diagram klas wzorca Factory method

Wzorzec składa się z dwóch ról: produktu Product definiującego typ zasobów oraz kreatora Creator definiującego sposób ich tworzenia. Wszystkie typy produktów (ConreteProduct1, ConreteProduct2 itp.) muszą implementować interfejs Product. Z kolei ConcreteCrator dostarcza mechanizm umożliwiający stworzenie obiektu produktu danego typu.

Przykładowa implementacja

<?php

// Produkty
interface Product{
    public function getName();
}
class ConceteProduct1 implements Product{
    public function getName() {
        return "Produkt 1";
    }
}
class ConceteProduct2 implements Product{
    public function getName() {
        return "Produkt 2";
    }
}

// Kreator tworzacy obiekt produktu
interface Creator{
    public function create($type);
}
class ConcreteCreator implements Creator{
    public function create($type) {
        switch($type) {
            case 'Product 1':
                return new ConceteProduct1();
                break;
            case 'Product 2':
                return new ConceteProduct2();
                break;
        }
    }
}

// testy
$creator = new ConcreteCreator();
$prod1 = $creator->create("Product 1");
$prod2 = $creator->create("Product 2");
echo $prod1->getName(); // wyswietli "Produkt 1"
echo $prod2->getName(); // wyswietli "Produkt 2"

?>

Przykład z życia wzięty

Tworzymy system zamówień dla pizzerii. W ofercie są różne typy pizz. Podstawowym pytaniem jest: jak stworzyć wydajny mechanizm do tworzenia obiektów różnych rodzai pizz? Posłużmy się metodą wytwórczą…

<?php

// Produkty
interface Pizza{
    public function getName();
}
class HawaiianPizza implements Pizza{
    public function getName() {
        return "Hawalian pizza";
    }
}
class DeluxePizza implements Pizza{
    public function getName() {
        return "Deluxe pizza";
    }
}

// Kreator tworzacy obiekt produktu
interface Creator{
    public function create($type);
}
class ConcreteCreator implements Creator{
    public function create($type) {
        switch($type) {
            case 'Hawalian':
                return new HawaiianPizza();
                break;
            case 'Deluxe':
                return new DeluxePizza();
                break;
        }
    }
}

// testy
$creator = new ConcreteCreator();
$prod1 = $creator->create("Hawalian");
$prod2 = $creator->create("Deluxe");
echo $prod1->getName(); // wyswietli "Hawalian pizza"
echo $prod2->getName(); // wyswietli "Deluxe pizza"

?>

Dzięki zastosowaniu factory method możemy w łatwy sposób dołączać kolejne pizze. Zamiast używania konstrukcji switch (korzystam z tego, gdyż nie chcę komplikować przykładu) warto byłoby stworzyć bardziej abstrakcyjny mechanizm.

Zalety i wady

Zalety:

  • Niezależność od konkretnych implementacji zasobów oraz procesu ich tworzenia.
  • Wzorzec hermetyzuje proces tworzenia obiektów, zamykając go za ściśle zdefiniowanym interfejsem./li>
  • Spójność produktów – w sytuacji, gdy pożądane jest, aby klasy produkty były z określonej rodziny.

Wady:

  • Nie znam…

Zastosowanie

Wzorzec metody wytwórczej można wykorzystać między innymi przy tworzeniu systemów zamówień, gdzie oferta może się zmieniać, ale składa z jednakowego typu produktów.

Innym zastosowaniem może być system pluginów. Dzięki zastosowaniu metody wytwórczej możemy łatwo rozbudowywać nasz skrypt o kolejne funkcjonalności (np. o obsługę kolejnych formatów plików).

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: bastard13, dodany: 20.07.2012 14:55, tagi: oop, php

krótki wstęp, a w nim o tym, czym jest interfejs

Do czego wykorzystuje się interfejsy? Do zapewnienia, że obiekty danej klasy będą posiadały określone metody. Po co chcemy mieć tą pewność? Ponieważ w danym miejscu ich posiadanie jest niezbędne do bezbłędnego wykonania pewnych instrukcji. Dlaczego wszystkie metody interfejsu są abstrakcyjne? Gdyż nie wymagamy określonego ich działania, wymagamy jedynie ich istnienia. Czytaj więcej »

Autor wpisu: Vokiel, dodany: 19.07.2012 19:50, tagi: php

phpcon2012-logo Rusza kolejna (trzecia) edycja ogólnopolskiej konferencji entuzjastów PHP. Tak samo jak w przypadku poprzednich edycji, organizatorem jest zarząd stowarzyszenia Polska Grupa Użytkowników Linuxa (PLUG). Spotkanie odbędzie się w ostatni weekend września – w hotelu „Przedwiośnie”, w Mąchocicach Kapitulnych (kapitalna nazwa) koło Kielc.

PHPCon Poland 2012

Tegoroczna konferencja objęta została sponsoringiem firmy MegiTeam, swój wkład potwierdzili też Microsoft oraz Mentax. Impreza pod medialnym patronatem serwisów php.pl, OSWorld, OSNews, 7thguard.net oraz webhosting.pl. A od teraz, też blog.Vokiel.com.

Co nam przyniesie tegoroczna edycja? Przede wszystkim bardzo istotną zmianę – uczestnicy mają po raz pierwszy realny wpływ na agendę. To właśnie głosy uczestników zadecydują o tym kogo i z czym będzie można usłyszeć podczas konferencji.

Na agendę (poszczególne prelekcje) można głosować na stronie www.phpcon.pl/agenda. W chwili tworzenia tego wpisu dostępnyc jest 29 propozycji – jest o co walczyć, bo w programie spotkania ma szansę pojawić się ich tylko kilkanaście. Prelekcje zostaną dobrane na podstawie liczby oddanych głosów w rankingu, rozpiętość jest już dość znaczna – od 7 do 39 głosów.

Warto wspomnieć o gościach specjalnych, w tym roku są to:

  • Wim Godden, który ma w swoim dorobku pracę dla takich projektów jak choćby PHPAdsNew, a w tej chwili zajmuje się skalowalnością i HA.
  • Thijs Feryn – organizator konferencji PHPBenelux oraz ewangelista odpowiedzialny za kontakty społecznościowe z belgijskiego Combella – firmy hostującej m.in. joind.in.
  • Jam McGuire – drupalista duszą i ciałem, pracujący dla niemieckiej firmy Aquia i reprezentujący Drupala, gdy tylko nadarzy się okazja.

Czas i miejsce

PHPCon 2012 odbędzie się w dniach 28 – 30 września 2012 r w miejscowości Mąchocice Kapitulne (rejon Gór Świętokrzyskich). Miejscem wystąpień będzie położony niedaleko Kielc Hotel Przedwiośnie ***.

Do tych co wybierają się na PHP Con 2012 – do zobaczenia we wrześniu!

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.