Apa itu Factory Pattern?

Factory Pattern merupakan salah satu design pattern yang sering digunakan dalam pengembangan sebuah program. Factory Pattern juga merupakan salah satu design pattern yang berasal dari kelompok Creational Design Pattern, yang berarti sebuah design pattern yang berfokus pada pembuatan suatu object.

Saya yakin, selain saya pribadi, temen-temen pasti juga sering lihat design pattern ini di dalam project temen-temen. Entah liat dari kodingan temen satu tim, kodingan di dalam suatu library, atau kodingan suatu framework yang teman-teman pakai.

Biasanya, factory pattern secara tersurat ditunjukkan di dalam penamaan class: CarFactory.java atau ShapeFactory.java dan sebagainya, yang mengandung kata-kata factory dalam penamaan class nya.

Sayangnya, saya dan kebanyakan dari kita cuma sebatas tahu: “oh class ini adalah sebuah factory class, karena mengandung kata-kata factory” tanpa tahu maksud sebenarnya mengapa nama class tesebut mengandung kata “factory”. 

Atau bahkan, cilakanya, kita ngga tahu sama sekali bahwa penamaan “factory” itu sebenarnya adalah sebuah implementasi dari factory pattern.

Sama, saya juga awalnya ngga tahu :’(

Pengertian Factory Pattern

Factory Pattern, merupakan sebuah design pattern (sebuah template, pattern atau pola penyelesaian masalah) yang menyediakan sebuah static method di dalam sebuah class yang disebut factory, yang dapat digunakan oleh client code untuk membuat suatu object, tanpa mengetahui detail tentang bagaimana object tersebut dibuat.

Persis seperti namanya – “factory” atau dalam bahasa indonesia berarti “pabrik” – ia memproduksi sebuah object yang memiliki beberapa fungsi, tanpa perlu memberi tahu penggunanya tentang bagaimana object tersebut dibuat dan apa yang dilakukan oleh fungsi-fungsi didalamnya.

Analoginya seperti ini:

Sebuah pabrik mobil (factory class) memiliki sebuah tugas untuk memproduksi (static method) dua mobil: mobil listrik (object) dan mobil konvensional (object). Kedua mobil tersebut memiliki beberapa fungsi, diantaranya adalah berjalanMaju (method) dan berjalanMundur (method).

Idealnya, sebagai supir (client code), tugasnya hanyalah memerintahkan pabrik untuk memproduksi (static method) mobil yang dinginkan – apakah mobil listrik (object) atau mobil konvensional (object) – dan menjalankan fungsi berjalanMaju (method) dan berjalanMundur (method).

Si supir ga perlu tau bagaimana cara pabrik memproduksi mobil yang diinginkan dan perintah-perintah apa yang dijalankan oleh fungsi berjalanMaju dan fungsi berjalanMundur pada mobil tersebut.

Fun fact: cerita diatas merupakan implementasi dari salah satu konsep OOP yaitu: encapsulation.

Sampai sini sudah sedikit paham dan kebayang? Ok, Biar lebih joss, kita coba transformasikan analogi yang saya sebutkan diatas kedalam kodingan java. Gaspol.

Membuat program Java sederhana

Dalam kesempatan kali ini, saya akan mencontohkan cara implementasi factory pattern menggunakan bahasa pemrograman Java dengan membuat sebuah program sederhana yang berfokus pada object mobil.

Pertama-tama, mari kita mulai dengan membuat interface Car beserta dua buah class yang mengimplementasi interface Car, yaitu GasolineCar dan ElectricCar

public interface Car {
    String getType();
    void startEngine();
    void moveForward();
    void moveBackward();
    void stopEngine();
}
public class GasolineCar implements Car {
    public static final String TYPE = "Gasoline Car";

    private int tankCapacity;

    public GasolineCar(int tankCapacity) {
        this.tankCapacity = tankCapacity;
    }

    public int getTankCapacity() {
        return tankCapacity;
    }

    @Override
    public String getType() {
        return TYPE;
    }

    @Override
    public void startEngine() {
        System.out.println("My " + TYPE + " engine is successfully started.");
    }

    @Override
    public void moveForward() {
        System.out.println("My " + TYPE + " is moving forward loudly. VROOOOMMMMMMM...");
    }

    @Override
    public void moveBackward() {
        System.out.println("My " + TYPE + " is moving backward loudly. WEEE-O... WEEE-O...");
    }

    @Override
    public void stopEngine() {
        System.out.println("My " + TYPE + " engine is successfully stopped.");
    }
}
public class ElectricCar implements Car {
    public static final String TYPE = "Electric Car";

    private int batteryCapacity;

    public ElectricCar(int batteryCapacity) {
        this.batteryCapacity = batteryCapacity;
    }

    public int getBatteryCapacity() {
        return batteryCapacity;
    }

    @Override
    public String getType() {
        return TYPE;
    }

    @Override
    public void startEngine() {
        System.out.println("My " + TYPE + " engine is successfully started.");
    }

    @Override
    public void moveForward() {
        System.out.println("My " + TYPE + " is moving forward silently. Woooooosh...");
    }

    @Override
    public void moveBackward() {
        System.out.println("My " + TYPE + " is moving backward silently. Beep... beep...");
    }

    @Override
    public void stopEngine() {
        System.out.println("My " + TYPE + " engine is successfully stopped.");
    }
}

Cukup dengan tiga buah class tersebut, kita sudah dapat menjalankan programnya. Mari kita buat sebuah class dengan nama App.java, kemudian kita buat fungsi main didalamnya. Didalam fungsi main tersebut, kita akan instantiate dua buah object yang merepresentasikan mobil konvensional dan mobil listrik.

public class App {
    public static void main(String[] args) {
        Car myFirstCar = new ElectricCar(100);
        Car mySecondCar = new GasolineCar(300);

        System.out.println("I want to use my electric car..");
        myFirstCar.startEngine();
        myFirstCar.moveForward();
        myFirstCar.moveBackward();
        myFirstCar.stopEngine();

        System.out.println("\n\nNow, I want to use my gasoline car..");
        mySecondCar.startEngine();
        mySecondCar.moveForward();
        mySecondCar.moveBackward();
        mySecondCar.stopEngine();
    }
}

Apabila kita perhatikan kode diatas, class App bertanggung jawab dalam pembuatan object-object dari interface Car. Pada saat pembuatan object dengan tipe ElectricCar, class App harus mendefinisikan variabel batteryCapacity.

Car myFirstCar = new ElectricCar(100);

Begitu juga pada saat pembuatan object dengan tipe GasolineCar, variabel tankCapacity harus didefinisikan terlebih dahulu pada saat pemanggilan constructor class GasolineCar.

Car mySecondCar = new GasolineCar(300);

Dalam program diatas, kita belum mengimplementasikan factory pattern. Nah, untuk itu, mari kita dapat implementasikan factory pattern ke dalam program kita.

Implementasi Factory Pattern

Tujuan utama dari pengimplementasian Factory Pattern adalah mengenkapsulasi pembuatan object dan membebastugaskan client code dalam pembuatan object. Client code tidak perlu mempedulikan bagaimana sebuah object itu dibuat, variabel-variabel apa saja yang dibutuhkan oleh constructor object tersebut, dan sebagainya.

Client code hanya perlu peduli apakah object tersebut sudah berhasil dibuat dan siap untuk digunakan.

Untuk dapat mengimplementasikan hal tersebut, kita akan siapkan sebuah factory class dengan nama CarFactory.java. Kemudian didalamnya kita siapkan sebuah static method bernama produce. Method produce inilah yang bertugas dalam pembuatan object. Client code hanya perlu memberitahukan kepada factory class, tipe object seperti apa yang ingin dibuat.

public enum CarType {
    ELECTRIC, GASOLINE
}
public class CarFactory {
    public static Car produce(CarType carType) {
        if (carType.equals(CarType.ELECTRIC)) {
            return new ElectricCar(100);
        } else if (carType.equals(CarType.GASOLINE)) {
            return new GasolineCar(300);
        } else {
            throw new UnsupportedOperationException("Cannot produce unknown car type.");
        }
    }
}

Kemudian, pada main method yang sudah kita buat sebelumnya di class App.java, kita hanya perlu memanggil method produce pada class CarFactory, dan melemparkan tipe mobil apa yang dikehendaki.

public class App {
    public static void main(String[] args) {
        Car myFirstCar = CarFactory.produce(CarType.ELECTRIC);
        Car mySecondCar = CarFactory.produce(CarType.GASOLINE);

        System.out.println("I want to use my electric car..");
        myFirstCar.startEngine();
        myFirstCar.moveForward();
        myFirstCar.moveBackward();
        myFirstCar.stopEngine();

        System.out.println("\n\nNow, I want to use my gasoline car..");
        mySecondCar.startEngine();
        mySecondCar.moveForward();
        mySecondCar.moveBackward();
        mySecondCar.stopEngine();
    }
}

Perlu diperhatikan dari kode diatas, bahwa kita tidak lagi perduli berapa nilai dari variabel tankCapacity ataupun batteryCapacity seperti sebelumnya, karena definisi keduanya sudah dilakukan didalam factory class.

Kesimpulan

Nah, itu tadi penjelasan dan tutorial singkat dari saya tentang factory pattern. Full code nya bisa temen-temen lihat di github saya. Jangan lupa follow github saya dan star repository nya ya!

Apabila ada pertanyaan yang ingin ditanyakan, atau butuh bantuan untuk lebih mengerti lagi tentang factory pattern, silakan temen-temen DM saya di LinkedIn atau Twitter atau langsung email saya juga boleh. Infonya semua ada di home page saya ya, atau langsung klik disini.

Sekian post saya kali ini, sampai bertemu di postingan berikutnya.

Terima kasih. Bye!