Di Pandu oleh Iterator Pattern
Tags: indonesia, go, designpatterns
Published: 2023-07-07 02:02:01

Artikel Ini adalah lanjutan pembahasan implementasi _design-pattern_ yang sebelumnya dibahas pada [Bersolek Ria dengan Decorator-pattern](https://dev.to/mhakimamransyah/bersolek-ria-dengan-decorator-pattern-2j7h). Domain permasalah dan _sources code_ yang digunakan merupakan lanjutan dari pembahasan sebelumnya.

## Prolog
Perusahaan tempat anda bekerja ternyata memiliki segudang ide dan rencana terkait dengan aplikasi yang anda kelola. Hari ini anda, atasan anda dan seorang _product owner_ melakukan _virtual meeting_ terkait _enhancement_ dari aplikasi tersebut. Diskusi berakhir dengan sebuah tugas yang di bebankan kepada anda melalui atasan anda.

Anda diminta untuk menambahkan fungsi untuk memfilter setiap pegawai yang akan dikirimkan notifikasi peringatan ke _sources code_ yang ada. Saat ini aplikasi anda bersifat "buta" dengan mengirimkan notifikasi peringatan kepada seluruh pegawai di setiap level tanpa memperhatikan apakah status pegawai tersebut masih aktif atau tidak.

## Open for extension Closed for modification
Atasan anda meminta agar filter yang dibuat bisa digunakan dimanapun ketika ada fitur yang membutuhkan. Filter tersebut juga diharapkan nantinya tidak perlu dimodifikasi apabila ada kebutuhan untuk memfilter pegawai dengan cara yang berbeda. Atasan anda kemudian menyebut sebuah kata yang bisa mengubah hidup anda sepenuhnya, dia berkata 

"**_Coba pelajari iterator pattern_**"

## Iterator
Setelah mendapatkan petunjuk dari atasan anda, anda memutuskan untuk menggunakan _iterator pattern_ pada kasus ini. Anda berencana untuk membuat sebuah objek yang hanya bertanggung jawab untuk memfilter status aktif dari pegawai. Anda juga tahu bahwa dengan menggunakan _pattern_ ini _iterator_ lain bisa dengan mudah ditambahkan apabila nanti dibutuhkan.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ku9qya9uqqdpln2svyk.png)

**iterator.go**
```
type Iterator interface {
	GetNext() Employee
	HasMore() bool
}

```
**active_employee_iterator.go**
```
type ActiveEmployeeIterator struct {
	Employees       []entity.Employee
	CurrentPosition int
	Status          bool
}

func (iter *ActiveEmployeeIterator) GetNext() entity.Employee {

	if !iter.HasMore() {
		return nil
	}

	employee := iter.Employees[iter.CurrentPosition]

	iter.CurrentPosition++

	if employee.GetStatus() {
		return employee
	}

	return iter.GetNext()

}
func (iter *ActiveEmployeeIterator) HasMore() bool {

	if iter.CurrentPosition >= len(iter.Employees) {
		return false
	}

	employee := iter.Employees[iter.CurrentPosition]

	if employee.GetStatus() {
		return iter.CurrentPosition < len(iter.Employees)
	}

	iter.CurrentPosition++

	return iter.HasMore()

}

func NewActiveEmployeeIterator(employees []entity.Employee, status bool) *ActiveEmployeeIterator {
	return &ActiveEmployeeIterator{Employees: employees, Status: status}
}
```
Panggil iterator pada main program sehingga;

**main.go**

```
// iterate only for active employee
	employeesIter := iterator.NewActiveEmployeeIterator(employees, true)

	for employeesIter.HasMore() {

		employee := employeesIter.GetNext()

		// accept performance notification visitor
		employee.Accept(performanceNotification)

		// accept bonus income visitor
		employee.Accept(bonusIncome)

	}
```

## Epilog
Seluruh _sources code_ yang berkaitan dengan artikel ini dapat dilihat pada _repository_ berikut https://github.com/Mhakimamransyah/practice-design-pattern

Referensi Bacaan
https://refactoring.guru/design-patterns/iterator

Author
https://github.com/Mhakimamransyah
https://www.linkedin.com/in/hakim-amr/
mailto: m.hakim.amransyah.hakim@gmail.com