Apa itu Pola Desain Pabrik di PHP?

90

Ini membingungkan saya, dalam istilah yang paling sederhana apa fungsinya? Anggaplah Anda sedang menjelaskan kepada ibu Anda atau seseorang yang hampir membuat Anda senang.

JasonDavis
sumber
116
Ibuku tidak akan memahaminya ...
Bruno Reis
6
@JasonDavis Saya terus menjawab pertanyaan Anda ... Saya mulai merasa seperti penguntit.
Tyler Carter

Jawaban:

176

Sebuah pabrik menciptakan sebuah benda. Jadi, jika Anda ingin membangun

 class A{
    public $classb;
    public $classc;
    public function __construct($classb, $classc)
    {
         $this->classb = $classb;
         $this->classc = $classc;
    }
  }

Anda tidak ingin bergantung pada keharusan melakukan kode berikut setiap kali Anda membuat objek

$obj = new ClassA(new ClassB, new Class C);

Di situlah pabrik akan masuk. Kami menentukan pabrik untuk mengurusnya bagi kami:

class Factory{
    public function build()
    {
        $classc = $this->buildC();
        $classb = $this->buildB();
        return $this->buildA($classb, $classc);

    }

    public function buildA($classb, $classc)
    {
        return new ClassA($classb, $classc);
    }

    public function buildB()
    {
        return new ClassB;
    }

    public function buildC()
    {
        return new ClassC;
    }
}

Sekarang yang harus kita lakukan adalah

$factory = new Factory;
$obj     = $factory->build();

Keuntungan sebenarnya adalah ketika Anda ingin mengubah kelas. Katakanlah kita ingin lulus di ClassC yang berbeda:

class Factory_New extends Factory{
    public function buildC(){
        return new ClassD;
    }
}

atau ClassB baru:

class Factory_New2 extends Factory{
    public function buildB(){
        return new ClassE;
    }
}

Sekarang kita dapat menggunakan pewarisan untuk dengan mudah memodifikasi cara kelas dibuat, untuk dimasukkan ke dalam kumpulan kelas yang berbeda.

Contoh yang bagus mungkin adalah kelas pengguna ini:

class User{
    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
}

Di kelas ini $dataadalah kelas yang kita gunakan untuk menyimpan data kita. Sekarang untuk kelas ini, katakanlah kita menggunakan Sesi untuk menyimpan data kita. Pabrik akan terlihat seperti ini:

class Factory{
    public function build()
    {
        $data = $this->buildData();
        return $this->buildUser($data);
    }

    public function buildData()
    {
        return SessionObject();
    }

    public function buildUser($data)
    {
        return User($data);
    }
}

Sekarang, katakanlah kita ingin menyimpan semua data kita di database, sangat mudah untuk mengubahnya:

class Factory_New extends Factory{
    public function buildData()
    {
        return DatabaseObject();
    }
}

Pabrik adalah pola desain yang kami gunakan untuk mengontrol cara kami menyatukan objek, dan menggunakan pola pabrik yang benar memungkinkan kami membuat objek yang disesuaikan yang kami butuhkan.

Tyler Carter
sumber
3
Itu banyak mengetik. Sekarang saya harus meletakkannya di wiki saya di beberapa titik.
Tyler Carter
1
Baik dan bermanfaat. Angkat topi untuk Anda sobat.
stefgosselin
1
Apa perbedaan / manfaat dari kode Anda $obj = $factory->build();lebih $obj = new whateverClass();? Juga, di kelas lain (katakanlah classZ) yang bergantung pada data classA, di mana di classZ Anda akan menggunakan metode pabrik? Anda pada dasarnya masih membuat instance kelas (classZ) di dalam kelas (classA), yang berarti tidak ada pengujian. misalnya pabrik sepertinya hanya memuat kode yang harus dilakukan newmelalui suatu metode daripada hanya menggunakan new.
Yakobus
Ini membingungkan saya. Saya telah membaca tentang pabrik dan pembangun selama satu jam terakhir dan ini tampak seperti pembangun, bukan pabrik.
akinuri
19

Seperti pabrik kehidupan nyata, itu menciptakan sesuatu dan mengembalikannya.

Bayangkan sesuatu seperti ini

$joe = new Joe();
$joe->say('hello');

atau metode pabrik

Joe::Factory()->say('hello');

Penerapan metode pabrik akan membuat instance baru dan mengembalikannya.

alex
sumber
1
Contoh yang bagus, membuat saya takjub betapa beragamnya penerapan untuk pola ini. Ketika dipanggil secara statis, saya berasumsi seseorang bisa mendapatkan referensi ke instance untuk menggunakan kembali instance yang sama nanti? yaitu $ joe = Joe :: Factory () -> say ('hello');
stefgosselin
tentu saja seperti pada 5.6 yang juga bisa dilakukan (new Joe ()) -> say ('hello');
Pancho
15

Pola desain pabrik sangat baik ketika Anda berurusan dengan banyak sumber daya dan ingin menerapkan abstraksi tingkat tinggi.

Mari kita pecahkan ini menjadi bagian yang berbeda.

Misalkan Anda harus mengimplementasikan abstraksi dan pengguna kelas Anda tidak perlu peduli tentang apa yang telah Anda terapkan dalam definisi kelas.

Dia / Dia hanya perlu khawatir tentang penggunaan metode kelas Anda.

misalnya Anda memiliki dua database untuk proyek Anda

class MySQLConn {

        public function __construct() {
                echo "MySQL Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your mysql select query execute here" . PHP_EOL;
        }

}

class OracleConn {

        public function __construct() {
                echo "Oracle Database Connection" . PHP_EOL;
        }

        public function select() {
                echo "Your oracle select query execute here" . PHP_EOL;
        }

}

Kelas Pabrik Anda akan menangani pembuatan objek untuk koneksi database.

class DBFactory {

        public static function getConn($dbtype) {

                switch($dbtype) {
                        case "MySQL":
                                $dbobj = new MySQLConn();
                                break;
                        case "Oracle":
                                $dbobj = new OracleConn();
                                break;
                        default:
                                $dbobj = new MySQLConn();
                                break;
                }

                return $dbobj;
        }

}

Pengguna hanya perlu memasukkan nama tipe database

$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();

Keluaran:

MySQL Database Connection
Your mysql select query execute here

Di masa depan Anda mungkin memiliki database yang berbeda maka Anda tidak perlu mengubah seluruh kode hanya perlu melewati tipe database baru dan kode lain akan berjalan tanpa melakukan perubahan apa pun.

$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();

Keluaran:

Oracle Database Connection
Your oracle select query execute here

Semoga ini bisa membantu.

Shailesh Sonare
sumber
1

Secara umum, sebuah "pabrik" menghasilkan sesuatu: dalam kasus Pemrograman Berorientasi Objek, sebuah "pola desain pabrik" menghasilkan objek.

Tidak masalah apakah itu dalam PHP, C # atau bahasa Berorientasi Objek lainnya.

Pindatjuh
sumber
1

Pola Desain Pabrik (Pola Pabrik) adalah untuk sambungan longgar. Seperti pengertian pabrik, data ke pabrik (menghasilkan data) hingga pengguna akhir. Dengan cara ini, pabrik memutuskan hubungan erat antara sumber data dan proses data.

N Zhang
sumber
0

Jawaban ini terkait dengan posting lain di mana Daniel White mengatakan menggunakan pabrik untuk membuat koneksi MySQL menggunakan pola pabrik.

Untuk koneksi MySQL saya lebih suka menggunakan pola tunggal karena Anda ingin menggunakan koneksi yang sama untuk mengakses database, bukan membuat database lain.

Marcin - pengguna2676388
sumber
0

Pendekatan klasik untuk membuat instance objek adalah:

$Object=new ClassName();

PHP memiliki kemampuan untuk membuat objek secara dinamis dari nama variabel menggunakan sintaks berikut:

$Object=new $classname;

di mana variabel $ classname berisi nama kelas yang ingin dibuat instance-nya.

Jadi pemfaktoran objek klasik akan terlihat seperti ini:

function getInstance($classname)
{
  if($classname==='Customer')
  {
    $Object=new Customer();
  }
  elseif($classname==='Product')
  {
    $Object=new Product();
  }
  return $Object;
}

dan jika Anda memanggil fungsi getInstance ('Product'), pabrik ini akan membuat dan mengembalikan objek Produk. Jika tidak, jika Anda memanggil fungsi getInstance ('Customer'), pabrik ini akan membuat dan mengembalikan objek tipe Pelanggan (dibuat dari kelas Customer ()).

Tidak perlu lagi, seseorang dapat mengirim 'Produk' atau 'Pelanggan' (nama persis dari kelas yang ada) sebagai nilai variabel untuk instance dinamis:

$classname='Product';
$Object1=new $classname; //this will instantiate new Product()

$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
sbrbot.dll
sumber
0

Sebagai catatan, dengan kata mudah, pabrik seperti @Pindatjuh mengatakan, mengembalikan sebuah objek.

Jadi, apa bedanya dengan konstruktor? (itu sama)

  1. konstruktor menggunakan instance-nya sendiri.
  2. Sesuatu yang saya ingin jadi sesuatu yang lebih maju dan saya tidak ingin membengkak objek (atau menambahkan ketergantungan).
  3. Pembuat dipanggil ketika setiap instance dibuat. Terkadang Anda tidak menginginkannya.

    Sebagai contoh, katakanlah setiap kali saya membuat objek akun kelas, saya membaca file dari database dan menggunakannya sebagai templat.

Menggunakan konstruktor:

class Account {
      var $user;
      var $pwd;
      var ...
      public __construct() {
         // here i read from the file
         // and many other stuff
      }
}

Menggunakan pabrik:

class Account {
      var $user;
      var $pwd;
      var ...
}
class AccountFactory {
      public static Create() {
         $obj=new Account();
         // here we read the file and more stuff.
         return $obj;
      }
magallanes
sumber