🏗️ Как используется паттерн простая фабрика в исходниках хромиума Почти год назад я говорил, что паттерн "простая фабрика" используется в исходниках хромиума, и вот у меня появилось желание дошли руки написать об этом.
Этот паттерн используется в реализации всем нам знакомого (кроме бэкендеров) метода document.createElement('div').
Вместо длинного списка switch/case у нас тут словарь, где по имени тега выбирается функция-конструктор и сразу вызывается.
Код целиком можно посмотреть вот здесь 🔗.
`// html_element_factory.cc
static void CreateHTMLFunctionMap() { DCHECK(!g_html_constructors); g_html_constructors = new HTMLFunctionMap;
// таблица соответствий тегов и функций-конструкторов static const CreateHTMLFunctionMapData data[] = { // тут конструкторы всех тегов div/span/ul/li/button/h1... { html_names::kDivTag, HTMLDivConstructor }, { html_names::kSpanTag, HTMLSpanConstructor }, { html_names::kMainTag, HTMLMainConstructor }, { html_names::kUlTag, HTMLUlConstructor }, { html_names::kLiTag, HTMLLiConstructor }, { html_names::kButtonTag, HTMLButtonConstructor }, { html_names::kCanvasTag, HTMLCanvasConstructor }, { html_names::kH1Tag, HTMLH1Constructor }, // .... и так далее };
for (size_t i = 0; i < std::size(data); i++) g_html_constructors->Set(data[i].tag.LocalName(), data[i].func); }
// функция — фабрика элементов HTMLElement* HTMLElementFactory::Create( const AtomicString& local_name, Document& document, const CreateElementFlags flags) { if (!g_html_constructors) CreateHTMLFunctionMap();
// находим функцию-конструктор по имени тега auto it = g_html_constructors->find(local_name); if (it == g_html_constructors->end()) return nullptr; HTMLConstructorFunction function = it->value;
// создаем элемент return function(document, flags); }
Но это не самое интересное 🕵️♂️.
Я достаточно долго искал этот код на гитхабе. И не потому что мне было плохо, когда я пытался читать C++ код. Я видел, что HTMLELementFactory::Create вызывается, но описания самой функции в коде нет.
Дело в том, что файл html_element_factory.cc, часть которого я привел выше — генирируется при билде. Я написал нескольким разработчикам хромиума, и пара из них скинула мне вот эту ссылку, где я смог посмотреть все исходники, включая сгенирированные.
А генирируется html_element_factory.cc на основе: - 📜 HTMLTagNames.in — списка тегов - 🏗️ ElementFactory.cpp.tmpl — шаблон файла фабрики
@cherkashindev`