Design Pattern pada PHP (Bagian 2)

Design Pattern pada PHP (Bagian 2)

Tutorial Information

ProgramPHP
Version5.0+
DifficultyPemula - Standar
Estimated Time15 menit

Pada artikel sebelumnya, Penulis telah menjelaskan tentang asal-usul design pattern dan juga 3 contoh design pattern yang umum digunakan. Padahal sebenarnya ada sangat banyak…

Pada artikel sebelumnya, Penulis telah menjelaskan tentang asal-usul design pattern dan juga 3 contoh design pattern yang umum digunakan. Padahal sebenarnya ada sangat banyak design pattern, seiring dengan perkembangan ilmu pemrograman berikut bahasanya yang semakin canggih. Dalam artikel kali ini, Penulis kembali membahas tentang design pattern, yaitu 4 contoh design pattern lain yang sering digunakan.

Artikel ini pernah dipublikasikan oleh Penulis di majalah PC Media edisi 02/2011 lalu.

Chain-Command Pattern

Pattern ini digunakan untuk mengatur jalannya (routing) perintah, pesan, request, atau apapun melalui sekumpulan handler. Setiap handler memiliki informasi perintah apa saja yang dapat dia lakukan. Kuncinya ada pada sebuah class yang menjadi tempat kumpulan handler tersebut. Anda bisa menambahkan atau menghapus handler dari sistem/class tersebut tanpa berdampak pada handler lainnya.

Contoh kode program untuk pattern ini adalah sebagai berikut.

<?php
// interface untuk command
interface ICommand {
  function onCommand($name, $args);
}

// class kunci untuk command chain
class CommandChain {
  private $_commands = array();

  public function addCommand($cmd) {
    $this->_commands[] = $cmd;
  }

  public function runCommand($name, $args) {
    foreach($this->_commands as $cmd) {
      if($cmd->onCommand($name, $args)) {
        return;
      }
    }
    // ketika tidak ada handler yang sesuai
    echo 'No registered found, command is not executed<br />';
  }
}

// command untuk user
class UserCommand implements ICommand {
  public function onCommand($name, $args) {
    if($name != 'addUser') {
      return false;
    }
    // perintah dijalankan di baris ini
    echo 'UserCommand handling \'addUser\'<br />';
    return true;
  }
}

// command untuk item
class ItemCommand implements ICommand {
  public function onCommand($name, $args) {
    if($name != 'addItem') {
      return false;
    }
    // perintah dijalankan di baris ini
    echo 'ItemCommand handling \'addItem\'<br />';
    return true;
  }
}

$cc = new CommandChain();
$cc->addCommand(new UserCommand());
$cc->addCommand(new ItemCommand());
$cc->runCommand('addUser', null);
$cc->runCommand('addItem', null);
$cc->runCommand('mail', null);

Pada contoh di atas terdapat satu interface untuk handler dan dua class yang menggunakan interface tersebut. Kedua class yang berfungsi sebagai handler tersebut memiliki command yang berbeda. Sedangkan untuk menjalankan command, harus dilakukan dengan object dari class CommandChain. Ketika Anda menjalankan program di atas, maka output yang dihasilkan adalah.

UserCommand handling 'addUser'
ItemCommand handling 'addItem'
No registered found, command is not executed

Pattern ini sangat bermanfaat jika Anda ingin membuat arsitektur pemrosesan request yang fleksible dan dapat diperbesar lingkupnya. Untuk struktur UML-nya seperti pada gambar. Desain UML untuk pattern ini dapat dilihat pada gambar.

Desain UML Chain-Command Pattern

Adapter Pattern

Pattern yang satu ini digunakan ketika Anda ingin mengubah suatu object dengan tipe tertentu, menjadi object dengan tipe lain. Jika Anda tidak mengerti tentang design pattern yang baik, maka kemungkinan Anda akan melakukan seperti kode di bawah ini.

<?php
class Item {
  private $_itemType;
  private $_itemName;

  public function setItemType($type) {
    $this->_itemType = $type;
  }

  public function getItemType() {
    return $this->_itemType;
  }

  public function setItemName($name) {
    $this->_itemName = $name;
  }

  public function getItemName() {
    return $this->_itemName;
  }
}

// class food tanpa hubungan dengan item
class Food {
  private $_foodName;

  public function setFoodName($food) {
    $this->_foodName = $food;
  }

  public function getFoodName() {
    return $this->_foodName;
  }
}

$item = new Item();
// membuat object food
$food = new Food();
$food->setFoodName('butter');
// memasukkan nilai, mengubah item menjadi food
$item->setItemType('food');
$item->setItemName($food->getFoodName());

echo $item->getItemType() . '<br />';
echo $item->getItemName();

Coba Anda perhatikan pada baris bagian akhir. Melakukan pengubahan satu-persatu property akan cukup menyulitkan jika ada banyak property yang harus direferensikan.

Implementasi pattern adapter akan membuat programmer tidak perlu mengetahui bagaimana class Food diubah menjadi class Item. Keuntungan utama dari desain seperti ini adalah menghindari pengubahan yang besar pada source code jika terjadi perubahan fitur atau desain class. Karena itu, penulisan kode dengan pattern adapter ini akan lebih efisien, seperti kode di bawah ini.

// gunakan class Item dan Food pada listing sebelumnya
<?php
class FoodToItemAdapter extends Item {
  public function __construct($food) {
    $this->setItemType('food');
    $this->setItemName($food->getFoodName());
  }
}

$food = new Food();
$food->setFoodName('Chicken Teriyaki');

$item = new FoodToItemAdapter($food);

echo $item->getItemType() . '<br />';
echo $item->getItemName();

Output yang dihasilkan akan sama dengan listing sebelumnya. Kelebihannya akan benar-benar terlihat dan terasa saat dalam program terjadi banyak perubahan tipe object dari food ke item seperti listing di atas ini. Desain UML untuk pattern ini dapat Anda lihat pada gambar.

Desain UML Adapter Pattern

Prototype Pattern

Seperti namanya, ide dari pattern ini adalah membuat sebuah prototype yang kemudian akan digandakan sesuai kebutuhan. Prinsipnya mirip dengan Factory Pattern, bahwa ini akan bermanfaat untuk membuat sebuah object dengan inisialisasi property awal yang sebagian besar sama. Jika Anda menggunakan cara biasa dengan membuat sekian object dari suatu class, kemudian mengatur nilai property-nya satu persatu di mana property tersebut bernilai sama (semisal membuat object dengan ukuran yang sama), maka akan ada banyak perulangan kode yang sia-sia, seperti kode di bawah ini.

<?php
// class utama
class Robot {
  private $_name;
  private $_type;

  public function setType($type) {
    $this->_type = $type;
  }

  public function getType() {
    return $this->_type;
  }

  public function setName($name) {
    $this->_name = $name;
  }

  public function getName() {
    return $this->_name;
  }
}

// perulangan yang tidak perlu
$aibo1 = new Robot();
$aibo2 = new Robot();
$aibo3 = new Robot();
$aibo1->setType('aibo');
$aibo2->setType('aibo');
$aibo3->setType('aibo');

Jika hanya membuat 3 object saja, mungkin tidak terlalu terasa. Tapi bayangkan jika Anda perlu membuat seribu object dengan beberapa property yang sama. Jika Anda mengeset-nya satu-persatu seperti di atas, ketika ada perubahan nilai property yang sama tersebut, Anda harus mengubah semuanya secara manual. Beruntung jika Anda bisa melakukan refactor dengan IDE kesayangan Anda. Tapi itu juga bukan solusi yang bagus.

Selain menggunakan Factory Pattern, Anda bisa menggunakan Prototype Pattern untuk mengatasi masalah tersebut. Keuntungannya, jika Ada property yang ingin diubah, Anda cukup menggantinya pada prototype maka semua property object yang menggunakan prototype tersebut akan ikut terganti. Salah satu implementasi Prototype Pattern adalah seperti di bawah ini.

<?php
// gunakan class Robot di atas juga
// prototype untuk aibo
class RobotAiboPrototype extends Robot {
  public function __construct() {
    $this->setType('aibo');
  }

  public function __clone() {
    // lakukan apapun saat proses cloning
  }
}

// test program
// buat prototype
$aibo_prototype = new RobotAiboPrototype();
// prototype tanpa class
$asimo_prototype = new Robot();
$asimo_prototype->setType('asimo');

// clone aibo
$aibo1 = clone $aibo_prototype;
$aibo2 = clone $aibo_prototype;
$aibo1->setName('Aibo 1');
$aibo2->setName('Aibo 2');
echo 'Tipe '.$aibo1->getType().' Nama '.$aibo1->getName().'<br />';
echo 'Tipe '.$aibo2->getType().' Nama '.$aibo2->getName().'<br />';

// clone asimo
$asimo1 = clone $asimo_prototype;
$asimo2 = clone $asimo_prototype;
$asimo1->setName('Asimo 1');
$asimo2->setName('Asimo 2');
echo 'Tipe '.$asimo1->getType().' Nama '.$asimo1->getName().'<br />';
echo 'Tipe '.$asimo2->getType().' Nama '.$asimo2->getName().'<br />';

Dengan demikian, Anda tetap memiliki instance dari class Robot namun dengan property yang sama untuk object-object dengan prototype yang sama. Kunci lainnya adalah pada fungsi clone yang disediakan dalam bahasa PHP. Dengan fungsi tersebut, tanpa membuat class untuk prototype pun, pattern ini tetap dapat berjalan. Output program di atas adalah sebagai berikut.

Tipe aibo Nama Aibo 1
Tipe aibo Nama Aibo 2
Tipe asimo Nama Asimo 1
Tipe asimo Nama Asimo 2

Pattern ini memiliki desain UML seperti gambar.

Desain UML Prototype Pattern

MVC

Pattern terakhir ini cukup kompleks, namun merupakan pattern yang cukup banyak dipakai, terutama dalam pembuatan-pembuatan framework PHP. MVC adalah singkatan dari Model-View-Controller. Seperti namanya, komponen utama dalam MVC ini adalah Model, View, dan Controller.

Ide dan tujuan utama dari penggunaan pattern MVC adalah memisahkan komponen business logic dari tampilan atau user interface, sehingga diharapkan dapat memudahkan proses modifikasi suatu bagian tanpa mempengaruhi bagian yang lainnya. Dalam MVC, model akan menjadi representasi data atau informasi dari sebuah aplikasi; view akan menjadi komponen yang berkaitan dengan tampilan; dan controller akan menjadi pengatur komunikasi yang terjadi dan juga aturan-aturan proses untuk memanipulasi data dari dan menuju model, yang kemudian ditampilkan dalam view.

Diagram Ilustrasi Model-View-Controller Pattern

Saat ini PHP juga telah mendukung pola desain MVC, dengan memanfaatkan fitur OOP (Object Oriented Programming) yang ada di dalamnya. Jika MVC dijelaskan secara sederhana dalam PHP, maka model adalah bagian yang meng-handle keseluruhan proses database. Model akan menghubungkan aplikasi ke database, dan juga berfungsi sebagai lapisan abstraksi data. View akan mendeskripsikan bentuk tampilan html, css, dan juga javascript di dalamnya. Controller akan menjadi jantung dan otak dari aplikasi MVC, yang tugasnya menghubungkan antara user dengan model dan view.

Dalam dunia web, MVC pertama kali diimpementasikan oleh David Heinemeier Hansson dalam sebuah framework bahasa Ruby, yaitu Ruby on Rails. Karena desainnya yang sangat baik, pola tersebut diimplementasikan pula pada bahasa pemrograman web lainnya, salah satunya adalah PHP.

Untuk menjabarkan bagaimana cara kerja MVC ini akan cukup panjang, karena itu tidak akan dijelaskan dalam artikel ini. Namun jika Anda tertarik untuk mendalami pattern ini dan mencoba membuat sendiri framework MVC dengan PHP, Anda bisa membaca artikel penulis di PC Media edisi sebelumnya yang berjudul “Membuat Sendiri Framework PHP MVC”.

Penutup

Dalam 2 artikel penulis ini hanya dibahas beberapa design pattern yang umum digunakan. Masih banyak design pattern yang bisa Anda gunakan sesuai kondisi dan kebutuhan Anda. Ada decorator pattern, iterator pattern, state pattern, dan sebagainya. Anda bisa mencari referensi lebih di internet, terutama di forum-forum developer PHP. Anda juga bisa mempelajari design pattern bahasa pemrograman lain untuk diterapkan pada PHP ini. Selamat mencoba. :D

Sumber dan Referensi Tambahan:

  • http://www.ibm.com/developerworks/library/os-php-designptrns/
  • http://www.ibm.com/developerworks/opensource/library/os-php-designpatterns/
  • http://www.phpro.org/tutorials/Design-Patterns.html
  • http://www.fluffycat.com/PHP-Design-Patterns/
Artikel ini pernah dipublikasikan oleh Penulis di majalah PC Media edisi 02/2011 lalu.
Tag: , , , , , , ,

5 Comments

Leave Comment
  1. Rizki Imam Andreas says:

    Akhirnya dapet ilmu lagi tentang design pattern ,, lanjutkan mas haqqi (Y)

  2. Haqqi says:

    Wah, terima kasih atas komentarnya. Tapi sayang sekali tidak menggunakan email asli Anda, sehingga tidak bisa terkirim notifikasi komentar balasan ini. Semoga Anda membaca komentar balasan saya.

    Saya ingin klarifikasi, bahwa saya tidak sekedar menerjemahkan. Memang saya salah bahwa tidak menyertakan link tersebut sebagai sumber, karena memang saya mengambilnya dari banyak sumber, termasuk dari dokumentasi PHP sendiri. Jadi tidak bisa dibilang bahwa tulisan saya menjiplak. Bahkan diagramnya saya bikin sendiri dengan tool Visual Paradigm. Mungkin memang mirip, karena saya ingin menggunakan standar pattern yang benar. Jadi tidak bisa dibilang bahwa saya mencuri. Sekali lagi saya hanya ingin mengklarifikasi. Terima kasih.

  3. Haqqi says:

    Sebagai contoh, coba Anda lihat pada pattern Singleton di part sebelumnya. Di situ saya tuliskan singleton yang biasa saya pakai, bukan mengambil contoh dari artikel yang Anda beri link-nya. Di link yang Anda berikan hanya 5 common design pattern, sementara saya menjelaskan 7 design pattern. Setiap design pattern selalu saya coba secara langsung, dan saya tulis contohnya, entah mirip atau beda sama sekali. Yang pasti, karena design pattern adalah pola umum, sebagian besar pasti mirip, diubah seperti apa pun bentuk variable-nya. CMIIW.

Write Comment

Your email will not be published. The marked label is required.