30 Bieg na Ślężę

Bieg na Ślężę miejsce 89 na 204 startujących, czas 41:50, waga 80,4kg. Pierwszy w karierze vertical gdzie biegnie się tylko pod górę z metą na szczycie. Bieg króciutki acz intensywny 5,10km i 530m up.

Fizycznie – dobrze, w trakcie biegu nie odczuwałem żadnych negatywnych fizycznych dolegliwości. Przed biegiem pracowałem nad spiętym brzuchatym (wewnętrzna głowa) w lewej łydce dwójką lewej nogi. Coś tam rozluźniłem ale po powrocie czuję więc do wyprostowania u fizjo.

Gdy na końcówce cisnąłem już na maksa to wydawało mi się, że blokerem nie były nogi, które jakoś nie czułem a kardio i oddech.

Żywienie – dobrze, wiele tego nie było. Standardowa kanapka o 8:00 humus + warzywa oraz miska makaronu i 1 morela. Po przyjeździe 2 figi a po rozgrzewce, 15 min przed biegiem standardowo 1 żel. Na trasę wziąłem softflask z 100ml ale nie skorzystałem, głównie pod cel uzupełnienia po biegu.

Warunki – ciepełko 19 stopni i pełnie słońce. 95% trasy w cieniu a ciepła nie odczuwałem więc raczej bez negatywnego wpływu. Na ostatnim km śliskie stały ale ogólnie warun bardzo dobry.

Przebieg – PacePro rozpisałem na 40 minut, pierwsze 1,5km do podbiegu pod Wieżyce -1:30, które planowo straciłem na podejściu, po Wieżycy gdzie nie było dużej stromizny gdzieś do 3km w okolicach 0:00, może lekki minus – to odpuszczenie widać na wykresie tętna. 3-4km gdzie gradient skoczył do 15-20% przejście w szybki chód w efekcie zjazd na +1:30. Ostatni km od skrzyżowania ze ścieżką pod skałami głownie ponownie bieg ale i tak ciut wolniej niż zakładane. Końcówkę cisnąłem już na maksa, pewnie za późno zacząłem. Ostatecznie koniec na +1:50.

Wniosek: po Wieżycy, 3km trzeba cisnąć mocniej żeby zrobić zapas na 4km, ew. wiadomo 4km biec a nie iść.

Ocena – 8/10. Podbiegi to nie jest moja mocna strona, dlatego trzeba nad nimi pracować. Ocena indywidualna RMT=608 co jest historycznie najwyższym moim osiągnięciem. Krośnice 2023=605 a najlepszy górski bieg Lhoste=551. Na pewno mogłem wcześniej przycisnąć bardziej bo dopiero w ostatnim km tętno skoczyło powyżej 170 ale się nie zmobilizowałem. Szacunki RMT trochę pobite więc wstydu nie ma. Więcej pod górkę chyba ciężko mi aktualnie wyciągnąć.

W biegu raczej wyprzedzałem niż byłem wyprzedzany, na wolnym 4 km być może słabe otoczenie biegowe być może nie mobilizowało do ekstremalnego wysiłku, a może po prostu też byłem słaby. Zmobilizowałem się na maksa dopiero od krzyżówki ze ścieżką pod skałami co było zakładane.

Maraton Opawski na Festiwalu 3xKopa

Maraton Opawski OPEN 34 miejsce na 94 zawodników. Widowiskowo – świetnie trasa z pięknymi prawdziwie górskimi ścieżkami i widokami. Biegowo – dla mnie zajazd, 2.2k up to bardzo dużo jak na 41 km, trasa w wielu miejscach mocno stroma zarówno na podejściu jak i na zbiegu. W drugiej pętli mocno doskwierał upał 20+ stopni i pełne słońce. Patrząc na czasy nie tylko dla mnie drugie kółko było zabójcze. Drugie kółko ma tylko 2 km więcej i tyle samo przewyższeń co pierwsze a czas okrążenia spadł mi z 2:37h na 3:53h. Mimo takiej masakry czasowej o dziwo w generalce spadłem tylko o 4 pozycje z 30 na 34. To pokazuje, że inni też lekko nie mieli.

Fizycznie – pierwsze kółko super, drugie bardzo ciężko – sporo skurczów (przywodziciele, dwójki, brzuchate) bywało, że nawet na zbiegu musiałem się na chwilę zatrzymać. Z bólów jedynie po raz pierwszy zbite stopy i to mocno – to pewnie przez rzadkie bieganie górskie w ostatnich miesiącach. Do poprawy więcej biegania po Ślęży na początku sezonu. Mimo iż zaliczyłem już biegowo m.in 72 km i 2.6k up na Sudeckiej Żylecie to jeszcze nigdy tak się nie zniszczyłem fizycznie i emocjonalnie. Na mecie nie mogłem powstrzymać łez, że ta katorga w końcu się skończyła. Być może miałem zbyt wygórowane plany i oczekiwania. Track w zegarku miałem ustawiony na optymistyczne 5:45h ostatecznie skończyłem na 6:30. RMT szacował na 6:06h-6:11h. Moje 5:45h dało by kosmiczne 15 miejsce więc widać, że było nierealne.

Żywienie – zagadka ale raczej słabo, 2 dni przed zawodami po raz pierwszy testowałem “ładowanie węgli” czy zadziałało na plus czy na minus ciężko powiedzieć. Zaraz przed biegiem wszedł baton a na trasie tylko 3 żele, dużo izo i coli. Żeli na pewno za mało mało, na dużo krótszych dystansach wcinałem po 4-5 a teraz przez wcześniejsze łądowanie wungli chyba miałem dosyć słodkiego. Po wciągnięciu żela w ogóle nie czułem mocy. Poszło też 5 salt sticków ale na skurcze nie pomogły. Być może za mało piłem bo nie mogłem użyć planowanego bukłaka 2l gdyż zapomniałęm wziąć zamknięcia. Lecialem więc na 0,5l flasku i choć nie czułem specjalnie doskwierającego pragnienia, to podświadomie, pomiędzy punktami żywieniowymi (były 4) na pewno za bardzo oszczędzałem wodę. Do poprawy.

Warunki – pierwsza pętla fajne – 8-12 stopni, druga 20+ i pełne słońce. Na końcowym podejściu pod Biskupią Kopę w zacienionych miejscach obok trasy leżał śnieg. Najchętniej bym się w nim wytarzał, ostatecznie musiałem poprzestać na wsadzaniu go sobie na głowę, kark, pod koszulkę. Trasa w 99% sucha, w 1% na szlaku strumyk, woda i błoto praktycznie nie do ominięcia. Dużo wąskich górskich ścieżek.

Organizacja – super, punkty żywieniowe dobrze zaopatrzone i pięknie dopingujące. Na minus drobne nieporozumienie z przedwcześnie zamkniętym parkingiem i biuro zawodów daleko od startu (przepak i jedzonko).

Ocena – ciężko jednoznacznie ocenić, miejsce w 45% w 36% stawki nie urywa, dawno tak daleko w biegu się nie uplasowałem. Przechodzenie z dystansu biegu z 20-30 km na maraton zwiększa trudność nie tylko w dystansie ale też w poziomie rywali bo tu zapisują się już głównie osoby zaprawione w bojach. Ale być może to tylko wymówka ;-)

Sam festiwal jak i maraton godny polecenia. Z zastrzeżeniem, że 2 kółko daje popalić. Podobno 3 kółko jest proste i mocno biegowe.

#3xkopa #3xkopa_2024 #maraton #bieganie #bieg #run #running #pokrzywna #góryopawskie

Główne wnioski:
* na razie odpuścić ładowanie węgli
* minimum 1 żel na 1h
* więcej biegania na Ślęży, szczególnie na początku sezonu
* maraton i więcej niż 2k up to na razie bardzo dużo dla mnie

Wzorzec projektowy Decorator – elastyczne dodawanie funkcjonalności

Wzorzec dekoratora jest przydatny w wielu sytuacjach, w których chcemy elastycznie dodawać funkcjonalność do istniejących obiektów. Oto kilka przykładów problemów, do których można użyć wzorca dekoratora:

  1. Dopasowywanie funkcjonalności na etapie uruchamiania: Możemy użyć dekoratora, aby dodać lub zmienić zachowanie obiektu w zależności od określonych warunków, takich jak konfiguracja aplikacji czy uprawnienia użytkownika.
  2. Logowanie i analiza: Dekorator może zostać zastosowany do rejestrowania działań obiektu, dodając logowanie przed lub po wykonaniu konkretnej metody. Na przykład, dekorator może logować czas wykonania metody lub przekazywane argumenty.
  3. Kształtowanie danych wyjściowych: W przypadku danych wyjściowych, takich jak formatowanie danych do wyświetlenia w różnych kontekstach (np. HTML, XML, JSON), dekorator może dostosowywać wyjście w zależności od wymagań.
  4. Cacheowanie: Dekorator może być użyty do dodania mechanizmu buforowania (cache) dla wyników wywołań metod, co pozwala na uniknięcie ponownego obliczania tych samych wyników dla tych samych argumentów.
  5. Autoryzacja: Dekorator może być wykorzystany do dodania mechanizmu autoryzacji przed wykonaniem danej metody. Na przykład, dekorator może sprawdzać uprawnienia użytkownika przed wykonaniem operacji.
  6. Śledzenie stanu obiektu: Dekorator może być użyty do monitorowania i rejestrowania zmian stanu obiektu. Na przykład, możemy zaimplementować dekoratory, które rejestrują historię zmian obiektu lub powiadamiają inne komponenty o aktualizacjach stanu.
  7. Kompresja danych: Dekorator może być użyty do dynamicznego kompresowania danych wyjściowych w celu zmniejszenia rozmiaru przesyłanych danych w zależności od preferencji użytkownika lub ustawień aplikacji.

Wzorzec dekoratora jest niezwykle elastyczny i pozwala na dynamiczne dostosowywanie funkcjonalności obiektów w czasie działania programu, co jest szczególnie przydatne w sytuacjach, gdy zachowanie obiektów może się zmieniać w zależności od różnych czynników.

// Interfejs komponentu
interface Component {
    public function operation(): string;
}

// Konkretny komponent
class ConcreteComponent implements Component {
    public function operation(): string {
        return "ConcreteComponent operation";
    }
}

// Dekorator bazowy
abstract class Decorator implements Component {
    protected $component;

    public function __construct(Component $component) {
        $this->component = $component;
    }

    public function operation(): string {
        return $this->component->operation();
    }
}

// Konkretny dekorator
class ConcreteDecorator extends Decorator {
    public function operation(): string {
        return parent::operation() . " with added behavior in ConcreteDecorator";
    }
}

// Użycie
$component = new ConcreteComponent();
$decoratedComponent = new ConcreteDecorator($component);
echo $decoratedComponent->operation(); // Wyświetli: ConcreteComponent operation with added behavior in ConcreteDecorator

Wykorzystanie wzorca dekoratora w frameworku Symfony

Symfony jest jednym z najpopularniejszych frameworków PHP, który zapewnia solidną strukturę i wiele gotowych rozwiązań do tworzenia aplikacji webowych.

Wśród wielu wzorców projektowych, które można zastosować w Symfony, wzorzec dekoratora odgrywa ważną rolę, umożliwiając elastyczne dostosowywanie funkcjonalności aplikacji w czasie jej działania. Poniżej przyjrzymy się, jak można wykorzystać wzorzec dekoratora w Symfony na podstawie konkretnych przykładów.

Dekorowanie usług Symfony

W Symfony usługi są kluczowym elementem, który umożliwia organizację kodu i zarządzanie zależnościami. Za pomocą wzorca dekoratora możemy łatwo modyfikować zachowanie usług bez ingerencji w ich kod. Przykładowo, załóżmy, że mamy usługę do kompresji danych, ale chcielibyśmy dodać dodatkową funkcjonalność, taką jak logowanie każdego żądania kompresji. Możemy to osiągnąć poprzez utworzenie dekoratora dla tej usługi:

use Symfony\Component\DependencyInjection\Argument\WrappedIterator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

// Dekorator logujący kompresję danych
class CompressionLoggingDecorator implements DataCompressionInterface
{
    private $compressionService;
    private $logger;

    public function __construct(DataCompressionInterface $compressionService, LoggerInterface $logger)
    {
        $this->compressionService = $compressionService;
        $this->logger = $logger;
    }

    public function compress($data)
    {
        $compressedData = $this->compressionService->compress($data);
        $this->logger->info('Data compressed successfully');
        return $compressedData;
    }
}

// Konfiguracja kontenera usług Symfony
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('compression_service', DataCompressionService::class);
$containerBuilder->register('compression_service_with_logging', CompressionLoggingDecorator::class)
    ->setDecoratedService('compression_service')
    ->addArgument(new Reference('compression_service'))
    ->addArgument(new Reference('logger'));

W powyższym przykładzie mamy usługę DataCompressionService, którą dekorujemy za pomocą CompressionLoggingDecorator, dodając logowanie do każdego wywołania kompresji danych.

Dekorowanie formularzy Symfony

Formularze w Symfony są wygodnym sposobem na obsługę danych wejściowych od użytkownika. Za pomocą wzorca dekoratora możemy modyfikować zachowanie formularzy w zależności od różnych warunków. Na przykład, możemy dodać walidację dodatkowych pól lub zmienić sposób wyświetlania formularza w zależności od uprawnień użytkownika. Poniżej znajduje się przykład dekorowania formularza:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

// Dekorator formularza dodający pole "Uwagi"
class CommentFieldDecorator extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('comment', TextType::class, [
            'label' => 'Uwagi',
            'required' => false,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'App\Entity\Comment',
        ]);
    }
}

// Klasa bazowa formularza
class CommentFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Budowanie formularza
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'App\Entity\Comment',
        ]);
    }
}

// Użycie dekoratora do zmiany formularza
$commentForm = $this->createForm(CommentFieldDecorator::class, $comment);

W tym przykładzie dekorujemy formularz CommentFormType za pomocą CommentFieldDecorator, dodając pole „Uwagi” do istniejącego formularza.

Podsumowanie

Wzorzec dekoratora jest potężnym narzędziem, które można zastosować w Symfony do elastycznego dostosowywania funkcjonalności aplikacji bez konieczności modyfikowania oryginalnego kodu.

Dzięki zastosowaniu dekoratorów możemy łatwo rozszerzać zachowanie usług, formularzy i innych komponentów Symfony, co przyczynia się do zwiększenia modularności i elastyczności naszej aplikacji.

Wzorzec projektowy Adapter – klucz do dostosowania interfejsu do Twoich potrzeb

Wzorzec projektowy Adapter w PHP – jak go zastosować w swoim projekcie?

Zobacz jak wzorzec projektowy Adapter może Ci pomóc dostosować interfejs do potrzeb Twojego projektu w PHP. Przeczytaj nasz przewodnik i poznaj przykłady jego zastosowania w praktyce.

Adapter to wzorzec projektowy, który pozwala na dostosowanie interfejsu jednej klasy do interfejsu innej klasy. Jest to użyteczne, gdy chcesz użyć już istniejącej klasy, ale jej interfejs nie pasuje do Twoich potrzeb. Wzorzec Adapter pozwala na ukrycie różnic między interfejsami, dzięki czemu można je łatwo połączyć i użyć razem.

Jakie zastosowania ma wzorzec Adapter?

Wzorzec Adapter jest często stosowany w następujących sytuacjach:

  • Integracja z istniejącymi klasami: Adapter może być użyty do integracji z już istniejącymi klasami, których interfejs jest niezgodny z twoimi potrzebami.
  • Zmiana interfejsu: Adapter pozwala na zmianę interfejsu klasy bez ingerencji w jej kod źródłowy.
  • Rozszerzanie funkcjonalności: Adapter może być użyty do rozszerzenia funkcjonalności istniejącej klasy poprzez dodanie dodatkowych funkcji.
  • Łączenie różnych systemów: Adapter może być użyty do łączenia różnych systemów i ukrywania różnic między nimi.
  • Współpraca z różnymi bibliotekami: Adapter może być użyty do współpracy z różnymi bibliotekami i frameworkami, które mają różne interfejsy.

Wzorzec projektowy Adapter – przykład implementacji

interface Target {
    public function request();
}
 
class Adaptee {
    public function specificRequest() {
        return "Specific request";
    }
}
 
class Adapter implements Target {
    private $adaptee;
 
    public function __construct(Adaptee $adaptee) {
        $this->adaptee = $adaptee;
    }
 
    public function request() {
        return "Adapter: (TRANSLATED) " . $this->adaptee->specificRequest();
    }
}
 
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
 
echo $adapter->request();

W powyższym kodzie mamy interfejs Target, który zawiera sygnaturę metody request(), którą chcemy użyć. Klasa Adaptee jest klasą, która posiada funkcjonalność, ale interfejs jest niezgodny z naszymi wymaganiami. Klasa Adapter jest naszym adapterem i jest on implementacją interfejsu Target. Wewnątrz klasy Adapter używamy obiektu Adaptee, aby wykonać żądane zadanie.

Wzorzec projektowy Adapter w Laravel

Wzorzec projektowy Adapter jest często używany w frameworku Laravel. Laravel posiada wiele mechanizmów, które pozwalają na łatwe dostosowanie interfejsu i implementacji do potrzeb projektu.

Na przykład, można dostosować dostarczone przez framework adaptery bazy danych, aby użyć innej niż domyślna biblioteki do komunikacji z bazą danych. W ten sposób wzorzec Adapter jest wykorzystywany w Laravel do dostosowywania interfejsu do potrzeb projektu.

Rozbicie routes na kilka plików w Laravel

Gdy aplikacja robi się coraz większa dla czytelności można chcieć podzielić plik routes/web.php na kilka mniejszych.

Aby to zrealizować moją pierwszą myślą było po prostu include wydzielonych plików z trasami:

// routes/web.php

require_once 'web/redirects.php';
require_once 'web/website.php';
require_once 'web/admin.php';

Mimo iż to jest złe podejście to po tej zmianie aplikacja działała całkowicie poprawnie.

Problemy zaczęły się gdy wykonałem testy PHPUnit

    public function test_home()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

    public function test_posts()
    {
        $response = $this->get('/posts');

        $response->assertStatus(200);
    }

Pierwszy test zawsze przechodził jednak następne (bez względu czy w tym samym czy innym pliku) zwracały błąd:

Route [home] not defined.

Okazuje się, że mechanika testująca Laravela wczytuje jedynie plik routes/web.php

Aby poprawnie rozbić routes na kilka plików zamiast includów w samym pliku trzeba dostarczyć ścieżki w Provoderze.

Poprawne rozbicie routes na wiele plików

// App\Providers\RouteServiceProvider.php;

Route::middleware('web')
    ->namespace($this->namespace)
    ->group(
        [
            base_path('routes/web.php'),
            base_path('routes/web/redirects.php'),
            base_path('routes/web/website.php'),
            base_path('routes/web/admin.php'),
        ]
    );

Wzorzec projektowy Strategy. Elastyczność i niezależność w twoim kodzie.

Wzorzec projektowy Strategy przydaje się do definiowania rodziny zachowań, algorytmów lub strategii, które mogą być wymieniane przez aplikację. Umożliwia to programowanie do interfejsu, a nie konkretnej implementacji.

Do konkretnych zastosowań wzorca Strategy należą:

  • Abstrakcja algorytmów: Strategy pozwala na oddzielenie logiki algorytmu od klienta, co pozwala na łatwą zmianę implementacji algorytmu bez konieczności modyfikacji kodu klienta.
  • Elastyczność: Aplikacja może zmienić strategię w trakcie działania, co pozwala na dostosowanie działania aplikacji do różnych potrzeb czy sytuacji.
  • Łatwe testowanie: oddzielenie algorytmów od reszty aplikacji pozwala na łatwe testowanie poszczególnych implementacji algorytmów.
  • Skalowalność: rozdzielenie algorytmów

Wzorzec projektowy Strategy – przykład implementacji

Poniżej przedstawiam przykład implementacji wzorca projektowego Strategy w PHP:

interface SortStrategy {
    public function sort(array $data): array;
}

class BubbleSort implements SortStrategy {
    public function sort(array $data): array {
        // implementacja sortowania bąbelkowego
        return $data;
    }
}

class quickSort implements SortStrategy {
    public function sort(array $data): array {
        // implementacja sortowania szybkiego
        return $data;
    }
}

class Sorter {
    protected $sortStrategy;

    public function __construct(SortStrategy $sortStrategy) {
        $this->sortStrategy = $sortStrategy;
    }

    public function setSortStrategy(SortStrategy $sortStrategy) {
        $this->sortStrategy = $sortStrategy;
    }

    public function sort(array $data): array {
        return $this->sortStrategy->sort($data);
    }
}

Kod powyżej zawiera interfejs SortStrategy, który zawiera metodę sort(array $data): array. Klasy bubbleSort i quickSort implementują ten interfejs i zwracają posortowane dane.

Klasa Sorter jest klasą klienta, która przyjmuje obiekt implementujący interfejs SortStrategy w konstruktorze, a następnie używa tego obiektu do wywołania metody sort(array $data) .

$data = [5, 1, 3, 8, 2, 9];

$sorter = new Sorter(new bubbleSort());
$sorter->sort($data);

$sorter->setSortStrategy(new quickSort());
$sorter->sort($data);

W powyższym przykładzie tworzymy instancję klasy Sorter z podaną implementacją sortowania, która jest przypisana do pola sortStrategy. W kolejnym kroku dzięki metodzie setSortStrategy zmieniamy implementację sortowania na inną.

Wzorzec strategy pozwala nam na dynamiczne zmienienie implementacji algorytmu, pozwala na oddzielenie logiki algorytmu od klienta oraz umożliwia tworzenie nowych implementacji bez konieczności modyfikacji kodu klienta.

Wzorzec projektowy Strategy w Laravel

W Laravelu wzorzec Strategy jest używany w kilku miejscach, w tym:

Obsługa różnych formatów danych – Laravel używa strategii do obsługi różnych formatów danych, takich jak json, xml czy też csv. Dzięki temu możemy łatwo dostosować format danych który jest zwracany przez API.

Obsługa różnych metod płatności – Laravel używa strategii do obsługi różnych metod płatności, takich jak PayPal czy też Stripe. Dzięki temu możemy łatwo dostosować system płatności do potrzeb naszej aplikacji.

Obsługa różnych metod wysyłki – Laravel używa strategii do obsługi różnych metod wysyłki, takich jak Poczta Polska czy też DHL. Dzięki temu możemy łatwo dostosować system wysyłki do potrzeb naszej aplikacji.

Widać więc, że wzorzec strategy jest ważnym elementem w Laravelu, ponieważ pozwala na dynamiczne dostosowywanie działania aplikacji do różnych potrzeb i sytuacji, co wpływa na elastyczność i skalowalność aplikacji. Dzięki temu, logika działania jest oddzielona od reszty aplikacji, co pozwala na łatwe testowanie oraz rozwijanie poszczególnych modułów.

Wzorzec projektowy Fabryka. Twoja szansa na zwiększenie czytelności i testowalności kodu.

Wzorzec projektowy Fabryka to Twoja przepustka do projektowania modularnego i skalowalnego kodu.

Wzorzec projektowy Fabryka jest przydatny do tworzenia obiektów. Głównym celem tego wzorca jest oddzielenie logiki tworzenia obiektów od reszty aplikacji oraz umożliwienie łatwego tworzenie różnych typów obiektów.

Do konkretnych zastosowań wzorca Fabryka należą:

  • Abstrakcja tworzenia obiektów – fabryka jest odpowiedzialna za tworzenie obiektów, a nie klient, dlatego logika tworzenia obiektów jest oddzielona od reszty aplikacji.
  • Tworzenie różnych typów obiektów – fabryka może tworzyć różne typy obiektów, które implementują tę samą klasę bazową lub interfejs. To pozwala na łatwe rozszerzanie aplikacji o nowe funkcjonalności.
  • Tworzenie obiektów z danymi testowymi – fabryki często są używane do tworzenia obiektów z danymi testowymi, co jest przydatne przy tworzeniu testów jednostkowych.
  • Elastyczność – Wzorzec fabryka umożliwia na dynamiczne tworzenie różnych implementacji tej samej klasy bazowej czy interfejsu.

Wzorzec projektowy Fabryka – przykład implementacji

Poniżej przedstawiam przykład implementacji wzorca projektowego Fabryka w PHP:

interface Vehicle {
    public function getType(): string;
}

class Car implements Vehicle {
    public function getType(): string {
        return "Car";
    }
}

class Bike implements Vehicle {
    public function getType(): string {
        return "Bike";
    }
}

class VehicleFactory {
    public static function createVehicle(string $type): Vehicle {
        switch ($type) {
            case "car":
                return new Car();
            case "bike":
                return new Bike();
            default:
                throw new Exception("Invalid vehicle type");
        }
    }
}

Kod powyżej zawiera interfejs Vehicle, który zawiera metodę getType(). Klasy Car i Bike implementują ten interfejs i zwracają odpowiedni typ pojazdu. Klasa VehicleFactory jest fabryką, która posiada statyczną metodę createVehicle(), która jest odpowiedzialna za tworzenie obiektów klas Car i Bike. Metoda ta przyjmuje jako argument typ pojazdu, a następnie w zależności od tego jaki typ jest podany zwraca odpowiedni obiekt.

$car = VehicleFactory::createVehicle("car");
echo $car->getType(); // "Car"

$bike = VehicleFactory::createVehicle("bike");
echo $bike->getType(); // "Bike"

W powyższym przykładie używamy metody createVehicle z klasy VehicleFactory by utworzyć instancję klasy Car lub Bike.

Warto zauważyć, że zwiększa to abstrakcję i oddziela logikę tworzenia obiektów od reszty aplikacji. Dzięki temu w razie potrzeby, możemy łatwo zmienić sposób tworzenia obiektów bez wpływu na pozostałą część aplikacji.

Warto wspomnieć że wzorzec Fabryka jest często używany w połączeniu z innymi wzorcami projektowymi takimi jak np. Wzorzec projektowy Strategia czy też Wzorzec projektowy Builder. Dzięki temu połączeniu, tworzą one skomplikowany system, który jest bardziej elastyczny i łatwy w utrzymaniu.

Wzorzec projektowy Fabryka w Laravel

W Laravelu wzorzec fabryka jest używany w kilku miejscach, w tym:

Tworzenie obiektów modeli – Laravel używa fabryk do tworzenia obiektów modeli, które reprezentują rekordy z bazy danych. Fabryki pozwalają na łatwe utworzenie obiektów z danymi testowymi, co jest bardzo przydatne przy tworzeniu testów jednostkowych.

Tworzenie migracji – Laravel używa fabryk do generowania danych testowych do migracji, które pozwalają na przetestowanie aplikacji przed uruchomieniem jej na produkcji.

Tworzenie przykładowych danych – Laravel udostępnia także API do tworzenia przykładowych danych, które są generowane przez fabryki.

Tworzenie modeli w kontrolerach – Fabryki Laravel pozwalają także na proste tworzenie modeli bezpośrednio w kontrolerach, w związku z tym użycie konstruktora nie jest konieczne.

Widać więc, że fabryki są istotnym elementem w Laravelu, ponieważ pozwalają na generowanie danych testowych, tworzenie modeli i migracji, co wpływa na poprawienie przetestowalności aplikacji. Dzięki fabrykom kod jest bardziej czytelny, ponieważ logika tworzenia obiektów jest oddzielona od reszty aplikacji.

Wzorzec projektowy Fabryka w Symfony

W Symfony możemy również użyć fabryki do tworzenia instancji usług zależnie od określonych warunków lub konfiguracji.

Na przykład, możemy stworzyć fabrykę, która na podstawie parametru konfiguracyjnego utworzy odpowiednią instancję usługi do obsługi operacji na plikach.

class FileServiceFactory {
    public static function create(string $storageType): FileServiceInterface {
        switch ($storageType) {
            case 'local':
                return new LocalFileService();
            case 'cloud':
                return new CloudFileService();
            default:
                throw new \InvalidArgumentException('Invalid storage type');
        }
    }
}

// Użycie fabryki
$fileService = FileServiceFactory::create('cloud');
$fileService->uploadFile($file);

Pluginy do WordPress

Uwaga: post oryginalnie został opublikowany w 2014, ale lista pluginów jest stale aktualizowana.

Poniżej prezentuję moją subiektywną listę najlepszych pluginów przydatnych do tworzenia i utrzymywania serwisu opartego o platformę WordPress.

Jeżeli znasz przydatny plugin podziel się tym w komentarzu.

Budowanie serwisu

Advanced Custom Fields – najlepszy plugin do budowania intuicyjnego interfejsu w panelu admina dla użytkowników serwisu postawionego na WordPress’ie. ACF bazuje na WordPress’owych custom_fields, nawet początkujący developer WP jest w stanie stworzyć przyjazdy interfejs z dedykowanymi polami pod konkretne dane dla każdego typu postu czy strony.  Integracja z Gravity: Gravityforms Add-on, i NinjaFormsImage Crop Add-on, Advanced Custom Fields: Image Aspect Ratio Crop Field (chyba lepszy) – do wymuszenia konkretnych rozmiarów zdjęć (nie trzeba add_image_size), Advanced Custom Fields: Table Field.

ACF better search – wyszukiwanie po polach ACF

WPgraphQL dla ACF – rest api dla pól ACF

Custom Post Type UI – plugin do tworzenia własnych typów danych i taksonomii, współpracuje z ACF.

Posts 2 Posts – Najlepszy plugin do tworzenia relacji pomiędzy typami postów. To poniekąd analogia do typu Relationship z ACF.

Debug Bar – plugin dodaje do wordpressowego toolbara informacje o wykonanych zapytaniach SQL, pobranych danych z cache, warningach i noticeach phpowych, listuje zmienne GET, POST, COOKIE oraz inne przydatne informacje. Aby skorzystać z wszystkich możliwości plugina należy ustawić w wp-config.php zmienne WP_DEBUG i SAVEQUERIES na true.

Query Monitor – dużo lepsza wtyczka od Debug Bar. Wyświetla więcej danych w bardziej przystępny sposób.

Regenerate Thumbnails – niezastąpiony plugin do aktualizowania plików graficznych z biblioteki mediów po zmianie rozmiaru miniaturek (Ustawienia->media) lub po dodaniu dodatkowych niestandardowych rozmiarów poprzez funkcję add_image_size.

Polylang – bardzo dobry plugin do obsługi wielojęzykowych serwisów, w przeciwieństwie do WPML jest darmowy.

https://github.com/KLicheR/wp-polylang-translate-rewrite-slugs/blob/master/polylang-translate-rewrite-slugs.php

JSON API – RESTful API dla WordPressa. Przydatne gdy w prosty sposób chcemy dostarczyć dane z WP do aplikacji zewnętrznych lub interfejsów JavaScriptowych.

rest-filter – Przywraca możliwość filtrowania w REST API, dzięki temu poprzez &filter[lang]=en można filtrować języki w Polylang.

WordPress REST API – oficjalny plugin REST API od WP

Add From Server – jeżeli potrzebujesz wgrywać do WP duże pliki to zrobisz to dzięki Add From Server. Schemat działania jest prosty, wgrywasz duży plik poprzez FTP do określonego katalogu a następnie z poziomu WP dodajesz do biblioteki mediów. Prosto i intuicyjnie. Jeżeli potrzebujesz wgrywać pliki o niestandardowych rozszerzeniach to pamiętaj o wyłączeniu natywnego filtrowania.

Loco Translate – plugin do tłumaczeń, korzysta z plików PO.

Post Type Archive Link – plugin dodaje linki do menu dla stron list custom post type. Dzięki temu można w prosty i automatyczny sposób dodawać do menu linki do stron z listami custom posts.

Breadcrumb NavXT – plugin do generowania okruszków, breadcrumbs

Simple Share Buttons Adder – przyjazny plugin do social ikon.

Social Media Feather – chyba jeszcze lepszy plugin do social media ikon.

SVG Support – plugin umożliwiający wgrywanie do WP plików SVG. Dodaje też pogląd SVG w bibliotece mediów.

WP-DB-Table-Editor – plugin umożliwiający odczyt/zapis/eksport danych z customowych tabel z bazy danych.

WP Crontrol – plugin umożliwiający dodawanie i zarządzeni wbudowanymi do WP zadaniami crona

Permalink manager – nieoceniony plugin do zaawansowanej zamiany permalinków, prosty interface i świetne działanie.

WP better permalinks – łatwe zarządzanie permalinkami dla custom posts i taxonomies

Shortcake (Shortcode UI) – plugin zapewniający przyjazny interface do tworzenia i wyświetlania shortcode’ów. Posiada niemrawą dokumentacje ale robi fajną robotę. Dodatek wp-shortcode-ui-richtext umożliwiający zamianę textarea na edytor wyswig.

Contextual Related Posts – powiązane posty

Yasr – Yet Another Stars Rating – ocena gwiazdkowa postów

pipDisqus – Lightweight Disqus Comments – plugin zamieniające natywne WP komentarze na disqus. Lepszy od oficjalnego plugina dla WP od disqus.

Czytaj dalej „Pluginy do WordPress”