Чему я хочу вас научить в теме проектирования? О чём это вообще?

МЕНЮ


Главная страница
Поиск
Регистрация на сайте
Помощь проекту
Архив новостей

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


2022-05-04 12:56

разработка по

Классическая работа программистов-джуниоров — это рутинные задачки класса ETL (очистка данных, их конвертация в нужный формат и загрузка в систему/в базу). Это вроде как достаточно хорошо автоматизируется, хотя и на ручную вычитку в компаниях часто сажают немало народа.

На уровне миддлов, и тем более сеньоров, в некотором смысле и ETL, и CRUD сохраняются. Только это уже не прямая перегонка из одного формата в другой с помощью некоторой условно атомарной функции, а возникают некоторые промежуточные представления (абстракции данных), когда мы разбираем исходные данные на кусочки, а потом снова их собираем, но уже совсем по-другому. Тут тоже довольно много можно делать автоматически, однако до полной автоматизации этой области мы ещё очень далеки (в прошлом посте об этом писал).

Так вот, самая главная засада, что именно тут, в этих промежуточных абстракциях, и рождается та самая проектная сложность — это всегда трудно, и у нас нету и пока не предвидится "САПР для программистов", потому что это как раз нечто такое, что в принципе не может быть видимо в коде "напрямую". Именно об этом постоянно пишу в материалах в Сильных Идеях.

Проектирование заключается в том, чтобы корректно перевести высокоуровневое описание (спецификацию, ТЗ) на низкие уровни детализации, семантику конкретного кода. Но даже на небольших проектных объёмах это становится невозможным делать напрямую — под каждой фразой техзадания может скрываться огромная сложность реализации. Напомню из "The Dark Side of Software Engineering" Robert Glass: "Увеличение сложности фич проекта на 25% ведёт к увеличению сложности реализуемого их софта на 100%".

Поэтому в системе быстро возникают различные промежуточные абстракции. Но всё бы ничего, если бы мы не строили эти промежуточные описания на предположениях, а не на фактах.

=

Возьмём Dwarf Fortress. Как известно,

"без выпивки дварфы будут работать всё медленнее и медленнее. Здоровый, не раненный дварф, будет пить исключительно алкоголь, если такой будет в наличии."

"Чтобы изготовить алкоголь на пивоварне, вам понадобится растение (которое можно использовать в изготовлении алкоголя) и пустая бочка. Каждая единица растения приносит 5 единиц алкоголя."

Скажем, у вас есть класс Still, у которого есть полиморфный метод BrewDrink, получающий параметром растения или фрукты, и пустую бочку, которая будет заполнена сваренным пойлом. И вот вы пишете код, в котором реализуется требование "Каждая единица растительного сырья превращается в винокурне в 5 единиц выпивки.", жёстко указывая в коде (или глобальной константой, неважно) коэффициент 5 (целое число). Но это очень слабое предположение, и именно такие предположения вы должны научиться определять и выявлять.

Например, я не хотел бы добавлять в бочку никакие 5 единиц типа Integer , это совершенно случайное предположение. На "Быстрой прокачке ООП", да и в других материалах Сильных Идей, подробно объясняю, в частности, что тут корректен только один подход: в бочке должны храниться значения полиморфного типа "Жидкость" (физически измеряемые в единицах "Литр", и никаких Integer или Float).

Или когда вы пишете дополнительный вывод мыслей дварфов на экран "Thoughts and preferences", и он выглядит как случайные 20 строк, можете ли вы на простом русском языке пояснить, что именно этот код делает? Потому что такое словесное объяснение заставляет вас сказать что-то, что ближе к общему "намерению" кода, чем к его деталям. И вы должны подумать о том, что когда вы (или кто-то другой) посмотрите на эти итоговые 20 строк кода, готовые для отправки в мастер, то будете уверены, что этот код делает именно то, что вы хотите, чтобы он делал.

=

В общем использование целого коэффициента 5 нельзя назвать однозначной ошибкой в проектировании. Это процесс, который можно заводить вообще произвольно далеко. Но это те вещи, которые вам надо держать "локализованными" (строго в рамках семантики домена, пользовательской системы типов).

Потому что однажды вполне может оказаться, что варка некоторых растений обязательно должна выдавать дробные значения (например, не 5 а 5.5), и бочке придётся хранить не целые единицы пойла, а вещественные. И во всех десяти тысячах мест в вашем коде, где используются бочки, вам придётся поменять код, чтобы работать с вещественными значениями. Таким образом, исходное слабое и вроде бы совсем скромное предположение о пяти целых единицах просочилось во все эти места, на которые оно совсем не должно было влиять. Потому что вы слишком явно привязались в коде к внутреннему устройству конкретной фичи.

=

Пример маленький, а в целом, должен отметить, по отчётам занимающихся, ситуация просто катастрофическая даже на уровне проектирования in small в самом классическом ООП :)

Типичное:

"Просил 180, сошлись на 170, хотя я был в проигрышном положении - у меня в резюме стояла цифра "от 160". После Ваших заметок о зп я её убрал;) Сейчас жду оффера по результатам проверки службы безопасности.

Позавчера было собеседование в аутсорс ....ru , тут я уже начал оперировать потенциально существующим оффером, сказал, что рассматриваю от 200. По фидбеку - сказали: тех.часть отлично, по зп подумают.

Сегодня же было абсолютно провальное собеседование в компанию ....com. Провальное потому, что я не был готов к задачам вроде: "задизайните мне по ООП Морской Бой" (с ним ещё +- справился), ....

Главное, что я увидел огромную область, где у меня пропасть в знаниях, буду навёрстывать именно практикой по проектированию ООП. Ну и плюс я не справился со стрессом, мало опыта с лайвкодингом и первый раз на собеседовании просят задизайнить что-то."

Ну, с одной стороны однозначно поддерживаю ребят, прожимающих свою зп 180+, и очень доволен конечно, что мой курс карьеры в этом хорошо помогает :) но дизайнить уровень Морского боя, хм, конечно тоже надо уметь хорошо.

Я кстати начинал одно время готовить для Сильных Идей материалы вот именно по ООП-проектированию, с разбором, по известным играм — какие там классы напрашиваются, как выявлять их, как они связаны, готовим нормальную систему типов короче. Сделал на 90% сокобан (с реализацией на C#), где-то на 30% — Darkest Dungeons (анализ и проектирование), но потом забросил, времени нету. Но видимо, таки придётся возобновлять :)

Летом наверное (сокобан точно),

сейчас заканчиваю последние хвосты по всему циклу "Как понять в программировании всё" (будет ещё бесплатный микро-курс по реляционной модели, + как правильно проектировать UI)

+ поддержку Go на сервер добавил, летом будет как минимум первый курс по алгоритмам на нём доступен

+ переношу в курс для начинающих с нуля VIP-версию, +50% задачек ещё будет (цены заморозил до следующего года!), и добавил туда немного задач из курса Гвидо ван Россума (автор Python), который он лично делал по заказу Агентства национальной безопасности США. Честно говоря, жутко им разочарован: ну для перехода программистов, уже умеющих кодить, на Python, наверное норм, но для начинающих с нуля (а курс именно так построен) он совершенно никудышный. Уже где-то с первых страниц начинаются функции, где используются глобальные переменные; сами функции нечистые (внутри куча выводов в консоль), и т. п. С педагогической точки зрения, в нём собраны все семантические ошибки, которые только не надо делать при обучении начинающих :)

=

Так вот, наиболее правильный (идеальный) подход к написанию программы, когда вы хотите сделать её лёгкой для чтения/понимания, и при этом корректной и надёжной — это использовать (загружать себе в голову) формальные методы, применяемые в теме синтеза программ (PS - Program Synthesis). Они годятся и для рядового кодинга, и например для проектирования API или системы типов, чтобы разработчикам было легко использовать их для написания своих новых программ.

Сермяга в том, что в теме PS доказывается, что алгоритм доказательства формальной корректности/соответствия спецификации синтезированного под неё кода для многих-многих классов задач существует ровно один. Поэтому вполне можно предположить (это не я, это учёные MIT так предполагают :), что наш ум во время чтения кода работает примерно по схожему единственному алгоритму. То есть когда вы обоснованно утверждаете, что ваш код работает именно так, существует единый (и только один) формальный механизм определения соответствия кода и модели (спецификации), и понимания, как они стыкуются/отображаются друг в друга. Таким образом, мы можем многое узнать из PS об алгоритмах идеального написания (генерации) кода, и использовать это всё в качестве думательной машинки, прокси-ума для того, чтобы максимально продуктивно писать код и рассуждать о коде.

=

В теме написания программ, которые сами пишут программы, понимания самого процесса кодогенерации, много алгоритмов имеют отношение к пространству поиска решения. Тут вообще фактически только две-три базовые операции, например из реляционной вычислительной модели (вы же знаете, что реляционное программирование — это лишь немножечко про базы данных, а так то это прежде всего логическое программирование?). Очень полезно с Прологом поэкспериментировать например, с солверами вроде Z3 и т. п. Здесь ключевое — это уметь программировать, подбирая правильные "ограничения", потому что если у вас нет этого абстрактного барьера, и вы имеете свободу в любой момент обращаться к любым байтам в программе, то пространство решений вырастет экспоненциально.

=

Очень хорошим мета-ограничением здесь может выступать конечно система типов. Например, когда мы стараемся сделать большинство "недействительных" состояний непрезентабельными на уровне синтаксиса. Речь о типах в классическом смысле программной инженерии, не из чистой теории типов. Например, система типов, гарантирующая, что доступ к базе данных имеет правильные настройки безопасности.

И когда мы придумываем такие системы типов, детально изучаем предметные области, обнаруживаем хорошие абстракции, то в ходе такой работы обычно и выявляется что-то фундаментальное, по самой глубинной природе вопроса.


Источник: vk.com

Комментарии: