Pola Command
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 96 dari 104.
Pola Command membungkus permintaan sebagai object, sehingga kamu dapat mengatur client dengan berbagai permintaan, mengantrekan operasi, atau mendukung fungsi pembatalan. Pola ini memisahkan object yang memanggil operasi dari object yang mengetahui cara menjalankannya.
Pola ini memiliki empat komponen utama: antarmuka Perintah dengan metode execute(), Perintah Konkret yang menerapkan tindakan tertentu, Penerima yang melakukan pekerjaan sebenarnya, dan Pemanggil yang memicu perintah:
#include <iostream>
#include <memory>
#include <vector>
// Penerima: tahu cara menjalankan operasi
class Light {
public:
void turnOn() { std::cout << "Light is ON\n"; }
void turnOff() { std::cout << "Light is OFF\n"; }
};
// Antarmuka perintah
class Command {
public:
virtual void execute() = 0;
virtual void undo() = 0;
virtual ~Command() = default;
};
// Perintah konkret
class LightOnCommand : public Command {
Light& light;
public:
LightOnCommand(Light& l) : light(l) {}
void execute() override { light.turnOn(); }
void undo() override { light.turnOff(); }
};
class LightOffCommand : public Command {
Light& light;
public:
LightOffCommand(Light& l) : light(l) {}
void execute() override { light.turnOff(); }
void undo() override { light.turnOn(); }
};
// Pemanggil
class RemoteControl {
std::vector<std::unique_ptr<Command>> history;
public:
void pressButton(std::unique_ptr<Command> cmd) {
cmd->execute();
history.push_back(std::move(cmd));
}
void pressUndo() {
if (!history.empty()) {
history.back()->undo();
history.pop_back();
}
}
};Setiap perintah menyimpan referensi ke penerimanya dan memanggil method yang sesuai saat dijalankan. Pemanggil tidak tahu tindakan apa yang akan terjadi, ia hanya memanggil execute(). Dengan menyimpan perintah dalam riwayat, kamu dapat dengan mudah menerapkan pembatalan dengan memanggil method undo() setiap perintah.
Gunakan Command saat kamu perlu mengantrekan operasi, menerapkan undo/redo, atau memisahkan pengirim permintaan dari penangan permintaan tersebut.
Tantangan
MudahMari buat Editor Teks dengan fungsi pembatalan menggunakan pola Command. Kamu akan membuat sistem yang mengemas operasi penyuntingan, seperti menyisipkan dan menghapus teks, sebagai object perintah. Dengan begitu, pengguna dapat menjalankan tindakan lalu membatalkannya dengan urutan terbalik, seperti di editor teks sungguhan.
Kamu akan menyusun kodemu dalam empat file:
TextDocument.h: Buat class penerima yang menyimpan dan mengolah konten teks sebenarnya.Class
TextDocumentharus menyimpan konten dokumen sebagai string. Implementasikan method berikut:insertText(const std::string& text): menambahkan teks di akhir kontendeleteText(int count): menghapuscountkarakter terakhir dari konten. Jangan lakukan apa pun jika count melebihi panjang konten.getContent(): mengembalikan konten saat ini sebagai referensi const
Command.h: Definisikan antarmuka perintah dan class perintah konkret.Buat class abstrak
Commanddengan method virtual murniexecute()danundo(), serta destruktor virtual.Lalu implementasikan dua perintah konkret:
InsertCommand: menerima referensi keTextDocumentdan string yang akan disisipkan. Saat dijalankan, perintah ini menyisipkan teks. Saat dibatalkan, perintah ini menghapus jumlah karakter yang sama dengan yang disisipkan.DeleteCommand: menerima referensi keTextDocumentdan jumlah karakter yang akan dihapus. Perintah ini harus menyimpan teks yang dihapus agar dapat memulihkannya saat dibatalkan. Saat dijalankan, perintah ini menghapus karakter dari akhir. Saat dibatalkan, perintah ini menyisipkan kembali teks yang disimpan.
TextEditor.h: Buat pemanggil yang mengelola pelaksanaan perintah dan riwayat.Class
TextEditorharus menyimpan referensi keTextDocumentdan memelihara riwayat perintah yang telah dijalankan menggunakan vectorunique_ptr<Command>. Implementasikan:executeCommand(std::unique_ptr<Command> cmd): menjalankan perintah dan menambahkannya ke riwayatundo(): membatalkan perintah terbaru dan menghapusnya dari riwayat. Jangan lakukan apa pun jika riwayat kosong.showContent(): menampilkan konten dokumen saat ini, atau[empty]jika kontennya kosong
main.cpp: Tunjukkan pola Command dengan fungsi pembatalan.Baca tiga input:
- Teks pertama yang akan disisipkan (string)
- Teks kedua yang akan disisipkan (string)
- Jumlah karakter yang akan dihapus (bilangan bulat)
Buat
TextDocumentdanTextEditor. Lalu lakukan operasi berikut secara berurutan, dan tampilkan konten setelah setiap langkah:- Sisipkan teks pertama, lalu tampilkan konten
- Sisipkan teks kedua, lalu tampilkan konten
- Hapus jumlah karakter yang ditentukan, lalu tampilkan konten
- Batalkan sekali, lalu tampilkan konten
- Batalkan sekali lagi, lalu tampilkan konten
Contohnya, dengan input Hello, World, dan 3:
Hello
Hello World
Hello Wo
Hello World
HelloDengan input Code, Editor, dan 6:
Code
CodeEditor
Code
CodeEditor
CodePerhatikan bahwa setiap perintah mengetahui cara membatalkan tindakannya sendiri. DeleteCommand mengingat teks yang dihapusnya agar dapat memulihkannya, dan InsertCommand mengetahui persis jumlah karakter yang harus dihapus saat dibatalkan. Inilah kekuatan pola Command: operasi menjadi object mandiri yang dapat disimpan, dijalankan, dan dibatalkan.
Coba sendiri
#include <iostream>
#include <string>
#include <memory>
#include "TextDocument.h"
#include "Command.h"
#include "TextEditor.h"
int main() {
// Baca input
std::string firstText;
std::string secondText;
int deleteCount;
std::getline(std::cin, firstText);
std::getline(std::cin, secondText);
std::cin >> deleteCount;
// TODO: Buat TextDocument dan TextEditor
// TODO: Lakukan operasi secara berurutan, lalu tampilkan konten setelah setiap operasi:
// 1. Sisipkan teks pertama, lalu tampilkan konten
// 2. Sisipkan teks kedua, lalu tampilkan konten
// 3. Hapus karakter sebanyak jumlah yang ditentukan, lalu tampilkan konten
// 4. Batalkan sekali, lalu tampilkan konten
// 5. Batalkan sekali lagi, lalu tampilkan konten
// Petunjuk: Gunakan std::make_unique<InsertCommand>(...) dan
// std::make_unique<DeleteCommand>(...) untuk membuat perintah
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