Monday, February 22, 2010

Asosiasi antar obyek di PHP

Apa itu agregasi apa itu komposisi? aggregasi itu salah satu bentuk asosiasi antar objekt... asosiasi object ada 2 macam. yang pertama dibilangnya "komposisi" yang kedua "agregasi"... UML notasinya bisa dilihat di wiki itu kalo komposisi node diamond nya itu diisi, kalau aggregasi itu kosong.

sekarang "asosiasi object" itu menjelaskan apa?

asosiasi object itu menjelaskan object X itu butuh atau menggunakan atau dibentuk dari object apa saja.

apakah asosiasi tersebut jenisnya "komposisi" atau "agregasi" ini dilihat dari ketergantungan object x tersebut sama object lainnya.

komposisi:
Object x "terdiri dari / dibentuk oleh / dibangun dengan / membutuhkan" object y, object z, dst... tanpa object y, object z, dst.. tersebut.. object x tidak bisa exist. atau dengan kata lain existensinya tidak berarti.. (oh apalah artinya hidup ini)

contoh ngasal dari wiki... object mobil terdiri dari object mesin, object ban, object gearbox, dst....

agregasi:
Object x "bisa memiliki / menggunakan" object y, object z, dst... tanpa object y, object z, dst.. tersebut object x tetap bisa exist.

contoh ngasal dari wiki... object danau bisa memiliki object bebek, object perahu dst...

ok sekarang kita masuk ke contoh aja deh ya...
class ProductModel {
  
  private $f1;
  
  public function setF1(F1 $f1) {
    $this->f1 = $f1;
  }
  
  
  public function getF1() {
    return $this->f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this->f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}

object ProduktModel bergantung gak sama object F1? nggak, soalnya gue bisa menciptakan object ProduktModel tanpa object F1,

misalnya
$productModel = new ProduktModel();

gue juga bisa menciptakan object F1 tanpa object ProduktModel misalnya
$f1 = new F1();

gue bisa bikin object ProductModel berasosiasi sama object F1 misalnya
$productModel->setF1($f1);

so.. jenis asosiasi apakah ini? maka jawabannya "agregasi";

contoh berikut:
class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1){
    $this->f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this->f1 = $f1;
  }
  
  
  public function getF1() {
    return $this->f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this->f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}

object ProductModel bergantung gak sama object F1? iya.. coba sekarang bikin object ProductModel tanpa object F1,
$productModel = new ProductModel();

gak bisa.. karena dalam penciptaannya (konstruksi nya) butuh object F1. maka:
$productModel = new ProductModel(new F1());

so.. jenis asosiasi apakah ini? maka jawabannya komposisi.

contoh lagi
abstract class ProductDAO {
  
  public static function create(ProductModel $product) {
    if ($dsn->query("INSERT INTO product (f1,f2,f3) 
                     VALUES ('{$product->getF1()}','{$product->getF2()}','{$product->getF3()}')")) {
      return true;
    } else {
      return false;
    }
  }
  
}

so.. kelas ProductDAO dalam hal ini abstract... entah dimana mestinya ada implementasi konkritnya.. tapi gak usah dibahas dulu. dalam hal ini tidak akan ada yang namanya object ProductDAO, karena sifatnya yang abstrak, kita gak bisa instantiate (baca koreksi gue di atas).

tapi kelas ProductDAO punya static method namanya create. methode ini butuh object ProductModel. kalo lo mo pake methode ini loe harus sertakan object ProductModel. misal:
$productModel = new ProductModel();
ProductDAO::create($productModel);

so.. jenis asosiasi apakah ini?.. ini sebenarnya asosiasi "komposisi" akan tetapi yang berasosiasi bukan antara object dengan object tapi static method dengan object...

kalo baca di wiki lebih lanjut... pada object yang memiliki asosiasi "komposisi"... apabila Object x dihancurkan, maka object y, object z, dst.. juga ikut hancur. sedangkan pada agregasi, apabila object x dihancurkan, maka object y, object z, dst... "bisa" tetap exist, karena tidak tergantung satu sama lain.

statement ini dalam OOP buat gue (kalo ada yang punya pendapat lain silahkan komentar) gak absolut. mungkin bisa gue jelaskan dalam contoh..

gue ambil contoh asosiasi komposisi seeperti diatas:
class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1){
    $this->f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this->f1 = $f1;
  }
  
  
  public function getF1() {
    return $this->f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this->f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}

so.. kalau kita menciptakan object ProductModel seperti contoh gue diatas,
$productModel = new ProductModel(new F1());

maka statement wiki tersebut benar. apabila object $productModel gue hancurkan, maka object F1 juga ikut hancur. misal
unset($productModel);

akan tetapi bagaimana kalau begini : ?
$f1 = new F1();
$productModel = new ProductModel($f1);

pada dasarnya object ProductModel tetap memiliki asosiasi komposisi terhadap object F1 (tidak bisa eksis tanpa F1) akan tetapi apabila objectProductModel kita hancurkan, object F1 tetap eksis, karena variabel $f1 masih punya reference ke object F1:
unset($productModel);
//object F1 masih exist... ga percaya?
var_dump($f1);

dengan ini statement tersebut tidak benar... statement tersebut kayaknya berlaku untuk bahasa2 seperti C, karena definisi asosiasi sendiri sudah ada lama jauh sebelum object oriented paradigma (betulkah begitu?... gue butuh dukungan atau komentar atas hal ini :D )

2 contoh lagi buat direnungkan atau di diskusikan:

contoh 1:
class ProductModel {
  
  private $f1;
  
  function __construct(F1 $f1 = null){
    $this->f1 = $f1;
  }
  
  public function setF1(F1 $f1) {
    $this->f1 = $f1;
  }
  
  
  public function getF1() {
    return $this->f1;
  }
  
}

class F1{
  private $f1;
  
  function setF1($f1){
    $this->f1 = $f1;
  }
  
  function getF1(){
    return $f1;
  }
}

pada snipets diatas.. constructor parameternya gue kasih default value (dalam hal ini default value null) berarti sekarang object ProductModel sudah tidak bergantung lagi sama object F1. Karena gue sekarang bisa menciptakan object ProductModel tanpa F1:
$productModel = new ProductModel();

berarti sekarang asosiasinya agregasi dong :D

contoh 2:
abstract class ProductDAO {
  
  public static function create(ProductModel $product = null) {
    if ($dsn->query("INSERT INTO product (f1,f2,f3) 
                     VALUES ('{$product->getF1()}','{$product->getF2()}','{$product->getF3()}')")) {
      return true;
    } else {
      return false;
    }
  }
  
}

sama seperti contoh 1, hanya saja kali ini bukan object tapi static method.

pada dasarnya gue "bisa" memanggil static method create tanpa menyertakan object ProductModel karena parameternya kita kasih default value (lagi2 null).. :
ProductDAO::create();

akan tetapi kalo lo liat pada implementasi create, disitu object $product gue pake.
.... VALUES ('{$product->getF1()}','{$product->getF2()}',' .....

meskipun "tidak harus" menyertakan object ProductModel, methode tersebut tidak bisa dipakai (existensi nya tidak berarti :D ) karena tetap butuh object ProductModel.

maka dari itu asosiasinya tetap komposisi dong? :D

Pertanyaan dari polutan:
gimana gambar UML nya untuk menyimbolkan bahwa yang berasosiasi bukan antara object dengan object tapi static method dengan object? Semua contoh2 dan yg di Wiki contohnya pasti melewatkan object B melalui konstruktor class A. Apalagi in abstract class dan static method, jd nggak yakin membuat gambarnya spt yg di tutorial2 itu..

UML itu modeling language... sifatnya informatif.. tergantung apa yang mau disampaikan...

lo bisa aja gambar seperti contoh di wiki, misalnya begini:

dengan gambar ini lo udah kasih tahu bahwa "abstract class ProductDAO punya relasi komposisi sama kelas ProductModel." implementasinya gimana itu gak relevan. sifatnya informatif saja.

kalo mo diperjelas dari sisi ProductDAO nya (sesuai pertanyaan elo) ya bisa aja lo bikin begini:

dengan gambar ini lo uda menginformasikan, bahwa "abstract class ProductDAO yang berelasi komposisi dengan kelas ProductModel di implementasikan di public static methode yang namanya create yang memiliki parameter dengan nama product yang type nya ProductModel dan returnnya Boolean."

ini pun sifatnya informatif saja, alias yang ga relevan ga dikasih liat. buktinya ProductModel gak gue isi member variabelnya apa, dan methodnya apa aja.

semuanya tergantung apa yang mo lo sampaikan atau informasikan.

kalo bingung kenapa dengan gambar seperti itu bisa tahu kalau kelasnya abstract atau methodnya public static.

No comments: