Pola Strategy
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 90 dari 107.
Pola Strategy memungkinkan kamu mendefinisikan sekumpulan algoritma, mengenkapsulasi setiap algoritma, dan membuatnya dapat saling dipertukarkan saat program berjalan. Berbeda dengan Observer, saat beberapa object bereaksi terhadap satu peristiwa, Strategy memungkinkan satu object beralih secara dinamis di antara berbagai perilaku.
Di Go, kita menerapkan Strategy dengan mendefinisikan interface untuk algoritma dan memasukkan implementasi yang berbeda ke dalam struct konteks:
type PaymentStrategy interface {
Pay(amount float64) string
}
type CreditCard struct{}
func (c CreditCard) Pay(amount float64) string {
return fmt.Sprintf("Paid %.2f via Credit Card", amount)
}
type PayPal struct{}
func (p PayPal) Pay(amount float64) string {
return fmt.Sprintf("Paid %.2f via PayPal", amount)
}Struct konteks menyimpan referensi ke interface strategi, sehingga algoritma dapat diganti tanpa mengubah kode konteks:
type Checkout struct {
strategy PaymentStrategy
}
func (c *Checkout) SetStrategy(s PaymentStrategy) {
c.strategy = s
}
func (c *Checkout) ProcessPayment(amount float64) string {
return c.strategy.Pay(amount)
}Sekarang kamu bisa mengubah metode pembayaran saat program berjalan:
checkout := &Checkout{}
checkout.SetStrategy(CreditCard{})
fmt.Println(checkout.ProcessPayment(100.00)) // Berhasil membayar 100.00 dengan Credit Card
checkout.SetStrategy(PayPal{})
fmt.Println(checkout.ProcessPayment(50.00)) // Berhasil membayar 50.00 dengan PayPalStrategy ideal digunakan saat kamu memiliki beberapa cara untuk melakukan operasi dan perlu memilih salah satunya berdasarkan input pengguna, konfigurasi, atau kondisi saat runtime. Kasus penggunaan yang umum mencakup algoritma pengurutan, method kompresi, dan aturan validasi.
Tantangan
MudahMari bangun sistem pemformatan teks menggunakan pola Strategy! Kamu akan membuat berbagai strategi pemformatan yang dapat diganti saat program berjalan, sehingga pemroses teks yang sama dapat menghasilkan gaya output yang berbeda tanpa mengubah kode intinya.
Kamu akan mengatur kodemu dalam tiga file:
formatter.go: Definisikan interface strategi dan strategi pemformatan konkret.Buat interface
TextFormatterdengan methodFormat(text string) stringyang mengubah teks sesuai aturan strategi.Implementasikan tiga strategi pemformatan:
UppercaseFormatter: mengubah semua teks menjadi huruf kapitalSnakeCaseFormatter: mengubah spasi menjadi garis bawah dan membuat teks menjadi huruf kecilTitleFormatter: membuat huruf pertama setiap kata menjadi huruf kapital (kata dipisahkan oleh spasi)
processor.go: Buat struct konteks yang menggunakan strategi pemformatan.Buat struct
TextProcessoryang menyimpan strategiTextFormatter. Tambahkan method berikut:SetFormatter(f TextFormatter)untuk mengubah strategi pemformatan yang aktifProcess(text string) stringyang menerapkan formatter saat ini pada teks
Buat juga constructor
NewTextProcessor()yang mengembalikan pemroses tanpa formatter awal.main.go: Tunjukkan cara mengganti strategi saat program berjalan.Baca teks, lalu baca jumlah operasi pemformatan. Untuk setiap operasi, baca tipe format (
upper,snake, atautitle), tetapkan formatter yang sesuai pada pemrosesmu, proses teks asli, lalu cetak hasilnya.
Input berikut akan diberikan:
- Baris 1: Teks yang akan diformat
- Baris 2: Jumlah operasi pemformatan
- Baris berikutnya: Tipe format untuk setiap operasi
Misalnya, jika diberikan:
hello world today
3
upper
snake
titleOutputmu seharusnya:
HELLO WORLD TODAY
hello_world_today
Hello World TodayDan jika diberikan:
Go Programming Language
2
snake
upperOutputmu seharusnya:
go_programming_language
GO PROGRAMMING LANGUAGEDan jika diberikan:
design patterns are useful
1
titleOutputmu seharusnya:
Design Patterns Are UsefulPerhatikan bagaimana TextProcessor yang sama menghasilkan output yang benar-benar berbeda hanya dengan mengganti strategi formatter-nya. Pemroses tidak mengetahui atau memedulikan formatter tertentu yang digunakannya. Pemroses hanya mendelegasikan tugas kepada strategi yang sedang ditetapkan!
Coba sendiri
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Baca teks yang akan diformat
text, _ := reader.ReadString('\n')
text = strings.TrimSpace(text)
// Baca jumlah operasi
countStr, _ := reader.ReadString('\n')
count, _ := strconv.Atoi(strings.TrimSpace(countStr))
// Buat pemroses teks baru
processor := NewTextProcessor()
// Proses setiap operasi pemformatan
for i := 0; i < count; i++ {
formatType, _ := reader.ReadString('\n')
formatType = strings.TrimSpace(formatType)
// TODO: Berdasarkan formatType ("upper", "snake", atau "title"),
// atur pemformat yang sesuai pada pemroses
// dan cetak teks yang telah diproses
}
}
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 Generik13Pola Desain Bagian 1
Pengantar Pola DesainPola SingletonPola FactoryPola Abstract FactoryPola ObserverPola Strategy2Mendalami 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 File3Pointer 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