Pola Pabrik. Kapan harus menggunakan metode pabrik?

Jawaban:

386

Saya suka berpikir tentang pola desain dalam hal kelas saya menjadi 'orang,' dan polanya adalah cara orang berbicara satu sama lain.

Jadi, bagi saya pola pabrik seperti agen perekrutan. Anda memiliki seseorang yang membutuhkan sejumlah pekerja variabel. Orang ini mungkin mengetahui beberapa informasi yang mereka butuhkan pada orang yang mereka sewa, tetapi hanya itu.

Jadi, ketika mereka membutuhkan karyawan baru, mereka memanggil agen perekrutan dan memberi tahu mereka apa yang mereka butuhkan. Sekarang, untuk benar-benar merekrut seseorang, Anda perlu mengetahui banyak hal - manfaat, verifikasi kelayakan, dll. Tetapi orang yang direkrut tidak perlu mengetahui semua ini - agen perekrutan menangani semua itu.

Dengan cara yang sama, menggunakan Pabrik memungkinkan konsumen untuk membuat objek baru tanpa harus mengetahui detail bagaimana mereka dibuat, atau apa dependensi mereka - mereka hanya harus memberikan informasi yang mereka inginkan.

public interface IThingFactory
{
    Thing GetThing(string theString);
}

public class ThingFactory : IThingFactory
{
    public Thing GetThing(string theString)
    {
        return new Thing(theString, firstDependency, secondDependency);
    }
}

Jadi, sekarang konsumen ThingFactory bisa mendapatkan Thing, tanpa harus tahu tentang ketergantungan Thing, kecuali untuk data string yang berasal dari konsumen.

Kyoryu
sumber
17
Di mana implementasi konkret GetThing () mengambil nilai firstDependency dan secondDependency?
Mikeyg36
88
Bisakah seseorang memberi tahu saya bagaimana ini menjawab pertanyaan OP? Ini hanya menggambarkan apa 'Pola Pabrik' dan kemudian menambahkan contoh 'Metode Pabrik', yang hanya salah satu dari tiga 'Pola Pabrik'. Dengan kata lain, saya tidak melihat perbandingan di mana pun.
Forethinker
4
Pertanyaan OP jelas menyebutkan within an object instead of a Factory class. Saya pikir dia maksudkan skenario di mana Anda membuat ctor pribadi dan menggunakan metode statis untuk membuat instance kelas (membuat objek). Tetapi untuk mengikuti contoh ini kita harus instantiate ThingFactorykelas terlebih dahulu untuk mendapatkan Thingobjek, yang membuat ini Factory classberlaku.
atiyar
4
Maaf, tetapi penjelasannya omong kosong, karena konstruktor juga dapat ditulis dengan cara menyembunyikan dependensi. Informasi latar belakang utama yang ingin Anda pisahkan informasi pembuatan ketergantungan dari manajemen ketergantungan tidak ada. Selain itu, pertanyaannya adalah tentang di dalam kelas yang sama, jawabannya tidak ada hubungannya dengan itu.
Christian Hujer
8
OP bertanya kapan . Kyoryu menjawab bagaimana . Meskipun gaya jawabannya patut dipuji, dalam konteks pertanyaan ini, itu hanyalah suara berisik.
8bitjunkie
96

Metode pabrik harus dianggap sebagai alternatif untuk konstruktor - kebanyakan ketika konstruktor tidak cukup ekspresif, yaitu.

class Foo{
  public Foo(bool withBar);
}

tidak se ekspresif seperti:

class Foo{
  public static Foo withBar();
  public static Foo withoutBar();
}

Kelas pabrik berguna ketika Anda membutuhkan proses rumit untuk membangun objek, ketika konstruksi membutuhkan ketergantungan yang tidak Anda inginkan untuk kelas aktual, ketika Anda perlu membuat objek yang berbeda dll.

Rasmus Faber
sumber
2
Di mana kelas Pabrik di sini?
Koray Tugay
20
@ KorayTugay: Tidak ada kelas pabrik, hanya metode pabrik. Pertanyaannya adalah kapan menggunakan metode pabrik dan bukan kelas pabrik. Tetapi metode pabrik lebih merupakan alternatif untuk konstruktor daripada alternatif untuk kelas pabrik. (Saya tidak tahu mengapa jawaban teratas dinilai sangat tinggi meskipun hanya berbicara tentang kelas pabrik).
Rasmus Faber
5
Perlu dicatat bahwa metode pabrik statis sama sekali berbeda dari Gang of Four: pola desain Metode Pabrik.
jaco0646
76

Satu situasi di mana saya secara pribadi menemukan kelas Pabrik terpisah masuk akal adalah ketika objek terakhir yang Anda coba buat bergantung pada beberapa objek lainnya. Misalnya, di PHP: Misalkan Anda memiliki Houseobjek, yang pada gilirannya memiliki Kitchendan LivingRoomobjek, dan LivingRoomobjek memiliki TVdalam objek juga.

Metode paling sederhana untuk mencapai hal ini adalah membuat setiap objek membuat anak-anak mereka pada metode konstruk mereka, tetapi jika properti relatif bersarang, ketika Housegagal Anda membuat Anda mungkin akan menghabiskan waktu mencoba mengisolasi apa yang gagal.

Alternatifnya adalah dengan melakukan hal berikut (injeksi ketergantungan, jika Anda suka istilah mewah):

$TVObj = new TV($param1, $param2, $param3);
$LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
$KitchenroomObj = new Kitchen($param1, $param2);
$HouseObj = new House($LivingroomObj, $KitchenroomObj);

Di sini jika proses membuat Housegagal hanya ada satu tempat untuk dilihat, tetapi harus menggunakan potongan ini setiap kali seseorang ingin yang baru Housejauh dari nyaman. Masukkan Pabrik:

class HouseFactory {
    public function create() {
        $TVObj = new TV($param1, $param2, $param3);
        $LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
        $KitchenroomObj = new Kitchen($param1, $param2);
        $HouseObj = new House($LivingroomObj, $KitchenroomObj);

        return $HouseObj;
    }
}

$houseFactory = new HouseFactory();
$HouseObj = $houseFactory->create();

Berkat pabrik di sini proses pembuatan Housediabstraksikan (di mana Anda tidak perlu membuat dan mengatur setiap ketergantungan ketika Anda hanya ingin membuat a House) dan pada saat yang sama terpusat yang membuatnya lebih mudah untuk dipertahankan. Ada alasan lain mengapa menggunakan Pabrik yang terpisah dapat bermanfaat (mis. Kemampuan testabilitas) tetapi saya menemukan kasus penggunaan khusus ini untuk mengilustrasikan terbaik bagaimana kelas Pabrik dapat bermanfaat.

Mahn
sumber
1
Bagaimana seseorang melakukan tes unit pada ini? Saya pikir menggunakan kata kunci "baru" di kelas dianggap praktik buruk karena tidak dapat diuji unit. Atau apakah pabrik dimaksudkan untuk menjadi pengecualian terhadap aturan itu?
AgmLauncher
1
@ AggLauncher Saya punya pertanyaan yang sama juga ketika saya mulai dengan pengujian unit, periksa: stackoverflow.com/questions/10128780/…
Mahn
1
Tidak mendapatkan ini Bagaimana tepatnya params untuk membuat objek yang berbeda diteruskan ke HouseFactorykelas?
atiyar
1
@ Ahn, bukankah akhirnya Anda memiliki banyak params pada akhirnya?
Pacerier
1
@Pacerier itu sesuatu bagi Anda untuk memutuskan bagaimana membuat model, tergantung pada kebutuhan Anda, tetapi Anda tidak selalu harus meneruskan setiap parameter ke createmetode. Misalnya, jika Anda Houseakan selalu memiliki jenis yang sama LivingRoommaka mungkin masuk akal untuk memiliki params hardcode di kelas pabrik daripada disahkan sebagai argumen. Atau Anda mungkin ingin memberikan typeargumen untuk HouseFactory::createmetode Anda jika Anda memiliki beberapa jenis LivingRooms dan beralih di dalamnya dengan parameter yang di-hardcode untuk setiap jenis.
Mahn
19

Penting untuk membedakan ide di balik penggunaan pabrik atau metode pabrik. Keduanya dimaksudkan untuk mengatasi berbagai jenis masalah penciptaan objek yang saling eksklusif.

Mari kita lebih spesifik tentang "metode pabrik":

Hal pertama adalah bahwa, ketika Anda sedang mengembangkan perpustakaan atau API yang pada gilirannya akan digunakan untuk pengembangan aplikasi lebih lanjut, maka metode pabrik adalah salah satu pilihan terbaik untuk pola pembuatan. Alasan di balik; Kita tahu bahwa kapan membuat objek dengan fungsionalitas yang diperlukan, tetapi tipe objek akan tetap ragu-ragu atau akan ditentukan berdasarkan parameter dinamis yang dilewati .

Sekarang intinya adalah, kira-kira sama dapat dicapai dengan menggunakan pola pabrik itu sendiri tetapi satu kelemahan besar akan memperkenalkan ke dalam sistem jika pola pabrik akan digunakan untuk masalah yang disorot di atas, itu adalah bahwa logika Anda crating objek yang berbeda (objek kelas sub) akan spesifik untuk beberapa kondisi bisnis sehingga di masa mendatang ketika Anda perlu memperluas fungsionalitas perpustakaan Anda untuk platform lain (Secara lebih teknis, Anda perlu menambahkan lebih banyak sub kelas antarmuka dasar atau kelas abstrak sehingga pabrik akan mengembalikan benda-benda itu juga di samping yang sudah ada berdasarkan beberapa parameter dinamis) maka setiap kali Anda perlu mengubah (memperluas) logika kelas pabrik yang akan menjadi operasi yang mahal dan tidak baik dari perspektif desain. Di sisi lain, jika "metode pabrik"

interface Deliverable 
{
    /*********/
}

abstract class DefaultProducer 
{

    public void taskToBeDone() 
    {   
        Deliverable deliverable = factoryMethodPattern();
    }
    protected abstract Deliverable factoryMethodPattern();
}

class SpecificDeliverable implements Deliverable 
{
 /***SPECIFIC TASK CAN BE WRITTEN HERE***/
}

class SpecificProducer extends DefaultProducer 
{
    protected Deliverable factoryMethodPattern() 
    {
        return new SpecificDeliverable();
    }
}

public class MasterApplicationProgram 
{
    public static void main(String arg[]) 
    {
        DefaultProducer defaultProducer = new SpecificProducer();
        defaultProducer.taskToBeDone();
    }
}
Prakash Chhipa
sumber
15

Mereka juga berguna ketika Anda membutuhkan beberapa "konstruktor" dengan tipe parameter yang sama tetapi dengan perilaku yang berbeda.

Rik
sumber
15

Sebaiknya gunakan metode pabrik di dalam objek saat:

  1. Kelas objek tidak tahu subkelas apa yang harus dibuatnya
  2. Kelas objek dirancang sehingga objek yang dibuatnya ditentukan oleh sub-kelas
  3. Kelas Object mendelegasikan tugasnya ke sub-kelas bantu dan tidak tahu kelas yang tepat akan mengambil tugas ini

Sebaiknya gunakan kelas pabrik abstrak saat:

  1. Objek Anda seharusnya tidak bergantung pada bagaimana objek dalamnya dibuat dan dirancang
  2. Kelompok objek yang ditautkan harus digunakan bersama dan Anda harus melayani kendala ini
  3. Objek harus dikonfigurasikan oleh salah satu dari beberapa keluarga kemungkinan objek tertaut yang akan menjadi bagian dari objek induk Anda
  4. Hal ini diperlukan untuk berbagi objek anak yang menunjukkan antarmuka saja tetapi bukan implementasi
Dzianis Yafimau
sumber
9

UML dari

masukkan deskripsi gambar di sini

Produk: Ini mendefinisikan antarmuka objek yang dibuat oleh metode Factory.

ConcreteProduct: Menerapkan antarmuka Produk

Pembuat: Menyatakan metode Pabrik

ConcreateCreator: Menerapkan metode Factory untuk mengembalikan instance dari ConcreteProduct

Pernyataan masalah: Buat Pabrik Game dengan menggunakan Metode Pabrik, yang mendefinisikan antarmuka game.

Cuplikan kode:

import java.util.HashMap;


/* Product interface as per UML diagram */
interface Game{
    /* createGame is a complex method, which executes a sequence of game steps */
    public void createGame();
}

/* ConcreteProduct implementation as per UML diagram */
class Chess implements Game{
    public Chess(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Chess game");
        System.out.println("Opponents:2");
        System.out.println("Define 64 blocks");
        System.out.println("Place 16 pieces for White opponent");
        System.out.println("Place 16 pieces for Black opponent");
        System.out.println("Start Chess game");
        System.out.println("---------------------------------------");
    }
}
class Checkers implements Game{
    public Checkers(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Checkers game");
        System.out.println("Opponents:2 or 3 or 4 or 6");
        System.out.println("For each opponent, place 10 coins");
        System.out.println("Start Checkers game");
        System.out.println("---------------------------------------");
    }
}
class Ludo implements Game{
    public Ludo(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Ludo game");
        System.out.println("Opponents:2 or 3 or 4");
        System.out.println("For each opponent, place 4 coins");
        System.out.println("Create two dices with numbers from 1-6");
        System.out.println("Start Ludo game");
        System.out.println("---------------------------------------");
    }
}

/* Creator interface as per UML diagram */
interface IGameFactory {
    public Game getGame(String gameName);
}

/* ConcreteCreator implementation as per UML diagram */
class GameFactory implements IGameFactory {

     HashMap<String,Game> games = new HashMap<String,Game>();
    /*  
        Since Game Creation is complex process, we don't want to create game using new operator every time.
        Instead we create Game only once and store it in Factory. When client request a specific game, 
        Game object is returned from Factory instead of creating new Game on the fly, which is time consuming
    */

    public GameFactory(){

        games.put(Chess.class.getName(),new Chess());
        games.put(Checkers.class.getName(),new Checkers());
        games.put(Ludo.class.getName(),new Ludo());        
    }
    public Game getGame(String gameName){
        return games.get(gameName);
    }
}

public class NonStaticFactoryDemo{
    public static void main(String args[]){
        if ( args.length < 1){
            System.out.println("Usage: java FactoryDemo gameName");
            return;
        }

        GameFactory factory = new GameFactory();
        Game game = factory.getGame(args[0]);
        if ( game != null ){                    
            game.createGame();
            System.out.println("Game="+game.getClass().getName());
        }else{
            System.out.println(args[0]+  " Game does not exists in factory");
        }           
    }
}

keluaran:

java NonStaticFactoryDemo Chess
---------------------------------------
Create Chess game
Opponents:2
Define 64 blocks
Place 16 pieces for White opponent
Place 16 pieces for Black opponent
Start Chess game
---------------------------------------
Game=Chess

Contoh ini menunjukkan Factorykelas dengan mengimplementasikan a FactoryMethod.

  1. Gameadalah antarmuka untuk semua jenis game. Ini mendefinisikan metode yang kompleks:createGame()

  2. Chess, Ludo, Checkers adalah varian permainan yang berbeda, yang menyediakan implementasi untuk createGame()

  3. public Game getGame(String gameName)ada FactoryMethoddi IGameFactorykelas

  4. GameFactorypra-membuat berbagai jenis game di konstruktor. Ini menerapkan IGameFactorymetode pabrik.

  5. Nama game dilewatkan sebagai argumen baris perintah ke NotStaticFactoryDemo

  6. getGamedi GameFactorymenerima nama permainan dan mengembalikan Gameobjek yang sesuai .

Pabrik:

Membuat objek tanpa memaparkan logika instantiation ke klien.

FactoryMethod

Tentukan antarmuka untuk membuat objek, tetapi biarkan subclass memutuskan kelas mana yang akan dipakai. Metode Factory memungkinkan class defer instantiation ke subclass

Gunakan kasus:

Kapan harus menggunakan: Clienttidak tahu kelas konkret apa yang harus dibuat saat runtime, tetapi hanya ingin mendapatkan kelas yang akan melakukan pekerjaan.

Ravindra babu
sumber
terima kasih untuk Anda bagian utama, itu ringkas untuk saya. tetapi, tidak terbayangkan bahwa "getArea () adalah Metode Pabrik dalam bentuk antarmuka", karena metode getArea PERNAH instantiate kelas apa pun, itu hanya melakukan perhitungan. tinjauan bahwa "Tentukan sebuah antarmuka untuk membuat objek, tetapi biarkan subclass memutuskan kelas mana yang akan dipakai "harap.
reco
getArea()bukan metode pabrik sama sekali .
Cranio
1
Saya memiliki pendapat yang berbeda - para ahli mohon validasi dan catat. 1. Klien (atau penyerang) membutuhkan Objek Menarik ... maka tidak perlu memanggil GameFactory baru () melainkan kelas Pabrik harus memiliki getInstance statis () 2.Juga Jika demikian maka games.put (Chess.class.getName ( ), Catur baru ()); akan selalu mengembalikan referensi Catur yang sama [jika diterapkan sebagai statis] - bagaimana menangani skenario itu dengan cara yang paling efektif?
Arnab Dutta
Saya telah memberikan contoh Pabrik non-statis. Anda dapat menerapkannya dengan blok dan metode statis jika Anda mau. Mengenai pertanyaan Anda: 1. Klien akan menghubungi Pabrik untuk mendapatkan Game. 2. Saya meletakkan objek sekali dan semua Dapatkan akan mengembalikan contoh yang sama - referenc.e Catur yang sama dikembalikan untuk setiap get
Ravindra babu
6

Ini benar-benar masalah selera. Kelas-kelas pabrik dapat diabstraksi / dihubung-hubungkan seperlunya, sedangkan metode pabrik lebih ringan (dan juga cenderung dapat diuji, karena mereka tidak memiliki tipe yang ditentukan, tetapi mereka akan memerlukan titik registrasi yang terkenal, seperti layanan locator tetapi untuk menemukan metode pabrik).

Brad Wilson
sumber
4

Kelas pabrik berguna untuk ketika jenis objek yang mereka kembalikan memiliki konstruktor pribadi, ketika kelas pabrik yang berbeda menetapkan properti yang berbeda pada objek yang kembali, atau ketika jenis pabrik tertentu digabungkan dengan jenis betonnya yang kembali.

WCF menggunakan kelas ServiceHostFactory untuk mengambil objek ServiceHost dalam situasi yang berbeda. The ServiceHostFactory standar yang digunakan oleh IIS untuk mengambil contoh ServiceHost untuk SVC file, tetapi WebScriptServiceHostFactory yang digunakan untuk layanan yang serializations kembali ke klien JavaScript. Layanan Data ADO.NET memiliki DataServiceHostFactory khusus dan ASP.NET memiliki ApplicationServicesHostFactory karena layanannya memiliki konstruktor pribadi.

Jika Anda hanya memiliki satu kelas yang mengkonsumsi pabrik, maka Anda bisa menggunakan metode pabrik dalam kelas itu.

Mark Cidade
sumber
2

Pertimbangkan skenario ketika Anda harus merancang kelas Pesanan dan Pelanggan. Untuk kesederhanaan dan persyaratan awal Anda tidak merasa perlu pabrik untuk kelas Order dan mengisi aplikasi Anda dengan banyak pernyataan 'Order baru ()'. Semuanya bekerja dengan baik.

Sekarang persyaratan baru muncul bahwa objek Pesanan tidak dapat dipakai tanpa asosiasi Pelanggan (ketergantungan baru). Sekarang Anda memiliki pertimbangan sebagai berikut.

1- Anda membuat kelebihan konstruktor yang hanya akan berfungsi untuk implementasi baru. (Tidak dapat diterima). 2- Anda mengubah tanda tangan Order () dan mengubah masing-masing dan setiap invokation. (Bukan latihan yang baik dan rasa sakit yang nyata).

Alih-alih Jika Anda telah membuat pabrik untuk Kelas Pesanan, Anda hanya perlu mengubah satu baris kode dan Anda dapat melakukannya. Saya menyarankan kelas Pabrik untuk hampir setiap asosiasi agregat. Semoga itu bisa membantu.

Muhammad Awais
sumber
1

jika Anda ingin membuat objek yang berbeda dalam hal menggunakan. Ini berguna.

public class factoryMethodPattern {
      static String planName = "COMMERCIALPLAN";
      static int units = 3;
      public static void main(String args[]) {
          GetPlanFactory planFactory = new GetPlanFactory();
          Plan p = planFactory.getPlan(planName);
          System.out.print("Bill amount for " + planName + " of  " + units
                        + " units is: ");
          p.getRate();
          p.calculateBill(units);
      }
}

abstract class Plan {
      protected double rate;

      abstract void getRate();

      public void calculateBill(int units) {
            System.out.println(units * rate);
      }
}

class DomesticPlan extends Plan {
      // @override
      public void getRate() {
            rate = 3.50;
      }
}

class CommercialPlan extends Plan {
      // @override
      public void getRate() {
            rate = 7.50;
      }
}

class InstitutionalPlan extends Plan {
      // @override
      public void getRate() {
            rate = 5.50;
      }
}

class GetPlanFactory {

      // use getPlan method to get object of type Plan
      public Plan getPlan(String planType) {
            if (planType == null) {
                  return null;
            }
            if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
                  return new DomesticPlan();
            } else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
                  return new CommercialPlan();
            } else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
                  return new InstitutionalPlan();
            }
            return null;
      }
}
Samet ÖZTOPRAK
sumber
1

Setiap kelas yang menunda pembuatan objek ke sub kelasnya untuk objek yang perlu dikerjakan dapat dilihat sebagai contoh pola Pabrik.

Saya telah menyebutkan secara rinci dalam jawaban lain di https://stackoverflow.com/a/49110001/504133

nits.kk
sumber
1

Saya pikir itu akan tergantung pada derajat kopling longgar yang ingin Anda bawa ke kode Anda.

Metode pabrik memisahkan hal-hal dengan sangat baik tetapi kelas pabrik tidak.

Dengan kata lain, lebih mudah untuk mengubah hal-hal jika Anda menggunakan metode pabrik daripada jika Anda menggunakan pabrik sederhana (dikenal sebagai kelas pabrik).

Lihatlah contoh ini: https://connected2know.com/programming/java-factory-pattern/ . Sekarang, bayangkan Anda ingin membawa binatang baru. Di kelas Pabrik Anda perlu mengubah Pabrik tetapi dalam metode pabrik, tidak, Anda hanya perlu menambahkan subkelas baru.

tagus
sumber
0

Kelas pabrik lebih berat, tetapi memberi Anda keuntungan tertentu. Dalam kasus ketika Anda perlu membangun objek Anda dari banyak, sumber data mentah, mereka memungkinkan Anda untuk merangkum hanya logika bangunan (dan mungkin agregasi data) di satu tempat. Di sana dapat diuji secara abstrak tanpa harus peduli dengan antarmuka objek.

Saya telah menemukan ini pola yang berguna, terutama di mana saya tidak dapat mengganti dan ORM tidak memadai dan ingin secara efisien instantiate banyak objek dari tabel DB bergabung atau prosedur yang tersimpan.

jonfm
sumber
0

Saya menyamakan pabrik dengan konsep perpustakaan. Misalnya, Anda dapat memiliki perpustakaan untuk bekerja dengan angka dan lainnya untuk bekerja dengan bentuk. Anda dapat menyimpan fungsi perpustakaan ini dalam direktori yang bernama logis sebagai Numbersatau Shapes. Ini adalah tipe generik yang dapat meliputi bilangan bulat, mengapung, dobules, long atau rectangles, lingkaran, segitiga, pentagon dalam hal bentuk.

Petter pabrik menggunakan polimorfisme, injeksi ketergantungan dan Inversi kontrol.

Tujuan lain dari Pola Pabrik adalah: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Jadi katakanlah Anda sedang membangun Sistem Operasi atau Kerangka Kerja dan Anda sedang membangun semua komponen diskrit.

Berikut adalah contoh sederhana dari konsep Pola Pabrik di PHP. Saya mungkin tidak 100% pada semua itu tetapi dimaksudkan untuk menjadi contoh sederhana. Saya bukan ahli.

class NumbersFactory {
    public static function makeNumber( $type, $number ) {
        $numObject = null;
        $number = null;

        switch( $type ) {
            case 'float':
                $numObject = new Float( $number );
                break;
            case 'integer':
                $numObject = new Integer( $number );
                break;
            case 'short':
                $numObject = new Short( $number );
                break;
            case 'double':
                $numObject = new Double( $number );
                break;
            case 'long':
                $numObject = new Long( $number );
                break;
            default:
                $numObject = new Integer( $number );
                break;
        }

        return $numObject;
    }
}

/* Numbers interface */
abstract class Number {
    protected $number;

    public function __construct( $number ) {
        $this->number = $number;
    }

    abstract public function add();
    abstract public function subtract();
    abstract public function multiply();
    abstract public function divide();
}
/* Float Implementation */
class Float extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Integer Implementation */
class Integer extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Short Implementation */
class Short extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Double Implementation */
class Double extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Long Implementation */
class Long extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}

$number = NumbersFactory::makeNumber( 'float', 12.5 );
Robert Rocha
sumber
Saya mengerti apa yang terjadi di sini, tetapi saya tidak mengerti apa maksudnya. Apa yang NumbersFactory::makeNumber( 'float', 12.5 );memberi saya hanya mengatakan new Float(12.5);jika saya tahu saya perlu Float? Ini yang tidak saya mengerti tentang pabrik ... apa gunanya?
BadHorsie
Ini memungkinkan Anda memilih implementasi yang berbeda dan tidak mengikat Anda untuk hanya satu. Antarmuka dibuat dan semua implementasi harus menjamin dan menghormatinya.
Robert Rocha