Квинтэссенция ООП

Есть такой известный в широких кругах программист - Джон Кармак. Известен он с 90-х главным образом своими играми - Doom и Quake и многочисленными их потомками.
Так вот он до игры Doom 3 всячески сопротивлялся новомодным веяниям и не использовал язык программирования C++, а использовал язык C.
И вы бы наверное подумали что он не использовал и Объектно-Ориентированное-Программирование?
Как бы не так!
Он давно уже опубликовал исходные коды своих знаменитых игр и там прекрасно видно как он воспроизводит технику ООП на структурах в чистом Си без классов.
Вот так, например: Quake-2/client/qmenu.h at master · id-Software/Quake-2 · GitHub

typedef struct
{
  int type;
  const char *name;
  int x, y;
  menuframework_s *parent;
  int cursor_offset;
  int  localdata[4];
  unsigned flags;

  const char *statusbar;

  void (*callback)( void *self );
  void (*statusbarfunc)( void *self );
  void (*ownerdraw)( void *self );
  void (*cursordraw)( void *self );
} menucommon_s;

typedef struct
{
  menucommon_s generic; // НАСЛЕДОВАНИЕ!!!

  char    buffer[80];
  int      cursor;
  int      length;
  int      visible_length;
  int      visible_offset;
} menufield_s;

Я прям вот комментарием с восклицательными знаками обозначил место где происходит наследование, а указатели на функции сами за себя говорят.
Кармак как минимум в Quake 2 в хвост и гриву использовал объектно-ориентированный подход, просто не хотел перейти на язык максимально дружелюбный к этому. И в Doom 3 перешёл наконец то и был доволен всячески.

Поэтому когда такие зубры и ретрограды не могут всё-таки сопротивляться новомодным (лет 30 как в 2000-ом году) веяниям, то кто тут мы и имеем ли даже вот моральное право говорить “мне оно не нужно”?
Эх…
Говорить то можно конечно, кто запретит, но реально - давайте уже примем как данность, что ООП в каждом тапке имеет право местом быть.

И снова терки за ООП! :wink:
ТС все нормально написал. Спорные моменты коллега Евгений отметил.

ООП это не куча классов и методов, а способ конструирования кода.
Давай попробуем в наших микро-проблемах это показать.

Моргаем светодиодом. Двумя, пятью, семнадцатью. С разными ритмами.
Ясно, что будем концептуально делать объект “светодиод” и передавать ему его программу мограния.
В С++ это сделаем классом. В С структурой или даже массивом, используемым как кортеж.
Это и есть ООП - мышление.
Или озвучиваем меню пищалкой. Пока она исполняет цитату из Баха (или из А-ха) нужно дальше на кнопки реагировать. Так как пищалку делать станем? А чтобы мелодии просто в заголовочном файле новые подключать?

Вы скажете: “Твои примеры на многопоточность” - нет! Шаг машины состояний для этих объектов можно хоть в лууп, хоть на тикер любой повесить, это не проблема. Вопрос в том, как мы их создаем, меняем и масштабируем.
Их код перемешан в итальянское блюдо “Спагетти Болоньезе” с основным кодом проекта, или это вообще отдельные и давно написанные кусочки, которые просто подключаются в проект, меняются, могут быть переписаны без влияния на основной проект. А можно пару “свистоперделок” к мигалке и гуделке добавить? А поменять диод на адресную ленту? А к пищалке добавить корабельный ревун в особых случаях?
ЧТобы в основном коде просто написатть: биипер(Ревун).
Это про мышление в стиле ООП.

Дальше про отладку с стиле “олдскул” и в стиле ООП.
В олдскуле ты проходишь дебаггером, точки останова, шаги и прочее. И интерактивном коде использовать невозможно.
В ООП ты прогоняешь объект отдельно, придумываешь ему юнит тесты. И далее в коде уже не грешишь на него. Если что-то работает не так, как задумано, то ты не тратишь время на копание в отдельно отлаженном объекте. Это в идеале, конечно. Но смысл сказанного в том, что объект не должен иметь сайд эффектов. Никаких. Это отлаживается отдельно.
Ну пока хватит. Работать надо. Йом ришон, как-никак.
Это я прокрастинирую. У меня есть:

  • задача программистская на микроконтроллере.
  • задача программистская -Вэб сайт.
  • задача админская - сложный прокси из Мордора для родителей. А то опенВПН уже многие режут.
  • задача ремонтная - перепаять БП на умной колонке.
  • задача строительная - сварить козырек над дверью в квартиру перед суровой израильской зимой! (не шутка. два месяца ливней, хоть и не холодно)
    БЛИН! Ничего не хочу делать, а хочу тупить в тикток и сраццо на форуме(-ах)!!!

А не надо было валить…
Я вот щас в дополнение к “валяться на диване и сраться в инете” еще и на пьянку поеду. А тебе там, небось. и выпить-то не с кем… евреи одни

5 лайков

это не ТС написал, а я

“проще писать” - нет никаких сомнений.
А вот что касается отлаживать/тестировать/сопровождать/модифицировать, тут уже появляются вопросы. А это 99+% трудозатрат против <1% для “писать”.

А какой в блинке полиморфизм?

Кстати да, я пока тут вожусь со своими домашними хобби сделал для общения по блутуз-свистку вспомогательный класс MicroProtocol с помощью которого лично мне удобно обмениваться с ардуинкой небольшими двоичными пакетами небольшой длины с некоторым контролем ошибок и самовосстановлением после ошибок. Пакеты переменной длины с полезной нагрузкой от 0,5 байта до 15,5 байта при этом эффективная длина пакета от 3 байт до 18 байт. Общий смысл в том, что заголовок это байты в битовой раскладке 0101XXXX NNNNLLLL, где X - это “тип команды” (0-15), L это длина тела, а N это битовая инверсия длины, плюс после тела еще есть банальная контрольная сумма.
Общая схема работы:

if ( mp.input( очередной_байт ) == 0 )
{ // команда прошла все проверки и готова к обработке
  switch ( mp.getType() )
  {
    case 1:
      if ( mp.getLength() > 0 )
      {
         mp[ 0 ] // можно прочитать байт
      }
  };
}

Еще буду допиливать шаблонный метод as(i), но в целом костяк уже сформировался и вот почему я его вспомнил сейчас - в нём есть кусочек ООП-нутого кода:

// 2024.11.30

#ifndef MICRO_PROTOCOL_H
#define MICRO_PROTOCOL_H

#ifdef ARDUINO
#include "Arduino.h"
#else
typedef unsigned char byte;
#endif

class MicroProtocol
{
private:
	enum State
	{
		ReadHeader,
		ReadLength,
		ReadBody,
		ReadChecksum
	};

	State mode = ReadHeader;
	byte index;
	byte body[18] = { 0 };  // max length = header + length + data[15] + checksum

	byte checksum();

public:
	enum Result
	{
		BadChecksum = -3,
		BadLength = -2,
		BadHeader = -1,
		Success = 0,
		Pending = 1
	};

	MicroProtocol()
	{
	};
	~MicroProtocol()
	{
	};

	// Content read/write / Чтение/запись содержимого
	byte &operator[]( byte index ) { return body[index + 2]; };
	
	// Input methods / Методы ввода
	Result input( byte data );
	byte getType() { return body[0] & 0x0F; };
	byte getSize() { return body[1] & 0x0F; };
	void reset() { mode = ReadHeader; };

	// Output methods / Методы вывода
	void setType(byte type) { body[0] = (0xA0 | (type & 0x0F)); };
	void setSize(byte length) { body[1] = (length & 0x0F) | (((~length) & 0x0F) << 4); };
	byte *prepareWrite( byte *outSize );
#ifdef ARDUINO
	void writeToStream(Stream &stream);
#endif

};
#endif

Надеюсь после темы уже понятно где он именно и в чём заключается.

Я, в целом, согласен с мыслью, что “лучше изобрести велосипед, чем ничего не изобрести”, но в таких вопросах, … даже не знаю … кодировка с коррекцией ошибок – настолько “общее место”, там настолько хорошо проработанная математика, вот правда не понимаю, зачем что-то тут изобретать? Тем более, изобретать вещи, которые заведомо хуже существующих.

ну а для надёжности еще и периодически вносить ошибку надо, все контрольные приборы канального уровня так работают и если конкретного % ошибок нет - незачёт )))

Посчитал просто ненужным тут, решил что исключительная простота кода лучше. У меня даже есть пруфлинк что читал 8 класс. Касательные. | WASM Можете сверить ник и дату. :smiley:
Флетчер приглянулся и его напарник, забыл фамилию, но там 16-битные суммы. А вот на хабре нашёл идеальное попадание - 8 бит суммы и буквально пара сдвигов и 99% эффективности, но даже после этого я уже ленивая жопа не стал менять.

Но вообще в приведенном куске кода нет главного - реализации всего самого важного, это был пример для вопроса, а вопрос был - где в этом куске кода притаился ООП?

Между прочим, из этой темы мы можем начать хоронить теорию Дарвина. Ведь суть ООП объясняет сходство классов, – вполне очевидное, – при отсутствии эволюции как таковой – ведь она опровергнута фактурой археологии.

Все просто: классы родственны (т.е похожи) потому что так проще Кодеру, но они отнюдь не произошли друг ото друга, не превращались один в другой. Просто Кодер сделал их похожими. Лень – двигатель прогресса, в любом масштабе. Будь ты хоть сам Бог, если ты не идиот, то ты сторонник ООП.

Забористая шмаль!

Спойлер

Кто то постеснялся подписаться))

1 лайк

Забористая шмаль!
Это типа “возражение”? Или даже “опровержение”? Или "контраргумент? – Как это понимать?

Я вот могу досыпать еще логических коллизий.
Объясните мне ситуацию: вот на Марсе Маск склонен искать бактерии, а не крокодилов. Почему? – Очевидно потому, что они наиболее живучи изо всех организмов У маска к Дарвину нет вопросов при этом? Почему бы ему не искать там организмы посложнее, ведь усложнение по Дарвину, это путь увеличения живучести?

У меня вопрос вот еще есть, к любителям НЛО: на Луне обнаружили правильный ровный куб. “Это явно внеземные цивилизации!” – кричат они. Вопрос в студию: “с чего вы это взяли?”
– Но ведь люди там этого не делали, а это явно творение разума!
– А с чего вы взяли что это “творение разума”?
– Но само собой такое не могло построиться! Природа не создает правильных форм!
– Тоесть природа осилила создать чудо Жизни, со всеми ее “мелкими” чудесами, – типа регенерации, репродукции, разума – ни одно из которых человек не в силах повторить, – но не осилила простой куб?

Такой же вопрос на предмет камней на земле. Почему ровно обструганный камень, явно имеющий признаки обработки с целью специализации в применении, сразу же причисляют к “орудиям труда древних”. Типа “имеет предназначение, – значит творение разума”. Но вот специализацию в животном мире называют тупо “приспособлением”, и упрямо не хотят видеть за ней признака разумной инициативы некоего Творца? – Я ведь пока даже не настаиваю на каком либо “боге”.

Вопрос пока о простоте: что проще – предположить, что

  1. то, что Человек Разумный не в состоянии ни создать ни повторить – появилось само, из Хаоса?
    – Или проще
  2. предположить некоего Создателя, более разумного, чем человек?

Вопрос “кто Создатель” – мы не сейчас не рассматриваем. Пока что разбираемся с базой. С элементарной очевидной логикой.

Дарвин ведь ничего не знал об ООП. Ничего не знал о Генах, представляющих из себя шестеричный математический код. В его поле опыта было единственное объяснение сходству видов – прямое происхождение одних видов от других.

Любой программист на Java скажет, что Дарвин был прав, но не во всем. Классы действительно могут “происходить” один из другого. Но не потому что сами по себе мутируют. А потому что ООП. И археологи могут упокоиться: их никто больше не заставит еще тысячелетия бесплодно рыть землю в поисках обещанных Дарвиным “промежуточных видов”, которых как не было так и нет. – И не будет. Потому что ООП.

Текст не осилил (даже не пытался), поэтому просто отвечу на вопрос. Никаких “опровержений” и “контраргументов”. Вообще никаких предпосылок к диалогу не возникает. Просто констатация бытовой зависти))

1 лайк

Я потщусь предложить еще вариант. Может быть он составит такую предпосылку.
Существует вопрос то ли логический, то ли философский. Так вот он и состоит в том, к какой сфере он, собственно, относится: почему “миллион мух всегда неправ”? Может быть потому, что что люди, не ценящие или не имеющие собственное мнение, не доверяющие собственному разуму, – автоматически принимают позицию большинства? Вы ведь помните, чего стоило сумашедшим одиночкам опровергнуть очевидно бесспорное мнение миллиона мух о том, что земля плоская и солнце вертится вокруг нее… – Не так ли?

То, что таких людей – доверяющих авторитету больших имен или больших толп больше, чем доверяющих собственным глазам и собственному разуму – это история о трусости, или о глупости?

как можно доверять собственным глазам, когда мозг подсовывает тебе видеть, то что ты привык видеть? Правильно! Остановить этот морок! Умеют не все

Только люди с катушкой на голове

2 лайка

тут катушка даже зло! )))

А если это одно и то же. Мать-природа. Совокупность хоть и зависимых, но не субстанциональных законов природы… не более.

Предположим. Проведем умственный эксперимент.
Я ставлю перед собой бутылку водки. Звоню Михалычу: “Михалыч. Мне нужно забор поставить. Шесть метров, два пролета, штакетник. Чисто для умственного эксперимента, тоесть даже столбы заливать не надо, просто вкопать”.

А потом значит у меня стоит вопрос: как ту же самую задачу поставить Матери-природе, и за сколько она справится.

Напомню, мы исследуем разницу в сложности подходов. Помогите Caen’у поставить два метра забора. С помощью Матери-природы.