HTML

Projektmenedzsment, alkalmazásfejlesztés

Online projektmenedzsment rendszerek, webes alkalmazások fejlesztése, refactoring.

Friss topikok

Linkblog

A paraméterátadás egyszerűsítése objektumparaméter használatával (2. rész)

2011.03.02. 23:35 develop

A 2. részben a paraméterek számának csökkentésére az úgynevezett objektumparaméter módszert szeretném bemutatni.

Ennek érdekében vegyük az 1. részben használt myImage osztály PHP forrását. (Bővebb leírás az A paraméterátadás egyszerűsítése a paraméterek számának csökkentésével 1. részben.)

A feladat ugyanaz: adott kép felső és bal szélétől adott távolságra szöveget írni.

Objektumparaméter

Az objektumparaméter lényege, hogy a paraméterek számát úgy csökkentjük, hogy az értékeket objektum-adattagokba helyezzük, és a hívás során az objektum-példányt adjuk át paraméterként. (Így a paraméterek száma egyszerűen 1-re csökkenthető.)

A példa szerint:

  • adott szöveget kell,
  • adott betűmérettel,
  • egy képre írnunk,
  • a bal és felső szélektől adott távolságra.

Hozzunk létre egy osztályt, aminek adattagjaiban megadjuk a szükséges tulajdonságokat. A fentiek szerint négy paraméter használata szükséges. (Ezeket egy-egy adattagba tesszük.)

class imageWidthText {
  public $text = null;
  
  public $size = 10;
  
  public $distance = 10;
  
  public $imageFilePathSource;
  
  public function __construct( $imageFilePathSource, $text ) {
    $this -> imageFilePathSource = $imageFilePathSource;
    $this -> text = $text;
  }
}

Feltételeztem, hogy 10 pixel távolságra, 10 pixeles méretben akarunk általában írni a képre, ezért ezt default értékkén betettem az adattagba.

A fix értékek módosítására közvetlenül ne is adjunk lehetőséget, mivel így tovább tudjuk csökkenteni a kód bonyolultságát.

(A példában az egyszerűség érdekében használok public-ot a protected helyett.)

Köztes osztály létrehozása

A létrehozott objektum példányt fogjuk majd átadni egy olyan metódusnak, ami el is végzi a képre írást.

Annak érdekében, hogy fel tudjuk használni az 1. részben elkészített myImage osztályt, egy új osztályt hoztam létre, myImageWrite néven. Így egyszerűen tudom bemutatni az objektumparaméter használatát.

(Itt most nem cél, hogy az objektumparaméteres megadást a myImage osztályba tegyük. A teljesen különálló myImageWrite osztállyal talán jobban látható az alkalmazás módja, illetve, hogy egy már meglévő - akár teljesen más jellegű szolgáltatásokat nyújtó - osztályhoz hogyan lehet egyszerűen egy további szolgáltatást adni, az eredeti osztály szolgáltatásainak felhasználásával.)

Annyit tettem még, hogy az objektumparamétert - bár nem végzek rajta műveletet -, cím szerint fogadtam. (Így az objektumból nem keletkezik másolat, vagyis spóroltunk némi erőforrást.)

class myImageWrite {
  public static function writeLeftTop( imageWidthText &$object ) {
    $image = new myImage( $object -> imageFilePathSource, $object -> size );
    
    $image -> writeLeftTop( $object -> text, $object -> distance );
    
    $image -> save( 'c:\mintakep_output.jpg' );
  }
}

$image = new imageWidthText( 'c:\mintakep.jpg', 'árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP' );
myImageWrite::writeLeftTop( $image );

Igaz, hogy a fenti megoldás még nem elég rugalmas (tekintve, pl. hogy csak egy kimeneti állománnyal dolgozik), de az objektumparaméter bemutatásával tulajdonképpen megvagyunk.

Üzleti logika beillesztése

Azon túl, hogy az összetartozó paramétereket egy egységbe fogtuk össze, akkor is érdemes használni ezt a módszert, ha a paraméterekhez valamilyen üzleti logika megadása is szükséges.

Például: a képre nem kerülhet 20 pixelnél nagyobb szöveg, és a szöveg mögé fel kell tüntetni egy álandó szöveget is.

Ezeket a "megkötéseket" a konstruktorba tettem.

class imageWidthText {
  public $text = null;
  
  public $size = 10;
  
  public $distance = 10;
  
  public $imageFilePathSource;
  
  public function __construct( $imageFilePathSource, $text, $size = null ) {
    $this -> imageFilePathSource = $imageFilePathSource;
    $this -> size = 20 < $size ? 20 : $size;
    $this -> text = $text.' - develop.blog.hu';

  } } class myImageWrite {   public static function writeLeftTop( imageWidthText &$object ) {     $image = new myImage( $object -> imageFilePathSource, $object -> size );          $image -> writeLeftTop( $object -> text, $object -> distance );          $image -> save( 'c:\mintakep_output.jpg' );   } } $image = new imageWidthText( 'c:\mintakep.jpg', 'árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP', 10 ); myImageWrite::writeLeftTop( $image );

Ilyen módon elértük, hogy rugalmasan, és gyorsan tudjunk reagálni a megváltozott üzelti igényekre.

További felhasználás

Utolsó példaként bemutatom, hogy az objektum példányt mennyire könnyű egy új funkció bevezetésére használni.

Itt egyszerűen a kép kimenti állományának nevét, valamint a szöveget felhasználva generálok IMG taget a kép böngészőbe való beillesztéséhez.

Az új kép a PHP mellé, az aktuális könyvtárba kerül.

(Itt sem a teljes minta kidolgozása a cél, emiatt a forrás további refaktorálást igényelhet.)

class imageWidthText {
  public $text = null;
  
  public $size = 10;
  
  public $distance = 10;
  
  public $imageFilePathSource;
  public $imageFileNameDestination;
     public function __construct( $imageFilePathSource, $text, $size = null ) {     $this -> imageFilePathSource = $imageFilePathSource;     $this -> size = 20 < $size ? 20 : $size;     $this -> text = $text.' - develop.blog.hu';   } } class myImageWrite {   public static function writeLeftTop( imageWidthText &$object ) {     $image = new myImage( $object -> imageFilePathSource, $object -> size );          $image -> writeLeftTop( $object -> text, $object -> distance );          $object -> imageFileNameDestination = 'mintakep_output.jpg';
         $image -> save( $object -> imageFileNameDestination );   }   public static function get( imageWidthText &$object ) {
    echo '<img alt="'.$object -> text.'" title="'.$object -> text.'" src="'.$object -> imageFileNameDestination.'" />';   }
} $image = new imageWidthText( 'c:\mintakep.jpg', 'árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP', 10 ); myImageWrite::writeLeftTop( $image ); myImageWrite::get( $image );

Tanulság

Az objektumparaméterek használata első ránézésre feleslegesnek tűnhet, és 2-3 paraméterig valószínűleg nem is feltételen szükséges.

Több paraméter, vagy összetartozó paraméterek egyszerűsítésére viszont kiválóan alkalmas, ugyanúgy, ahogy az üzleti logikával való kiegészítésre is.

Ilyen módon a kód érintett részét meg tudjuk tisztítani a nem az adott kontextusba illő kódrészletektől, ezáltal is tisztább, átláthatóbb kódot kapunk.

Egy esetleges új paraméter bevezetése az objektumparaméterrel már valóban egyszerű, mivel csak egy új adattagot kell felvenni, így a paraméterek száma nem változik, torábbra is 1 lesz.

Az objektumparaméter használatával - már csak az objektum volta miatt is -, ismét csak rugalmasabban módosítható kódot kapunk, így egy továbbfejlesztés esetén további erőforrások takaríthatóak meg.

2 komment

Címkék: refactoring paraméterátadás egyszerűsítése objektum paraméter metódus hívások egyszerűsítése

A bejegyzés trackback címe:

https://develop.blog.hu/api/trackback/id/tr512705901

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

gphilip · http://search-download.com 2011.03.08. 23:42:09

Végülis mi a lényege ennek a dolognak itt? Az biztos, hogy kapsz vele egy kis overheadet meg olvashatatlan kódot :)

Ha egy metódusnak túl sok paramétere van, akkor valószínűleg magával a metódussal van a baj, és a paraméterek "láthataltanná tétele" valójában semmit nem old meg.

Legalábbis én így gondolom :)

Ja, és "Annyit tettem még, hogy az objektumparamétert - bár nem végzek rajta műveletet -, cím szerint fogadtam. (Így az objektumból nem keletkezik másolat, vagyis spóroltunk némi erőforrást.)"

PHP5-től ez implicit így zajlik, nincs rá szükség itt.

fidesz = házmesterek pártja 2011.05.21. 07:22:20

Kissé kötekedés jelleggel (refactoring témában kerestem olvasnivalót, úgy keveredtem ide):

"A fix értékek módosítására közvetlenül ne is adjunk lehetőséget, mivel így tovább tudjuk csökkenteni a kód bonyolultságát."
Ez szép és jó, bár a konkrét példában nem értek egyet a fix értékekkel, de... Ha nem módosítható értket tárolsz, akkor miért nem const-ként definiálod őket?
süti beállítások módosítása