Menu
CoddyTech

Pola Composite

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 96 dari 107.

Pola Composite memungkinkan kamu memperlakukan object individual dan grup object secara seragam. Sementara State mengubah perilaku berdasarkan state internal, Composite membangun struktur pohon yang membuat daun dan wadah menggunakan antarmuka yang sama.

Pola ini sangat cocok untuk struktur hierarkis seperti sistem file, bagan organisasi, atau komponen UI. Di Go, kita mendefinisikan interface umum yang diimplementasikan oleh item individual dan kontainer:

type Component interface {
    GetSize() int
}

type File struct {
    Name string
    Size int
}

func (f File) GetSize() int {
    return f.Size
}

Komponen komposit (wadah) menampung komponen anak dan menerapkan antarmuka yang sama dengan menggabungkan hasilnya:

type Folder struct {
    Name     string
    Children []Component
}

func (f *Folder) Add(c Component) {
    f.Children = append(f.Children, c)
}

func (f Folder) GetSize() int {
    total := 0
    for _, child := range f.Children {
        total += child.GetSize()
    }
    return total
}

Sekarang kamu bisa membuat folder bersarang di dalam folder lain, dan memanggil GetSize() bekerja dengan cara yang sama, baik untuk satu file maupun seluruh pohon direktori:

docs := &Folder{Name: "docs"}
docs.Add(File{Name: "readme.txt", Size: 100})
docs.Add(File{Name: "notes.txt", Size: 50})

root := &Folder{Name: "root"}
root.Add(docs)
root.Add(File{Name: "config.json", Size: 25})

fmt.Println(root.GetSize())  // 175

Composite cocok digunakan saat kamu perlu merepresentasikan hierarki bagian-keseluruhan dan ingin client memperlakukan object individual dan komposisi secara sama.

challenge icon

Tantangan

Mudah

Mari buat sistem bagan organisasi menggunakan pola Composite! Kamu akan membuat struktur tempat setiap karyawan dan departemen (yang berisi karyawan atau departemen lain) dapat diperlakukan secara seragam, cocok untuk menghitung total gaji di bagian mana pun dalam organisasi.

Kamu akan mengatur kodemu dalam tiga file:

  • component.go: Definisikan interface umum yang akan diterapkan oleh setiap individu dan kelompok.

    Buat interface OrgComponent dengan dua method:

    • GetSalary() int: mengembalikan total gaji untuk komponen ini
    • GetName() string: mengembalikan nama karyawan atau departemen
  • organization.go: Implementasikan tipe leaf (karyawan individu) dan composite (departemen).

    Buat struct Employee dengan field Name (string) dan Salary (int). GetSalary() mengembalikan gajinya sendiri, dan GetName() mengembalikan namanya.

    Buat struct Department dengan field Name (string) dan slice Members yang menampung item OrgComponent. Tambahkan method Add(c OrgComponent) untuk menambahkan anggota. GetSalary() harus mengembalikan jumlah gaji semua anggotanya, dan GetName() mengembalikan nama departemen.

  • main.go: Bangun struktur organisasi dan hitung gaji.

    Baca jumlah karyawan. Untuk setiap karyawan, baca nama dan gajinya, lalu buat instance Employee. Kemudian baca jumlah departemen. Untuk setiap departemen, baca namanya dan jumlah indeks anggota, lalu baca indeks-indeks tersebut (berbasis 0, merujuk pada karyawan atau departemen yang sudah dibuat sebelumnya sesuai urutan pembuatannya).

    Setelah membangun struktur, baca indeks terakhir dan cetak nama komponen tersebut serta total gajinya dengan format: [name]: [salary]

Input berikut akan diberikan:

  • Jumlah karyawan, lalu nama dan gaji setiap karyawan pada baris terpisah
  • Jumlah departemen, lalu nama setiap departemen, jumlah anggota, dan indeks anggota
  • Indeks terakhir untuk dikueri

Contohnya, jika diberikan:

3
Alice
50000
Bob
60000
Carol
55000
1
Engineering
3
0
1
2
3

Outputmu harus berupa:

Engineering: 165000

Dan jika diberikan:

4
Alice
50000
Bob
60000
Carol
55000
Dave
70000
2
Dev
2
0
1
QA
2
2
3
4

Outputmu harus berupa:

QA: 125000

Dan jika diberikan:

2
Alice
50000
Bob
60000
0
1

Outputmu harus berupa:

Bob: 60000

Perhatikan bahwa GetSalary() bekerja dengan cara yang sama, baik saat kamu memanggilnya pada satu karyawan maupun pada seluruh departemen: pola Composite memungkinkan kamu memperlakukan individu dan kelompok secara seragam melalui interface yang sama!

Coba sendiri

package main

import "fmt"

func main() {
	// Baca jumlah karyawan
	var numEmployees int
	fmt.Scanln(&numEmployees)

	// Simpan semua komponen (karyawan dan departemen) sesuai urutan pembuatannya
	var components []OrgComponent

	// TODO: Baca nama dan gaji setiap karyawan
	// Buat instance Employee dan tambahkan ke slice components
	for i := 0; i < numEmployees; i++ {
		var name string
		var salary int
		fmt.Scanln(&name)
		fmt.Scanln(&salary)
		// TODO: Buat karyawan dan tambahkan ke components
	}

	// Baca jumlah departemen
	var numDepartments int
	fmt.Scanln(&numDepartments)

	// TODO: Baca nama, jumlah anggota, dan indeks anggota setiap departemen
	// Buat instance Department, tambahkan anggota berdasarkan indeks, lalu tambahkan ke components
	for i := 0; i < numDepartments; i++ {
		var deptName string
		var memberCount int
		fmt.Scanln(&deptName)
		fmt.Scanln(&memberCount)
		// TODO: Buat departemen, baca indeks anggota, tambahkan anggota, lalu tambahkan ke components
	}

	// Baca indeks terakhir untuk query
	var queryIndex int
	fmt.Scanln(&queryIndex)

	// TODO: Cetak nama komponen dan total gajinya dalam format: [name]: [salary]
	// Contoh: fmt.Printf("%s: %d\n", name, salary)
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Go online