DEV Community

Cover image for Di Pandu oleh Iterator Pattern
M.Hakim Amransyah
M.Hakim Amransyah

Posted on

Di Pandu oleh Iterator Pattern

Artikel Ini adalah lanjutan pembahasan implementasi design-pattern yang sebelumnya dibahas pada Bersolek Ria dengan Decorator-pattern. 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

iterator.go

type Iterator interface {
    GetNext() Employee
    HasMore() bool
}

Enter fullscreen mode Exit fullscreen mode

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}
}
Enter fullscreen mode Exit fullscreen mode

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)

    }
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)