DRY (reguła)
Z Wikipedii
Ten artykuł wymaga dopracowania zgodnie z zaleceniami edycyjnymi. Należy w nim poprawić: przeredagować - pociąć na sekcje, za dużo o PHP, dodać więcej o klasach i innych ogólnych mechnizmach/konstrukcjach. Dokładniejsze informacje o tym, co należy poprawić, być może znajdziesz na stronie dyskusji tego artykułu. Po naprawieniu wszystkich błędów można usunąć tę wiadomość. |
DRY - skrót od angielskiego wyrażenia Don't Repeat Yourself, reguły polegającej na unikaniu pisania tej samej części kodu programu w dwóch miejscach w celu zaoszczędzenia czasu i optymalizacji kodu.
Ta pragmatyczna reguła jest najczęściej używana przez twórców programów komputerowych. Jej istotą w tym kontekście jest taki zapis kodu źródłowego programu, żeby elementy wykorzystywane wielokrotnie kodować było trzeba tylko raz, a następnie można było jedynie odwoływać się do nich.
Regułę tę przykładowo stosuje się we frameworkach Ruby on Rails czy Django. Jest często spotykana (a nawet niemalże wymagana) podczas pisania skryptów PHP, w których to serwer wykonuje kod. Aby uniknąć powtórzeń definiuje się funkcje oraz tworzy klasy.
Chodzi tu głównie o uniknięcie naiwnego kopiowania i wklejania tekstu na rzecz tworzenia funkcji bądź procedur - nazwanych bloków programu, które są wykorzystywane zamiast powtórzeń tekstu.
Reguła DRY jest także sposobem na zapewnienie lokalności zmian w tekście programu podczas jego ewolucji w czasie. W przypadku bowiem konieczności wprowadzenia zmian, bez stosowania się do reguły DRY, zmiany trzeba robić w wielu miejscach. Prowadzi to zgodnie z jednym z praw Murphy'ego do powstawania błędów, gdyż z dużym prawdopodobieństwem w co najmniej jednym miejscu programu pozostanie stara, skopiowana wersja jego tekstu.
Jednocześnie stosowanie DRY wymusza lepsze specyfikowanie funkcjonalności i projektowanie interfejsów w kierunku ich uniwersalności. Na przykład funkcje: wypisująca dane do pliku i wypisująca dane na ekran mają z reguły niemal identyczną postać. Zaprojektowanie wspólnego interfejsu wypisywania danych dla ekranu i pliku (deskryptor konsoli, którego można użyć razem z write() w POSIX, czy strumienie w C++) pozwalają na całkowite uwspólnienie kodu.
W swych założeniach reguła DRY jest podobna do tzw. brzytwy Ockhama i reguły KISS.
Spis treści |
[edytuj] Przykład w C++
[edytuj] Funkcje
W języku C++ przykładem na zastosowanie reguły DRY są funkcje.
Na przykład kod w postaci:
#include <iostream> using namespace std; int main() { int theValue = 0; theValue += 10; cout << theValue << endl; if (theValue >= 30) cout << "Liczba jest wieksza lub rowna 30!\n"; theValue += 10; cout << theValue << endl; if (theValue >= 30) cout << "Liczba jest wieksza lub rowna 30!\n"; theValue += 10; cout << theValue << endl; if (theValue >= 30) cout << "Liczba jest wieksza lub rowna 30!\n"; theValue += 10; cout << theValue << endl; if (theValue >= 30) cout << "Liczba jest wieksza lub rowna 30!\n"; return 0; }
Wynik:
10 20 30 Liczba jest wieksza lub rowna 30! 40 Liczba jest wieksza lub rowna 30!
Można zastąpić łatwiejszą do konserwacji wersją:
#include <iostream> using namespace std; void getAndIncrease(int&); // prototyp funkcji int main() { int theValue = 0; getAndIncrease(theValue); // Cztery wywołania funkcji getAndIncrease(theValue); getAndIncrease(theValue); getAndIncrease(theValue); return 0; } void getAndIncrease(int &theValue) // Definicja funkcji { theValue += 10; cout << theValue << endl; if (theValue >= 30) cout << "Liczba jest wieksza lub rowna 30!\n"; }
Wynik:
10 20 30 Liczba jest wieksza lub rowna 30! 40 Liczba jest wieksza lub rowna 30!
W obecnym przykładzie kod tylko nieznacznie się skrócił, ale wystarczy pomyśleć co byłoby, gdyby programista musiał wpisać go wielokrotnie, albo gdyby powtarzający się kod był długi. Pozwala to zaoszczędzić miejsce i zamiast pisać w wielu miejscach ten sam kawałek kodu można wywołać go jako funkcję. Dzięki temu można robić rzeczy niemożliwe iteracyjnie, jak rekurencja (rekursja). Kod w takiej postaci znacznie łatwiej poddawać konserwacji.
[edytuj] Przykład w PHP
[edytuj] Deklaracja funkcji
Poniżej znajduje się przykładowy kod napisany w PHP:
$liczba_a = 83; $liczba_b = 72; $liczba_c = -2; //... if ($liczba_a > 0){ echo 'X'; $predkosc = $liczba_a * $stala_predkosci; } else{ echo 'Y'; $predkosc = 0; } if ($liczba_b > 0){ echo 'X'; $predkosc = $liczba_b * $stala_predkosci; } else{ echo 'Y'; $predkosc = 0; } if ($liczba_c > 0){ echo 'X'; $predkosc = $liczba_c * $stala_predkosci; } else{ echo 'Y'; $predkosc = 0; }
Zamiast powtórzonego kodu możemy po prostu zdefiniować funkcję:
function sprawdz($liczba){ global $stala_predkosci; if ($liczba > 0){ echo 'X'; return $liczba * $stala_predkosci; } else{ echo 'Y'; return 0; } } $liczba_a = 83; $liczba_b = 72; $liczba_c = -2; sprawdz($liczba_a); sprawdz($liczba_b); sprawdz($liczba_c);
Jak widać kod jest krótszy i brak już w nim powtarzającego się kodu.
[edytuj] Include, require
W celu uniknięcia powtórzeń w kodzie oraz jego zminimalizowania, w PHP stosuje się też funkcje include i require.
Przykład
if (session_is_registered(uzytkownik)) { include 'log_menu.php'; } elseif (session_is_registered(admin)) { include 'to_log.php'; } else { include 'log_form.php'; }
Dzięki temu mechanizmowi kod wyświetla co innego zalogowanemu użytkownikowi, co innego adminowi, a co innego niezalogowanego - co powoduje, że na jednej stronie nie trzeba się powtarzać i pisać zachowanie skryptu dla zalogowanego i dla niezalogowanego, tylko w zależności od potrzeby podczepiać plik w danej chwili potrzebny.
PHP posiada też inną funkcję która zapobiega powtarzaniu się kodu, mianowicie include_once i require_once. Jeśli po użyciu funkcji require_once użytkownik użyje tej funkcji jeszcze raz w odniesieniu do tego samego pliku, kompilator wyświetli błąd.
require_once 'album.php'; /* Tutaj dalsza część skryptu php */ require_once 'album.php'; // plik album.php już został dołączony więc nie zostanie dołączony po raz drugi
Dzięki tej funkcji mamy pewność, iż plik został dołączony tylko raz. To zastosowanie ma sens np. wtedy kiedy dołączamy plik, w którym deklarowane są funkcje, np.
include_once "funkcje.php";
W pliku mysql.php są następujące instrukcje
function foo() { return 'foo'; } function bar() { return 'bar'; }
Gdyby plik został załączony dwa razy za pomocą zwykłego include lub require, to wystąpiłby błąd, gdyż PHP nie obsługuje ponownego deklarowania funkcji. require/include_once zapobiegają takiemu zachowaniu.