Pola Singleton
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 91 dari 104.
Pola Singleton memastikan bahwa sebuah class hanya memiliki satu instance di seluruh program dan menyediakan titik akses global ke instance tersebut. Ini berguna untuk sumber daya yang sebaiknya digunakan bersama, seperti pengelola konfigurasi, logger, atau kumpulan koneksi database.
Ide utamanya adalah membuat constructor bersifat private agar tidak ada yang bisa membuat instance secara langsung, lalu menyediakan method static yang mengembalikan satu-satunya instance:
#include <iostream>
#include <string>
class Logger {
private:
std::string logFile;
// Konstruktor privat mencegah pembuatan instance secara langsung
Logger() : logFile("app.log") {}
// Hapus konstruktor salin dan operator penugasan
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
public:
// method statis untuk mengakses satu-satunya instance
static Logger& getInstance() {
static Logger instance; // Dibuat sekali, tetap ada hingga program berakhir
return instance;
}
void log(const std::string& message) {
std::cout << "[LOG] " << message << "\n";
}
};
int main() {
Logger::getInstance().log("Application started");
Logger& logger = Logger::getInstance();
logger.log("Processing data");
}static Logger instance di dalam getInstance() adalah fitur C++11 yang disebut "static ajaib". Fitur ini aman untuk thread dan dijamin hanya diinisialisasi satu kali. Dengan menghapus copy constructor dan assignment operator, kita mencegah siapa pun membuat salinan singleton kita.
Gunakan Singleton secukupnya, karena Singleton memperkenalkan state global yang dapat mempersulit pengujian. Singleton paling cocok untuk resource yang benar-benar digunakan bersama, karena memiliki beberapa instance dapat menimbulkan masalah.
Tantangan
MudahMari buat singleton GameSettings yang mengelola konfigurasi aplikasi game. Ini adalah kasus penggunaan yang tepat untuk pola Singleton. Kamu menginginkan tepat satu pengelola pengaturan yang dapat diakses oleh semua bagian game, sehingga konfigurasi tetap konsisten di seluruh bagian.
Kamu akan menyusun kodemu dalam tiga file:
GameSettings.h: Definisikan class singleton yang mengelola konfigurasi game.Class
GameSettingsharus menyimpan tiga pengaturan sebagai anggota privat:difficulty(string),volume(bilangan bulat dari 0-100), danfullscreen(boolean). Inisialisasi dengan nilai default:"Normal",50, danfalse.Terapkan pola Singleton dengan benar:
- Buat constructor menjadi privat
- Hapus copy constructor dan operator assignment
- Sediakan method statis
getInstance()yang mengembalikan referensi ke satu-satunya instance
Tambahkan method publik berikut untuk berinteraksi dengan pengaturan:
setDifficulty(const std::string& diff): memperbarui difficultysetVolume(int vol): memperbarui volumesetFullscreen(bool fs): memperbarui mode fullscreendisplaySettings(): menampilkan semua pengaturan saat ini
GameModule.h: Buat module terpisah yang mengakses singleton.Definisikan fungsi bernama
applyGamePresetyang menerima nama preset (string). Fungsi ini harus mengakses singletonGameSettingsdan mengonfigurasinya berdasarkan preset:"casual": mengatur difficulty ke"Easy", volume ke70, fullscreen kefalse"competitive": mengatur difficulty ke"Hard", volume ke30, fullscreen ketrue- Preset lainnya: mempertahankan pengaturan default tanpa perubahan
Ini menunjukkan cara berbagai bagian program dapat mengakses dan mengubah instance singleton yang sama.
main.cpp: Satukan semuanya untuk menunjukkan singleton beraksi.Baca dua input:
- Nama preset (string)
- Tingkat volume kustom (bilangan bulat)
Pertama, tampilkan pengaturan default awal dengan memanggil
displaySettings()pada singleton. Cetak satu baris kosong setelahnya.Kemudian terapkan preset menggunakan fungsi
applyGamePresetdan tampilkan pengaturan sekali lagi. Cetak satu baris kosong setelahnya.Terakhir, ubah hanya volume menggunakan nilai input kustom, lalu tampilkan pengaturan akhir.
Method displaySettings() harus menghasilkan output dengan format persis seperti ini:
Difficulty: [value]
Volume: [value]
Fullscreen: [yes/no]Contohnya, dengan input casual dan 85:
Difficulty: Normal
Volume: 50
Fullscreen: no
Difficulty: Easy
Volume: 70
Fullscreen: no
Difficulty: Easy
Volume: 85
Fullscreen: noDengan input competitive dan 20:
Difficulty: Normal
Volume: 50
Fullscreen: no
Difficulty: Hard
Volume: 30
Fullscreen: yes
Difficulty: Hard
Volume: 20
Fullscreen: yesPerhatikan bagaimana main.cpp dan GameModule.h sama-sama mengakses instance singleton yang sama: perubahan yang dibuat di satu tempat akan terlihat di semua tempat. Inilah keunggulan pola Singleton untuk sumber daya bersama seperti pengaturan game.
Coba sendiri
#include <iostream>
#include <string>
#include "GameSettings.h"
#include "GameModule.h"
using namespace std;
int main() {
// Baca input
string presetName;
int customVolume;
cin >> presetName;
cin >> customVolume;
// TODO: Dapatkan instance singleton GameSettings
// TODO: Tampilkan pengaturan bawaan awal
// TODO: Cetak baris kosong
// TODO: Terapkan preset menggunakan fungsi applyGamePreset
// TODO: Tampilkan pengaturan setelah menerapkan preset
// TODO: Cetak baris kosong
// TODO: Ganti nilai volume dengan customVolume
// TODO: Tampilkan pengaturan akhir
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 Karyawan10Gambaran Umum STL
Gambaran Umum dan Filosofi STLKontainer STLIteratorAlgoritma STLFunctor dan Ekspresi LambdaRangkuman: Frekuensi Kata13Pola Desain Bagian 1
Pengantar Pola DesainPola SingletonFactory dan Abstract FactoryPola BuilderPola ObserverPola Strategy2Manajemen 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 Bentuk3Konstruktor & 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