Autor wpisu: Piotr Śliwa, dodany: 07.09.2014 23:05, tagi: php
Obiekty* są fajne, dzięki nim można zrobić miłe w użyciu api. Obiekty są fajne, bo dają nam narzędzia do reużywalności kodu. Obiekty są fajne przede wszystkim dlatego, bo dają nam możliwość ukrywania implementacji i hermetyzacji danych.
PHP to przede wszystkim język dwuparadygmatowy, powstał jako język strukturalny. Następnie dodano do niego bardzo kulawe wsparcie do programowania obiektowego (PHP4), które naprostowano w PHP5. Kolejnym krokiem było dodanie trochę mniej kulawego wsparcia dla domknięć (Closure) w PHP 5.3, które częściowo zostało naprostowane w PHP 5.4.
Ale lepszy rydz niż nic. Ten rydz nie jest taki zły, dzięki niemu programowanie funkcyjne w PHP jest łatwiejsze i faktycznie ma sens.
A o co chodzi?
Nie chcę sypać tutaj definicjami, ale absolutne minimum musi być. W programowaniu funkcyjnym funkcja jest obywatelem pierwszej kategorii - to znaczy że można ją przypisać do zmiennej, wykonywać operacje na niej, przekazywać funkcje jako parametr do funkcji itp. Analogicznie do obiektu w OOP - można przypsać obiekt do zmiennej, wywołać jakąś metodę na nim i przekazać ten obiekt jako argument do jakieś metody / funkcji. W php przypisanie do zmiennej i przekazanie jako parametr można zrealizować tak:
//przypisanie do zmiennej
$removeDigits = function($s){
return preg_replace('/\d/', '', $s);
};
//przekazanie jako argument
$words = array_map($removeDigits, ['śaJ123', '32i1', 'aisogłaM321']);
Jest to mały, prosty kawałek kodu zrealizowany w sposób funkcyjny: mamy dane na wejściu w postaci tablicy stringów, a następnie jest wywołana funkcja, która korzystając z innego parametru (funkcji $removeDigits
), wywołuje operacje na danych wejściowych. Kod ten oczywiście można zrealizować w sposób strukturalny:
$words = array();
foreach(['śaJ123', '32i1', 'aisogłaM321'] as $word) {
$words[] = preg_replace('/\d/', '', $word);
}
Obiektowo również:
class Word {
private $word;
//... 50 lini później
$firstChars = $stringCleaner->clean([new Word('śaJ123'), new Word('32i1'), new Word('aisogłaM321')]);
Jak widać, obiekty nie wszędzie pasują... ;)
Operacje na funkcjach
W powyższym przykładzie nie pokazałem w jaki sposób można operować na funkcjach - trzeba nadrobić zaległości. Wyobraźmy sobie, że nie dość że chcemy usunąć cyfry, to jeszcze chcemy odwrócić każdy wyraz (za pomocą np. strrev
).
$removeDigits = function($s){
//dodane strrev
return strrev(preg_replace('/\d/', '', $s));
};
$words = array_map($removeDigits, ['śaJ123', '32i1', 'aisogłaM321']);
Ok, nazwa $removeDigits
już nie jest aktualna, nowa nazwa będzie wymagała zastosowanie operatora logicznego &&
- to jest zapach że funkcja ma więcej niż jedną odpowiedzialność.
Jak przyjrzymy się bliżej i jeśli uważaliśmy na analizie matematycznej, to zauważymy operację zwaną składaniem funkcji.