Pola Command
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 96 dari 104.
Command pattern mengemas permintaan sebagai object, sehingga kamu dapat mengatur parameter client dengan berbagai permintaan, mengantrekan operasi, atau mendukung fungsi undo. Pola ini memisahkan object yang memanggil operasi dari object yang tahu cara menjalankannya.
Pola ini memiliki empat komponen utama: antarmuka Command dengan method execute(), Concrete Commands yang menerapkan tindakan tertentu, Receiver yang melakukan pekerjaan sebenarnya, dan Invoker 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 undo dengan memanggil method undo() pada setiap perintah.
Gunakan Command saat kamu perlu mengantrekan operasi, menerapkan undo/redo, atau memisahkan pengirim permintaan dari penangan permintaan.
Tantangan
MudahMari buat Editor Teks dengan fitur pembatalan menggunakan pola Command. Kamu akan membuat sistem yang membungkus operasi penyuntingan, seperti menyisipkan dan menghapus teks, sebagai object perintah. Dengan begitu, pengguna dapat menjalankan tindakan lalu membatalkannya dalam urutan terbalik, seperti di editor teks sungguhan.
Kamu akan menyusun kodemu dalam empat file:
TextDocument.h: Buat class penerima yang menyimpan dan mengolah isi teks sebenarnya.Class
TextDocumentharus menyimpan isi dokumen sebagai string. Implementasikan method berikut:insertText(const std::string& text): menambahkan teks di akhir isideleteText(int count): menghapuscountkarakter terakhir dari isi, tidak melakukan apa pun jika count melebihi panjang isigetContent(): mengembalikan isi 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 jumlah karakter yang disisipkan.DeleteCommand: menerima referensi keTextDocumentdan jumlah karakter yang akan dihapus. Perintah ini perlu 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 riwayatnya.Class
TextEditorharus menyimpan referensi keTextDocumentdan memelihara riwayat perintah yang telah dijalankan menggunakan vector berisiunique_ptr<Command>. Implementasikan:executeCommand(std::unique_ptr<Command> cmd): menjalankan perintah dan menambahkannya ke riwayatundo(): membatalkan perintah terbaru dan menghapusnya dari riwayat, tidak melakukan apa pun jika riwayat kosongshowContent(): menampilkan isi dokumen saat ini, atau[empty]jika isinya kosong
main.cpp: Tunjukkan pola Command dengan fitur 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 isi setelah setiap langkah:- Sisipkan teks pertama, lalu tampilkan isi
- Sisipkan teks kedua, lalu tampilkan isi
- Hapus jumlah karakter yang ditentukan, lalu tampilkan isi
- Batalkan sekali, lalu tampilkan isi
- Batalkan sekali lagi, lalu tampilkan isi
Misalnya, dengan input Hello, World, dan 3:
Hello
Hello World
Hello Wo
Hello World
HelloDengan input Code, Editor, dan 6:
Code
CodeEditor
Code
CodeEditor
CodePerhatikan bagaimana setiap perintah tahu cara membatalkan tindakannya sendiri. DeleteCommand mengingat apa yang dihapus agar dapat memulihkannya, sedangkan InsertCommand tahu persis berapa banyak karakter yang harus dihapus saat pembatalan. Inilah keunggulan 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 sejumlah karakter 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