S.O.L.I.D Principle - Open Closed Principle (OCP)
Tags: programming, kotlin, oop, architecutre
Published: 2021-06-14 16:36:40

Open Closed Principle ini dapat didefinisikan sebagai berikut:
> 💡 Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

yang berarti setiap entitas perangkat lunak (class, module, fungsi, dsb.) sebaiknya terbuka untuk dilakukan ekstensi, dan tertutup untuk modifikasi. Kita seharusnya dapat menambahkan behavior baru tanpa perlu merubah implementasinya.

Tujuan dari prinsip ini untuk menghindari kemungkinan terjadinya bug-bug baru ketika kita merubah implementasi code yang sudah uda.

Ilustrasi Open Closed Principle:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjwoomtqkrzzirch3lpe.jpg)[Image Source](https://cosmos.id/product/cosmos-blenz-cb-802-blender-1-2-l/)

Seperti gambar Illustrasi di atas, Terdapat 1 Mesin Blender, dan beberapa wadah untuk blender yang digunakan untuk kasus-kasus yang berbeda, dimana ada yang untuk memblender daging, memblender buah, memblender bumbu dapur. Jadi wadah tersebut memiliki fungsi yang berbeda-beda tanpa harus merubah fungsi utama dari mesin blender.

## Contoh Kasus

Kita ambil contoh Blender di atas. Misal anda memiliki class Blender yang memiliki fungsi untuk memblender buah buahan

```kotlin
class Blender {
    fun blend() {
        println("Mulai memblender")
    }
}
```

lalu ada kebutuhan dari Produk yang membuat class Blender anda dapat daging, dan bumbu dapur / rempah-rempah.

**Jika anda tidak mengikuti prinsip Open Closed Principle** mungkin saja anda akan melakukan hal seperti ini:
```kotlin
class Blender {
    fun blend(tipe: String) {
        when (tipe) {
            "BUAH" -> blendFruit()
            "DAGING" -> blendMeat()
            "REMPAH" -> blendSpices()
        }
    }

    private fun blendFruit() {
        println("Mulai memblender Buah")
    }
    
    fun blendMeat() {
        println("Mulai memblender Daging")
    }

    fun blendSpices() {
        println("Mulai memblender rempah-rempah")
    }
}
```

Jika anda melakukan hal tersebut sangat memungkinkan terciptanya bug baru karena anda telah mengubah code yang sebelumnya telah berjalan normal.

### Code Improvement
Sekarang kita akan coba melakukan improvement agar sesuai dengan prinsip OCP.

```kotlin
interface Processor {
    fun process()
}
```

kita siapkan antarmuka / abstraksi yang akan kita gunakan sebagai cetakan processor-processor yang akan kita buat nanti.

Lalu kita mulai buat masing-masing processor menggunakan cetakan yang sudah ada.

```kotlin
class FruitProcessor() : Processor {
    override fun process() {
        println("Mulai memblender Buah")
    }
}
```

```kotlin
class MeatProcessor() : Processor {
    override fun process() {
        println("Mulai memblender Daging")
    }
}
```

```kotlin
class SpicesProcessor() : Processor {
    override fun process() {
        println("Mulai memblender rempah-rempah")
    }
}
```

setelah kita buat masing-masing processor nya untuk memproses masing-masing bahan olahan.

kita menambahkan parameter di fungsi blend dengan object Processor yang akan kita gunakan untuk memproses bahan olahan.

```kotlin
class Blender {
    fun blend(processor: Processor) {
        processor.process()
    }
}
```

**Lantas apa yang terjadi ketika produk ingin menambahkan kebutuhan untuk memblender batu es (ice cube) ?**

Kita tinggal membuat class baru yang mengimplementasikan interface Processor

```kotlin
class IceCubeProcessor() : Processor {
    override fun process() {
        println("Mulai memblender batu es")
    }
}
```

sehingga kita tidak perlu mengubah class Blender yang sebelumnya sudah berjalan.

## Manfaat
* fungsionalitas dari class 'X' dapat dengan mudah diperluas dengan fungsionalitas yang baru dengan dikemas dalam kelas yang terpisah dari class 'X' tanpa perlu mengubah implementasi di class 'X' (tidak ada perubahan di class 'X')
* code anda menjadi loosely coupled
* class 'Y' yang di pakai di dalam class 'X' dapat dengan mudah dimock (dipalsukan), sehingga membuat class 'X' lebih mudah untuk di test.

## Akhir Kata
Sekian dan terimakasih, Saya harap anda bisa menerapkan prinsip ini sehingga code yang anda tulis akan mencadi lebih bersih, mudah untuk test, lebih mudah untuk dikembangkan lagi,   dan dapat menunjang produktivitas anda.