pengantar
Katakanlah kita memiliki sekumpulan objek dengan beberapa data, dan kita perlu memanipulasi objek-objek ini.
Misalkan contoh paling umum adalah mengisi keranjang dengan buah. Kami akan menerapkan kelas art tertentu, di mana kami akan menambahkan buah-buahan. Selanjutnya, kita membutuhkan buah kelas dasar, untuk menentukan parameter volume, yang akan kita berikan nilai tergantung pada buahnya. Masalahnya terpecahkan, buah ditambahkan hingga volume keranjang mencapai ambang batas.
Setelah beberapa iterasi, ketika program kami, untuk mengisi keranjang, telah melipat beberapa pir busuk, apel dengan cacing, atau ada yang salah, kami akan memperluas kelas Buah dasar, menambahkan parameter kesegaran, kemurnian, dll. Ke dalamnya, sementara baru kondisi verifikasi muncul.
Dan di sinilah masalahnya dimulai. Ya, kelas kami telah menjadi lebih fleksibel, tetapi tidak hanya jumlah masalah dengan buah yang dapat meningkat, tetapi situasi pemetikan buah sendiri dapat berbeda. Misalnya, kami memetik buah-buahan yang setiap buahnya benar-benar segar. Mengapa dalam hal ini kita membutuhkan ladang yang bertanggung jawab atas kesegaran, jika semua buah diketahui segar? Untuk memagari fungsionalitas ekstra untuk menunjukkan tipe wajib dan opsional? - Tentu saja tidak. Kami menempatkan sejumlah tipe opsional ke dalam array (kamus), di mana setiap tipe tidak langsung menjadi bagian dari kelas. Fungsionalitas kami lebih pintar lagi, hebat.
Namun, saya memutuskan untuk melangkah lebih jauh dan mengembangkan topik ini sedikit.
Ide
Kami mendefinisikan tipe yang akan bertanggung jawab untuk menyimpan variabel opsional dalam format string. Faktanya, ini adalah pembungkus atas sebuah array. Sebagai sekumpulan informasi minimum, kita akan menyimpan nama variabel, tipe (bisa berupa dasar, int, string, bool, atau komposisi dari beberapa yang dasar) dan nilai.
Metode objek ini bisa bervariasi, tetapi saya telah menyoroti yang berikut untuk saya sendiri:
mendapatkan daftar variabel dan tipenya dalam format string (secara umum, Anda dapat membatasi diri pada nama). Ini bisa berguna jika kita ingin menandai beberapa objek dengan "origin".
getter yang mengembalikan array kita dengan informasi tentang variabel dalam format konstan.
mendapatkan id dari tipe dan nilai dengan nama variabel (diperlukan untuk mentransmisikan ke tipe tertentu).
class IVariable
{
public:
using Type = std::variant < int, double, bool, std::string>; //
virtual std::vector < std::pair < std::string_view, std::string_view > > abstract() = 0;
virtual std::vector < std::tuple < std::string_view, VarTypes, std::string_view > > released() = 0;
virtual std::pair < VarTypes, std::string_view > released(const std::string_view& name) = 0;
};
, , :
, "" , .
, ""
bool tryVector(const std::string_view& dX)
{
auto type = range.front()->released(dX);
if(type.first == VarTypes::_null)
{
return false;
}
for(auto&& var : _range)
{
if(var->released(dX).first != type.first)
{
return false;
}
}
return true;
}
, ( tryVector).
, , , .
, , .
Kemampuan untuk menyesuaikan lingkup kerja dengan objek, ketika, tergantung pada situasinya, kita membutuhkan lebih banyak parameter, atau sebaliknya, lebih sedikit.
Pikirkan bukan tentang bagaimana mendesain suatu objek, tetapi tentang tindakan apa yang harus dilakukan dengan objek tersebut
kerugian
Tidak cocok untuk menghitung sejumlah besar objek dengan tipe yang sama. Misalnya, untuk beberapa kelas yang menentukan komponen rgb dari sebuah piksel, akan lebih efisien untuk mendefinisikan properti secara eksplisit.
Pendekatan semacam itu akan menghabiskan banyak memori, dan, karenanya, masuk akal untuk menggunakannya hanya untuk bekerja dengan objek, yang esensinya tidak dapat diekspresikan dalam beberapa variabel sederhana, yaitu. lebih untuk pemrosesan objek secara logis daripada kalkulasi langsung.