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”

Wysyłka SMS w aplikacjach internetowych

Tworząc aplikacje internetowe często zachodzi potrzeba implementacji modułu do wysyłki SMS.

Może to być informacja o zmianie statusu zamówienia złożonego w sklepie internetowym, może to być jakiś ważny komunikat systemowy dotyczący konta w serwisie, może to być powiadomienie o wystąpieniu jakiegoś zdarzenia, które monitoruje klient (np. pojawienie się oferty spełniającej ustawione kryteria) lub po prostu mechanizm weryfikacji wysyłający kod na telefon. Potrzeby wdrożeń powiadomień SMS’owych z pewnością można mnożyć.

Wdrażając moduł powiadomień SMS należy mieć na uwadze, że komunikacja SMS’owa nadaje przekazywanej wiadomości dużo większy priorytet niż e-mail czy powiadomienie w aplikacji na smartfona, nic bardziej nie irytuje użytkownika niż spam w SMS’ach.

Obecnie w internecie znaleźć można bardzo wiele bramek/serwisów oferujących mniej lub bardziej zaawansowane systemy do obsługi powiadomień sms.

Jak to działa?

Wdrożenie modułu SMS jest na prawdę proste i nieskomplikowane, opiera się na 3 krokach:

  • Rejestrujesz się w serwisie obsługującym wysyłki SMS. Ściągasz klienta API czyli bibliotekę przez którą łączysz się z systemem obsługującym wysyłkę.
  • Wprowadzasz namiary autoryzacyjne (login/hasło/hash autoryzujący) tak aby system mógł zidentyfikować żądanie wysyłki.
  • Wdrażasz wywołanie API do aplikacji.

Należy w tym miejscu rozróżnić bramkę sms od usługi sms api. Zwykła bramka sms jedynie umożliwia ręczne wprowadzenie wiadomości natomiast w aplikacji potrzebujemy mechanizmu automatycznego, czyli dostęp przez API.

Który serwis do wysyłki SMS wybrać?

Jak wspomniałem wcześniej, serwisów do wysyłki SMS jest wiele, zdecydowana większość jest płatna a ceny wahają się w granicach od kilku do kilkunastu groszy za SMS, czyli w budżecie np. 100 zł dostępnych jest 1428 smsów w cenie 0,07 zł każdy. Myślę, że przy takim niskim koszcie wysyłki nie opłaca się szukać na siłę darmowych niekoniecznie sprawdzonych i dobrze działających alternatyw.

Ja w projekcie wybrałem SMSAPI.pl. Dlaczego?

  • Profesjonalnie napisany klient php, dostępny od ręki w composerze.
  • Bardzo dobrze przygotowany dział dla developera (smsapi.pl/dev) z wieloma gotowymi modułami i przykładowymi integracjami.
  • Mnogość opcji wysyłki wiadomości ECO, PRO, ze zdefiniowanym nadawcą lub bez, MMS, VMS, odbiór wiadomości.
  • Szybkość działania, większość wiadomości dostarczane jest w czasie do 10 sekund.
  • Przejrzysty serwis internetowy i panel klienta, możliwość wysyłki bezpośrednio z panelu klienta.

Przykład użycia API

<?php

require_once 'smsapi/Autoload.php';

$client = new \SMSApi\Client('login');
// Ustawiamy hasło, w panelu klienta możemy wygenerować hasło różne od hasła do panelu klienta, wysyłkę można też zabezpieczyć IPkami.
$client->setPasswordHash( 'haslo w md5' );

// Inicjalizujemy klienta API
$smsapi = new \SMSApi\Api\SmsFactory();
$smsapi->setClient($client);

try {

    $actionSend = $smsapi->actionSend();

    $actionSend->setTo('600xxxxxx');
    $actionSend->setText('Hello World!!');
    //Pole nadawcy lub typ wiadomość 'ECO', '2Way'
    $actionSend->setSender('Info');

    $response = $actionSend->execute();

    foreach( $response->getList() as $status ) {
        echo  $status->getNumber() . ' ' . $status->getPoints() . ' ' . $status->getStatus();
    }
}
// Przechwytujemy ewentualne błędy, będą one automatycznie widoczne w panelu klienta.
catch( \SMSApi\Exception\SmsapiException $e ) {
    echo 'ERROR: ' . $e->getMessage();
}

Kombinacje bez powtórzeń zbioru liczb – zapytanie SQL

Pytanie zgłoszone przez czytelnika. W jaki sposób z zestawu liczb będących w osobnych rekordach wyświetlić kombinacje bez powtórzeń. Dla przykładu wyświetlimy kombinacje bez powtórzeń zbioru 3 elementowego ze zbioru 6 elementowego. n!/k!(n-k)!

Tworzymy tabelę testową:

create table test(
id serial primary key,
  number float
);

insert into test(number) values(2.49);
insert into test(number) values(5.11);
insert into test(number) values(10);
insert into test(number) values(20);
insert into test(number) values(27.4);
insert into test(number) values(75);

W zapytaniu nasze dane złączamy 3 krotnie bo takiej wielkości zbiór unikalnych liczb chcemy uzyskać, złączamy z warunkiem na różne IDki aby uniknąć zduplikowanych liczb. Następnie w zapytaniu nadrzędnym odfiltrowujemy powtarzające się rekordy.

W przypadku gdybyśmy chcieli uzyskać zbiory 4 elementowe należy złączyć 4 krotnie, stworzyć kolumnę number4 i dodać na nią warunek w zapytaniu zewnętrznym.

SELECT 
*
FROM 
  (SELECT
    T1.number AS number1, 
    T2.number AS number2, 
    T3.number AS number3 
  FROM test AS T1 
  JOIN test AS T2 ON T1.id != T2.id
  JOIN test AS T3 ON T2.id != T3.id AND T1.id != T3.id
  ORDER BY number1, number2, number3
  ) AS sub
WHERE 
  sub.number1 <  sub.number2
AND
  sub.number2 <  sub.number3

Wynik zapytania:

 number1 | number2 | number3
---------+---------+---------
    2.49 |    5.11 |      10
    2.49 |    5.11 |      20
    2.49 |    5.11 |    27.4
    2.49 |    5.11 |      75
    2.49 |      10 |      20
    2.49 |      10 |    27.4
    2.49 |      10 |      75
    2.49 |      20 |    27.4
    2.49 |      20 |      75
    2.49 |    27.4 |      75
    5.11 |      10 |      20
    5.11 |      10 |    27.4
    5.11 |      10 |      75
    5.11 |      20 |    27.4
    5.11 |      20 |      75
    5.11 |    27.4 |      75
      10 |      20 |    27.4
      10 |      20 |      75
      10 |    27.4 |      75
      20 |    27.4 |      75
(20 rows)

Masz problem SQL do rozwiązania? Napisz.

Jak usunąć klasę „hentry” z WordPress?

W wordpress’owym szablonie single.php, który odpowiada za wyświetlenie pojedynczego wpisu używana często jest funkcja

post_class();

Funkcja ta generuje szereg klas typu:

class="post-395 post type-post status-publish format-standard hentry category-sample category-wyroznione"

Konflikt Rich Snippets

Klasy te często są przydatne i na części z nich z pewnością opierają się definicje CSS. Problem w tym, że jeżeli na blogu posiadamy zaimplementowane Google Rich Snippets w formacie innym niż microformats to klasa „hentry” będzie powodować błędy widoczne na screenie. Czytaj dalej „Jak usunąć klasę „hentry” z WordPress?”

Jak w WordPress usunąć rel=”next” i rel=”prev”?

Według wytycznych Google atrybuty znacznika LINK rel=”next” i rel=”prev” znajdujące się w sekcji HEAD służą do wskazywania zależności pomiędzy stronami na liście stron… czyli opisują pozycje w pagerze. Jest to istotna podpowiedź na temat duplikacji oraz zależności treści w serwisie i wpływa pozytywnie na SEO.

Duże było moje zdziwienie gdy niedawno odkryłem, że WordPress standardowo wstawia te atrybuty na stronach ze szczegółami wpisu wstawiając w nich linki do następnego i poprzedniego (w kontekście daty publikacji) wpisu. Każdy post jest unikalny, posiada unikalny adres url i zazwyczaj nie jest semantycznie powiązany z następnym/poprzednim.

Wpisy z rel=”next” i rel=”prev” powinny być na stronie z listą wpisów w kategorii gdzie mamy stronicowanie, natomiast na stronach ze szczegółami wpisu znaczniki te są kompletnie niepotrzebne i mogą powodować jedynie zamieszanie.. Czytaj dalej „Jak w WordPress usunąć rel=”next” i rel=”prev”?”

Instalacja Apache 2.4 + PHP 5.4 pod Windows 7

Z pewnością w necie znajduje się już wiele poradników w temacie instalacji i konfiguracji PHP + Apache, jednak nie zawsze zawierają wszelkie niezbędne informacje. Wczoraj sam przebrnąłem przez proces aktualizacji z Apache 2.2 i PHP 5.2 do Apache 2.4 + PHP 5.4 co defakto oznaczało ponowną instalacją i konfiguracją tych dwóch softów. Czytaj dalej „Instalacja Apache 2.4 + PHP 5.4 pod Windows 7”

Sprawdzanie permutacji ciągu znaków w PostgreSQL

Permutacja w języku matematycznym to „wzajemnie jednoznaczne przekształcenie pewnego zbioru na siebie”. Używając języka mniej technicznego permutacje, na przykładzie liter w słowie, to wszystkie możliwe ustawienia literek w słowie, zatem dla słowa „marcin” permutacjami będą: „amrcin”, „mracin”, „mrcain” etc… w słowie 6 znakowym będzie ich łącznie 6!.

Problem

W bazie danych mamy pole tekstowe z zapisanymi pewnymi ciągami znaków, chcemy sprawdzić te dane pod kątem występowania w nich permutacji pewnego stringu. Czyli mając w danych wejściowych np. „mrcain” chcemy sprawdzić czy w bazie nie ma „marcin” lub innej permutacji. Czytaj dalej „Sprawdzanie permutacji ciągu znaków w PostgreSQL”