# Open Closed Principle (OCP)

Prinsip yang pertama kali dikenalkan oleh Bertrand Meyer pada buku *Object Oriented Software Construction* pada tahun 1988. Idea dasar dari Prinsip ini adalah Software Entity baik itu class, module, function terbuka untuk penambahan feature baru tanpa merubah code yang ada. Sebagai contoh adalah seperti berikut ini.

> Tulisan ini adalah bagian dari [SOLID Principles](https://verri.andriawan.web.id/series/solid-principles) Series, sehingga untuk bisa membaca secara menyeluruh dan berkesinambungan, alangkah lebih baik bisa membaca secara urut dari link series [berikut](https://verri.andriawan.web.id/series/solid-principles).

Asumsi kita sudah membuat class untuk Notification dengan nama file `NotifyEvent.ts` dengan content seperti berikut:

```typescript
class NotifyEvent {
	
	private email: string
	private phone: string
	private id: string
	private content: string
	
	static new(data: Record<string, any>) : NotifyEvent {
		const instance = new NotifyEvent
		instance.setEntity(data)
		return instance
	}
	
	setEntity(data: Record<string,any>) {
		this.id = data.id
		this.email = data.email
		this.phone = data.phone
		this.content = data.content
	}
	
	sendEmail() {
		// code untuk mengirim email
	}
	
	sendSMS() {
		// code untuk mengirim sms
	}
	
}
```

Class tersebut hanya memiliki tugas yang yaitu `Notification`. Tapi class ini bermasalah atau orang biasanya menyebutnya tidak fleksible. Kenapa? karena, seandainya kita ingin menambah fitur notifikasi baru untuk mengirim infomasi ke Telegram Messanger misalnya, maka kita harus merubah class tersebut untuk menambah method baru semisal bernama `sendTelegram` . Jika kita mengimplementasikan Prinsip *OpenClose*, Code class di atas akan menjadi seperti ini:

Pertama kita perlu melakukan abstraction agar semua method yang required, diharuskan diimplementasi. Kita bisa menggunakan abtract class atau kita bisa menggunakan Interface. Tapi pada tulisan ini saya akan menggunakan Class Abstraction. Tapi apa bedanya? Saya akan buat tulisan khusus untuk membahas itu. Berikut contoh abstract cclass yang kita gunakan.

```typescript
abstract class NotifyEvent {
	abstract setProp(data: Record<string,any>): void
	abstract log(): Promise<void>
	abstract send(): Promise<boolean>
}
```

Buat class event yang extends dari class NotifyEvent tersebut. Sebagai contoh di sini akan membuat event notifier untuk SMS.

```typescript
class NotifySMSEvent extends NotifyEvent {
	private phone: string
	
	static new(data: Record<string,any>): NotifyEvent {
		const instance = new NotifySMSEvent
		instance.setProp(data)
		return instance
	}
	
	setProp(data: Record<string, any>) {
		// set property
	}

	async log() {
	  // Log to database
	}
	
	async send() {
		// Send Code di sini
	}
}
```

Lalu kita buat dispatcher class atau executor untuk notifier SMS diatas.

```typescript
class NotifyDispatcher {
	private events: NotifyEvent[] = []; 
	
	async execute() {
	  const events: any[] = []
	  for(let e of this.events) {
	     events.push(e,send(), e.log())
	  }
	  return Promise.all(events)
	}	
	
	pushEvent(event: NotifyEvent) {
		this.events.push(event)
	}
}
```

Class dipatcher inilah yang seharusnya ada pada bagian core dengan tujuan agar tidak ada perubahan pada core atau module utama ketika business menginginkan penambahan feature untuk notification.

Selanjutnya pada function utama, kita perlu untuk meng-initialisasi class-class diatas. Seperti berikut.

```typescript
function main() {
		const data = {} 
		const event: NotifyEvent = NotifySMSEvent.new(data)
   
		const dispatcher= new NotifyDispatcher
		dispatcher.pushEvent(event)
		
		await dispatcher.execute()
}
```

### Kesimpulan

Dengan mengimplementasikan OCP, maka program akan lebih flexible dalam melakukan pergantian usecase module yang akan digunakan.

references:

* [https://web.uettaxila.edu.pk/CMS/AUT2011/seSCbs/tutorial/Object Oriented Software Construction.pdf](https://web.uettaxila.edu.pk/CMS/AUT2011/seSCbs/tutorial/Object%20Oriented%20Software%20Construction.pdf)
    
* [https://stackify.com/solid-design-open-closed-principle](https://stackify.com/solid-design-open-closed-principle/)
