Új funkciók, szolgáltatások bevezetése során a forrás egy idő után kezelhetetlenné válhat.
Ennek egyik jele, hogy egy kis módosítás elvégzése is nehézkes lesz. Ez több erőforrást igényel, ami megdrágítja a fejlesztést, és ezt általában nem tudunk az ügyfélre terhelni.
Ennek elkerülése érdekében a kód folyamatos refactorálására van szükség.
Ezt a folyamatot mutom be összetett, egymásra épülő funkciók esetében.
Vegyünk egy webáruházat, és egy termék részletes oldalát.
1000-s csoportosításban kell megjelenítenünk a "nettó ár + ÁFA tartalom = bruttó ár" információt.
A nettó árat 12345-nak tekintve, 25%-os ÁFÁ-val számolva "12 345 + 3 086 = 15 431" lenne a kívánt eredmény.
Lássuk a jelenlegi forrást.
$priceNet = 12345;
Az első dolog, ami a szemünkbe ötlik, az a kódismétlés.
$priceNetFormat = number_format( $priceNet, 0, ',', ' ' );
$priceVat = $priceNet * 0.25;
$priceVatFormat = number_format( $priceVat, 0, ',', ' ' );
$priceTotal = $priceNet * 1.25;
$priceTotalFormat = number_format( $priceTotal, 0, ',', ' ' );
echo $priceNetFormat.' + '.$priceVatFormat.' = '.$priceTotalFormat; // A továbbiakban ezt elhagyom
Az 1000-s csoportosítás kódját emeljük ki függvénybe, illetve emeljük ki változóba az ÁFA értékét is.
function numberFormat( $value ) {
return number_format( $value, 0, ',', ' ' );
}
$tax = 0.25;
$priceNet = 12345;
$priceNetFormat = numberFormat( $priceNet );
$priceVat = $priceNet * $tax;
$priceVatFormat = numberFormat( $priceVat );
$priceTotal = $priceNet * ( 1 + $tax );
$priceTotalFormat = numberFormat( $priceTotal );
Az ÁFA és a teljes összeg kiszámításához vezessünk be egy-egy függvényt.
Ezek csak az ÁFÁ-tól, valamint a nettó összegtől függnek. (Mivel nem akarunk globális változót használni, ezért az ÁFA értékét paraméterben adjuk át.)
function numberFormat( $value ) {
return number_format( $value, 0, ',', ' ' );
}
$tax = 0.25;
function getPriceVat( $priceNet, $tax ) {
return $priceNet * $tax;
}
function getPriceTotal( $priceNet, $tax ) {
return $priceNet * ( 1 + $tax );
}
$priceNet = 12345;
$priceNetFormat = numberFormat( $priceNet, $tax );
$priceVat = getPriceVat( $priceNet, $tax );
$priceVatFormat = numberFormat( $priceVat );
$priceTotal = getPriceTotal( $priceNet, $tax );
$priceTotalFormat = numberFormat( $priceTotal );
A formázott nettó- és teljes összeg megjelenítését most már két-két lépésben el tudjuk ugyan végezni, de ehhez plusz változó bevezetésére, valamint értékenként két függvény meghívására van szükségünk.
Szüntessük meg a változót, és vonjuk össze a két függvényhívást.
Ezzel párhuzamosan a nettó ár megjelenítését is módosítottam.
function numberFormat( $value ) {
return number_format( $value, 0, ',', ' ' );
}
$tax = 0.25;
function getPriceVat( $priceNet, $tax ) {
return $priceNet * $tax;
}
function getPriceTotal( $priceNet, $tax ) {
return $priceNet * ( 1 + $tax );
}
function getPriceNetFormat( $priceNet, $tax ) {
return numberFormat( $priceNet );
}
function getPriceVatFormat( $priceNet, $tax ) {
return numberFormat( getPriceVat( $priceNet, $tax ) );
}
function getPriceTotalFormat( $priceNet, $tax ) {
return numberFormat( getPriceTotal( $priceNet, $tax ) );
}
$priceNet = 12345;
$priceNetFormat = getPriceNetFormat( $priceNet, $tax );
$priceVatFormat = getPriceVatFormat( $priceNet, $tax );
$priceTotalFormat = getPriceTotalFormat( $priceNet, $tax );
Az átalakítások után keletkező függvények szinte mindegyike árral kapcsolatos tevékenységet végez. Adja magát a következő lépés.
Gyűjtsük osztályba a függvényeket és az ÁFA értékét is.
Ezzel együtt megszüntettem az ÁFA paraméterként való átadását is, mivel az érték már az osztály részét képezi.
class price {
public static $tax = 0.25;
public static function numberFormat( $value ) {
return number_format( $value, 0, ',', ' ' );
}
public static function getPriceNetFormat( $priceNet ) {
return self::numberFormat( $priceNet );
}
public static function getPriceVat( $priceNet ) {
return $priceNet * self::$tax;
}
public static function getPriceVatFormat( $priceNet ) {
return self::numberFormat( self::getPriceVat( $priceNet ) );
}
public static function getPriceTotal( $priceNet ) {
return $priceNet * ( 1 + self::$tax );
}
public static function getPriceTotalFormat( $priceNet ) {
return self::numberFormat( self::getPriceTotal( $priceNet ) );
}
}
$priceNet = 12345;
$priceNetFormat = price::getPriceNetFormat( $priceNet );
$priceVatFormat = price::getPriceVatFormat( $priceNet );
$priceTotalFormat = price::getPriceTotalFormat( $priceNet );
Mostanra a kódunk áttekinthető és a megjelenítés rugalmasan, egy helyen módosítható.
A price osztállyal biztosítjuk, hogy a webáruházban megjelenő ár mindegyike ugyanolyan formában kerül kiírásra. (Számoláshoz pedig használhatjuk a getPriceVat(), getPriceTotal() metódusokat.)
Egy ÁFA vagy valuta-váltás esetén (Ft -> EURO) a tizetes jegyek megjelenítése sem okoz problémát.
(A fenti kódot áttekintve további finomításként elhagyhatnánk a getPrice* metódusok nevéből a "Price" részt: feleslegesnek tűnik egy price osztálybeli metódusnál.
A $priceNet ismétlése miatt további refactorálást végezhetnénk, de az osztály rugalmasságát veszítenénk el, ha az árat egy setterrel, statikus változóban rögzítenénk.)
További funkciókkal való bővítés lehetősége
class price {
private static $decimals = 0;
private static $decimalPoint = ',';
private static $thousandSeparator = ' ';
public static function setTax( $value ) {
self::$tax = $value;
}
public static function setDecimals( $value ) {
self::$decimals = $value;
}
public static function setDecimalPoint( $value ) {
self::$decimalPoint = $value;
}
public static function setThousandSeparator( $value ) {
self::$thousandSeparator = $value;
}
...
public static function numberFormat( $value ) {
return number_format( $value, self::$decimals, self::$decimalPoint, self::$thousandSeparator );
}
}
price::setTax( 0.2 );
price::setDecimals( 2 );