DEV Community

Cover image for Bersolek Ria dengan Decorator Pattern
M.Hakim Amransyah
M.Hakim Amransyah

Posted on

Bersolek Ria dengan Decorator Pattern

Artikel Ini adalah lanjutan pembahasan implementasi design-pattern yang sebelumnya dibahas pada lebih dekat dengan visitor-pattern. Domain permasalah dan sources code yang digunakan merupakan lanjutan dari pembahasan sebelumnya.

Prolog

Pada saat daily standup kemarin anda mendapatkan arahan dari atasan anda untuk melakukan enhance pada fitur pengiriman notifikasi peringatan yang telah dibuat. Sebelumnya anda hanya menggunakan fungsi sederhana untuk mengirimkan notifikasi peringatan ke seluruh level pegawai. Atasan anda meminta agar sources code yang ada mampu mengakomodasi untuk mengirimkan notifikasi menggunakan beberapa media yang berbeda-beda. Adapun ketentuan yang diminta oleh atasan anda adalah;

  • Seluruh level pegawai akan menerima notifikasi melalui push notification pada aplikasi mobile perusahaan.
  • Selain push notification, supervisor dapat menerima notifikasi melalui email.
  • Selain push notification, manajer dapat menerima notifikasi melalui email & pesan whatsapp.

Secara umum saat ini aplikasi anda memiliki relasi kelas sebagai berikut;

Image description

Tanggung jawab pengiriman notifikasi peringatan saat ini diemban oleh objek PerformanceWarningVisitor yang merupakan implementasi dari visitor-pattern (dijelaskan pada lebih dekat dengan visitor-pattern ).

Mendekor ulang objek

Anda tahu bahwa saat ini notifikasi peringatan hanya dikirimkan melalui push notifications. Sesuai dengan ketentuan yang diberikan, anda harus menambahkan media notifikasi lainnya tanpa menghapus atau menghilangkan default notifikasi yang saat ini digunakan.

Anda sadar bahwa membuat objek yang berdiri sendiri bukanlah ide yang bagus karena (sekali lagi) setiap jenis notifikasi akan berakumulasi dengan jenis notifikasi lain. Sederhananya ketentuan tersebut dapat dijelaskan seperti berikut

Staf -> Push Notification
Supervisor -> Push Notification | Email
Manajer -> Push Notification | Email | WhatsApp Number

Decorator Pattern

Setelah gugling dan bertapa cukup lama, anda akhirnya memutuskan untuk menggunakan decorator-pattern untuk menangani kasus ini. Anda akan membuat sebuah decorator yang akan mendekorasi ulang fungsi push-notifications sehingga memiliki fungsi notifikasi dengan media yang berbeda-beda.

Image description

Anda membuat sebuah kelas factory yang bertugas untuk meng-assemble berbagai macam decorator sesuai dengan level pegawai yang ada. Singkatnya implementasi kelas tersebut adalah sebagai berikut;

notification_factory.go

type NotificatorContract interface {
    StaffNotifier() entity.Notifier
    SupervisorNotifier() entity.Notifier
    ManagerNotifier() entity.Notifier
}

type Notificator struct{}

func (notifier *Notificator) StaffNotifier() entity.Notifier {
    return decorator.NewPushNotificationDecorator()
}

func (notifier *Notificator) SupervisorNotifier() entity.Notifier {
    pushNotification := decorator.NewPushNotificationDecorator()
    emailNotification := decorator.NewEmailDecorator(pushNotification)
    return emailNotification
}

func (notifier *Notificator) ManagerNotifier() entity.Notifier {
    pushNotification := decorator.NewPushNotificationDecorator()
    emailNotification := decorator.NewEmailDecorator(pushNotification)
    whatsAppNotification := decorator.NewWhatsAppDecorator(emailNotification)
    return whatsAppNotification
}

func NewNotificator() *Notificator {
    return &Notificator{}
}
Enter fullscreen mode Exit fullscreen mode

Factory tersebut nantinya akan dimanfaatkan oleh objek PerformanceWarningVisitor.

performance_warning_visitor.go

type PerformanceWarningVisitor struct {
    Notif factory.NotificatorContract
}

func (visitor PerformanceWarningVisitor) VisitStaff(staff *entities.Staff) (interface{}, error) {

    var warningType string

    notification := visitor.Notif.StaffNotifier()

    if staff.PerformancePercentage < 30 {
        warningType = STERN_WARNING
    }

    if staff.PerformancePercentage >= 30 && staff.PerformancePercentage < 67 {
        warningType = WARNING
    }

    notification.SendMessage(
        staff,
        fmt.Sprintf("Notification %s send to staff : %s \n", warningType, staff.Name),
    )

    return warningType, nil
}

func (visitor PerformanceWarningVisitor) VisitSupervisor(spv *entities.Supervisor) (interface{}, error) {

    var warningType string

    durationInYear := (time.Now()).Sub(spv.JoinDate).Hours() / 8760
    notification := visitor.Notif.SupervisorNotifier()

    if spv.PerformancePercentage < 30 {
        warningType = STERN_WARNING
    }

    if durationInYear >= 10 && (spv.PerformancePercentage >= 30 && spv.PerformancePercentage < 60) {
        warningType = WARNING
    }

    if durationInYear < 10 && (spv.PerformancePercentage >= 30 && spv.PerformancePercentage < 70) {
        warningType = WARNING
    }

    notification.SendMessage(
        spv,
        fmt.Sprintf("Notification %s send to supervisor : %s \n", warningType, spv.Name),
    )

    return warningType, nil
}

func (visitor PerformanceWarningVisitor) VisitManager(manager *entities.Manager) (interface{}, error) {

    var warningType string

    Age := (time.Now()).Sub(manager.BirthDate).Hours() / 8760
    notification := visitor.Notif.ManagerNotifier()

    if manager.PerformancePercentage < 40 {
        warningType = STERN_WARNING
    }

    if Age >= 40 && (manager.PerformancePercentage >= 40 && manager.PerformancePercentage < 60) {
        warningType = WARNING
    }

    if Age < 40 && (manager.PerformancePercentage >= 40 && manager.PerformancePercentage < 70) {
        warningType = WARNING
    }

    notification.SendMessage(
        manager,
        fmt.Sprintf("Notification %s send to manager : %s \n", warningType, manager.Name),
    )

    return warningType, nil
}
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/decorator
https://www.youtube.com/watch?v=metYIcjQLls

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

Top comments (0)