Pola Template Method
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 94 dari 107.
Pola Template Method mendefinisikan kerangka algoritma dalam tipe dasar, sehingga subtipe dapat mengganti langkah-langkah tertentu tanpa mengubah struktur keseluruhan. Decorator menambahkan perilaku dengan membungkus object, sedangkan Template Method mengontrol alur algoritma dan memungkinkan penyesuaian setiap langkah.
Di Go, karena tidak ada pewarisan, kita menerapkan pola ini menggunakan penyematan struct yang dipadukan dengan interface. Struct "template" menentukan struktur algoritma dan memanggil method yang bisa disesuaikan:
type DataProcessor interface {
ReadData() string
ProcessData(data string) string
SaveData(result string) string
}
type BaseProcessor struct {
Impl DataProcessor
}
func (b *BaseProcessor) Execute() string {
data := b.Impl.ReadData()
result := b.Impl.ProcessData(data)
return b.Impl.SaveData(result)
}Implementasi konkret menyediakan versinya sendiri untuk setiap langkah, sementara alur algoritma tetap tidak berubah:
type CSVProcessor struct{}
func (c CSVProcessor) ReadData() string { return "csv-data" }
func (c CSVProcessor) ProcessData(d string) string { return "processed-" + d }
func (c CSVProcessor) SaveData(r string) string { return "Saved: " + r }
type JSONProcessor struct{}
func (j JSONProcessor) ReadData() string { return "json-data" }
func (j JSONProcessor) ProcessData(d string) string { return "parsed-" + d }
func (j JSONProcessor) SaveData(r string) string { return "Stored: " + r }Method template Execute mengatur langkah-langkah dalam urutan tetap:
csvProc := &BaseProcessor{Impl: CSVProcessor{}}
fmt.Println(csvProc.Execute()) // Disimpan: processed-csv-data
jsonProc := &BaseProcessor{Impl: JSONProcessor{}}
fmt.Println(jsonProc.Execute()) // Disimpan: parsed-json-dataTemplate Method cocok digunakan saat kamu memiliki algoritma yang memiliki struktur sama, tetapi berbeda pada langkah-langkah tertentu, seperti pipeline impor/ekspor data, generator laporan, atau framework pengujian.
Tantangan
MudahMari buat sistem pembuatan laporan menggunakan pola Template Method! Kamu akan membuat framework tempat berbagai jenis laporan mengikuti proses pembuatan yang sama, yaitu mengumpulkan data, memformatnya, dan menghasilkan output, tetapi setiap jenis laporan menyesuaikan langkah-langkah ini dengan cara yang berbeda.
Kamu akan menyusun kodemu dalam tiga file:
report.go: Definisikan interface dan pemroses dasar yang mengatur algoritma pembuatan laporan.Buat interface
ReportGeneratordengan tiga method yang mewakili langkah-langkah pembuatan laporan:GatherData() string: mengambil data mentah untuk laporanFormatData(data string) string: mengubah data ke dalam format laporanOutputReport(formatted string) string: menghasilkan pesan output akhir
Buat struct
ReportProcessoryang menyimpan implementasiReportGenerator. Tambahkan methodGenerate() stringyang menjalankan ketiga langkah secara berurutan: mengumpulkan, memformat, lalu menghasilkan output, kemudian mengembalikan hasil akhir.generators.go: Implementasikan generator laporan konkret yang menyesuaikan setiap langkah.Buat dua jenis laporan:
SalesReportdengan fieldRegion(string)GatherData()mengembalikansales-data-[region]FormatData(data)mengembalikanSALES REPORT: [data]OutputReport(formatted)mengembalikanPrinted: [formatted]
InventoryReportdengan fieldWarehouse(string)GatherData()mengembalikaninventory-[warehouse]FormatData(data)mengembalikan*** [data] ***OutputReport(formatted)mengembalikanExported: [formatted]
main.go: Tunjukkan bagaimana struktur algoritma yang sama menghasilkan hasil berbeda berdasarkan implementasinya.Baca jenis laporan (
salesatauinventory) dan nilai konfigurasi (region untuk sales, warehouse untuk inventory). Buat generator yang sesuai, bungkus denganReportProcessor, panggilGenerate(), lalu cetak hasilnya.
Input berikut akan diberikan:
- Baris 1: Jenis laporan (
salesatauinventory) - Baris 2: Nilai konfigurasi (nama region atau nama warehouse)
Contohnya, jika diberikan:
sales
NorthOutput kamu seharusnya:
Printed: SALES REPORT: sales-data-NorthDan jika diberikan:
inventory
MainHubOutput kamu seharusnya:
Exported: *** inventory-MainHub ***Dan jika diberikan:
sales
WestOutput kamu seharusnya:
Printed: SALES REPORT: sales-data-WestPerhatikan bahwa ReportProcessor selalu memanggil tiga langkah yang sama dalam urutan yang sama, tetapi setiap jenis laporan menyediakan implementasinya sendiri untuk langkah-langkah tersebut. Kerangka algoritmanya tetap, sementara detailnya berbeda. Itulah pola Template Method!
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Baca jenis laporan
scanner.Scan()
reportType := scanner.Text()
// Baca nilai konfigurasi (wilayah atau gudang)
scanner.Scan()
configValue := scanner.Text()
// TODO: Buat generator yang sesuai berdasarkan reportType
// - Jika reportType bernilai "sales", buat SalesReport dengan Region diatur ke configValue
// - Jika reportType bernilai "inventory", buat InventoryReport dengan Warehouse diatur ke configValue
// TODO: Buat ReportProcessor dengan generator tersebut
// TODO: Panggil Generate() dan cetak hasilnya
_ = reportType
_ = configValue
fmt.Println("TODO: Generate and print the report")
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File11Pustaka Standar & OOP
io.Reader & io.Writersort.InterfaceAntarmuka fmt.Stringerencoding/json dengan StructAntarmuka http.HandlerRingkasan, Model REST API14Pola Desain Bagian 2
Pola CommandPola AdapterPola DecoratorPola Template MethodPola StatePola CompositeMiddleware sebagai Decorator3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online