Pola Template Method
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 99 dari 104.
Pola Template Method mendefinisikan kerangka algoritma dalam base class, sehingga subclass dapat mengganti langkah tertentu tanpa mengubah struktur keseluruhan algoritma. Berbeda dengan Strategy, yang mengganti seluruh algoritma, Template Method mempertahankan algoritma tetap sama sambil memungkinkan penyesuaian pada langkah-langkah individual.
Base class mengimplementasikan template method (algoritma) dan memanggil method abstrak atau virtual yang harus disediakan oleh subclass:
#include <iostream>
class DataProcessor {
public:
// Template method: menentukan kerangka algoritma
void process() {
loadData();
processData();
saveResults();
}
virtual ~DataProcessor() = default;
protected:
virtual void loadData() = 0; // Harus diimplementasikan
virtual void processData() = 0; // Harus diimplementasikan
// Hook: bisa ditimpa, dengan perilaku bawaan
virtual void saveResults() {
std::cout << "Saving to default location\n";
}
};
class CSVProcessor : public DataProcessor {
protected:
void loadData() override {
std::cout << "Loading CSV file\n";
}
void processData() override {
std::cout << "Parsing CSV data\n";
}
};
class JSONProcessor : public DataProcessor {
protected:
void loadData() override {
std::cout << "Loading JSON file\n";
}
void processData() override {
std::cout << "Parsing JSON data\n";
}
void saveResults() override {
std::cout << "Saving to cloud storage\n";
}
};
int main() {
CSVProcessor csv;
csv.process(); // Menggunakan saveResults bawaan
JSONProcessor json;
json.process(); // Menggunakan saveResults khusus
}method process() adalah template method, yang menentukan urutan langkah yang tetap. Subclass mengimplementasikan loadData() dan processData() secara berbeda, tetapi urutannya tidak pernah berubah. method saveResults() adalah "hook", yang memiliki implementasi default yang dapat secara opsional ditimpa oleh subclass.
Gunakan Template Method saat kamu memiliki algoritma dengan langkah-langkah yang tetap, tetapi membutuhkan fleksibilitas dalam operasi tertentu, atau saat kamu ingin menghindari duplikasi kode di antara class yang serupa.
Tantangan
MudahMari kita buat sistem Pembuat Laporan menggunakan pola Template Method. Kamu akan membuat framework tempat berbagai jenis laporan (seperti laporan penjualan dan laporan inventaris) mengikuti proses pembuatan yang sama, tetapi setiap jenis laporan menyesuaikan langkah tertentu. Ini adalah skenario yang tepat untuk Template Method: alur kerja keseluruhan tetap, sementara setiap langkah dapat berbeda.
Kamu akan mengatur kodemu dalam tiga file:
ReportGenerator.h: Definisikan class dasar abstrak dengan method template.Buat class
ReportGeneratoryang mendefinisikan kerangka algoritma pembuatan laporan. Method templategenerateReport()harus menjalankan langkah-langkah berikut secara berurutan:gatherData(): virtual murni, harus diimplementasikan oleh subclassformatReport(): virtual murni, harus diimplementasikan oleh subclassaddHeader(): hook dengan perilaku default yang mencetak--- Report ---printReport(): virtual murni, harus diimplementasikan oleh subclass
Method
addHeader()berfungsi sebagai hook yang dapat dipilih subclass untuk di-override guna menyesuaikan header.Reports.h: Implementasikan dua pembuat laporan konkret.Buat class
SalesReportyang:gatherData()mencetakGathering sales data from databaseformatReport()mencetakFormatting sales figuresprintReport()mencetakSales Total: $[amount], dengan amount diteruskan ke constructor
Buat class
InventoryReportyang:gatherData()mencetakScanning inventory recordsformatReport()mencetakOrganizing inventory by categoryaddHeader()meng-override hook untuk mencetak=== Inventory Report ===printReport()mencetakItems in stock: [count], dengan count diteruskan ke constructor
Kedua class harus menerima nilai masing-masing (amount atau count) melalui constructor.
main.cpp: Tunjukkan pola Template Method.Baca dua input:
- Jumlah penjualan (integer)
- Jumlah inventaris (integer)
Buat
SalesReportdengan jumlah penjualan, lalu buat laporannya. Setelah itu, buatInventoryReportdengan jumlah inventaris, lalu buat laporannya. Cetak satu baris kosong di antara kedua laporan agar mudah dibaca.
Contohnya, dengan input 15000 dan 250:
Gathering sales data from database
Formatting sales figures
--- Report ---
Sales Total: $15000
Scanning inventory records
Organizing inventory by category
=== Inventory Report ===
Items in stock: 250Dengan input 8500 dan 120:
Gathering sales data from database
Formatting sales figures
--- Report ---
Sales Total: $8500
Scanning inventory records
Organizing inventory by category
=== Inventory Report ===
Items in stock: 120Perhatikan bahwa kedua laporan mengikuti urutan langkah yang sama persis seperti yang ditentukan dalam generateReport(), tetapi masing-masing mengimplementasikan langkah-langkah tersebut dengan cara berbeda. InventoryReport juga menunjukkan cara meng-override method hook untuk menyesuaikan header, sedangkan SalesReport menggunakan perilaku default. Inilah pola Template Method: struktur algoritma ditetapkan di class dasar, tetapi detailnya fleksibel.
Coba sendiri
#include <iostream>
#include "Reports.h"
using namespace std;
int main() {
// Baca input
int salesAmount;
int inventoryCount;
cin >> salesAmount;
cin >> inventoryCount;
// TODO: Buat SalesReport dengan salesAmount lalu hasilkan laporannya
// TODO: Cetak satu baris kosong di antara laporan
// TODO: Buat InventoryReport dengan inventoryCount lalu hasilkan laporannya
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk11Konsep OOP Lanjutan
Komposisi vs PewarisanMixin melalui CRTPIdiom PimplPenghapusan TipeKelas Enum dan Pengetikan KuatPenanganan Pengecualian dalam OOPHierarki Pengecualian Kustom14Pola Desain Bagian 2
Pola CommandPola AdapterPola DecoratorPola Template MethodPola StatePola CompositeRAII sebagai Pola3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online