Menu
CoddyTech

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.

challenge icon

Tantangan

Mudah

Mari 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 GameSettings harus menyimpan tiga pengaturan sebagai anggota privat: difficulty (string), volume (bilangan bulat dari 0-100), dan fullscreen (boolean). Inisialisasi dengan nilai default: "Normal", 50, dan false.

    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 difficulty
    • setVolume(int vol): memperbarui volume
    • setFullscreen(bool fs): memperbarui mode fullscreen
    • displaySettings(): menampilkan semua pengaturan saat ini
  • GameModule.h: Buat module terpisah yang mengakses singleton.

    Definisikan fungsi bernama applyGamePreset yang menerima nama preset (string). Fungsi ini harus mengakses singleton GameSettings dan mengonfigurasinya berdasarkan preset:

    • "casual": mengatur difficulty ke "Easy", volume ke 70, fullscreen ke false
    • "competitive": mengatur difficulty ke "Hard", volume ke 30, fullscreen ke true
    • 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:

    1. Nama preset (string)
    2. 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 applyGamePreset dan 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: no

Dengan input competitive dan 20:

Difficulty: Normal
Volume: 50
Fullscreen: no

Difficulty: Hard
Volume: 30
Fullscreen: yes

Difficulty: Hard
Volume: 20
Fullscreen: yes

Perhatikan 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;
}
quiz iconUji dirimu

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

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online