|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
|
Архитектура приложения: разделение кода на слои22.09.2023, 22:33. Показов 1908. Ответов 34
Метки нет (Все метки)
Здравствуйте!
Подскажите, пожалуйста, по разделению кода программы на слои. Назначение программы — загрузка ("консолидация") в новую базу данных товаров из нескольких других старых баз. Одному товару в новой базе может соответствовать несколько товаров из нескольких старых баз. Так как пользователи разных подразделений вели свои отдельные базы, хотя по сути это один и тот же перечень товаров. Общий алгоритм следующий: 1) Выгружаем из конкретной n-ой базы-источника товары в файл передачи - это делает отдельная утилита. 2) Запускаем нашу программу, в ней выбираем файл передачи (загрузки). 3) Читаем старые товары из файла загрузки, создаем таблицу этих товаров (в памяти) - ТЗ-БД-Источник, и делаем некоторые преобразования. 4) Читает товары из новой базы также в таблицу в памяти ТЗ-БД-Новая, делаем некоторые преобразования. Преобразования в пунктах (3) и (4) нужны для того, чтобы значения полей товаров из разных баз можно было сопоставить друг с другом. 5) Читаем из базы флажки (см. далее) для товаров из базы-источника. Флажки обозначают состояние товара из базы-источника (загружен он уже или еще нет) и что с ним надо делать (надо загружать или нет). Подробнее назначение флажков описано далее. 6) По разным реквизитам (наименование, штрихкод) выполняем поиск соответствия между товарами из текущей базы и из базы-источника (по таблицам ТЗ-БД-Источник, ТЗ-БД-Новая). Это соответствие между товарами пока что "логическое". Результат соответствия, а также флажки, помещаем в специальную таблицу в памяти ТЗ-Соответствие, которую можно представить в виде дерева. Каждый "узел" дерева - это совпадающие реквизиты товаров. Подчиненные строки "узла" этого дерева: первая строка - это товар из источника, вторая строка - это товар в новой базе. 7) В таблице-дереве добавляем специальные колонки для флажков-признаков "проверен", "записывать", "записан" (при первом заполнении они пустые). Пользователь может вкл.\выкл. эти флажки. Значения флажков при переключении должны быть сохранены в базе. Эти флажки обозначают, что надо делать с товаром из базы-источника. 8) Выводим пользователю эту таблицу-дерево с узлами соответствия и флажками. 9) Пользователь смотрит на эту таблицу, проверяет данные: 9.1) Если пользователь убеждается, что соответствие установлено верно и товар надо загружать, он включает флажки "проверено", "записывать". При этом в базу записывается "жесткое" фиксированное соответствие: GUID товара из старой базы, GUID товара из новой базы, признак "записывать" = "Да". 9.2) Если пользователь убеждается, что соответствие установлено верно и товар не надо загружать, он включает признак "проверено", "записывать" выключает. В базу записывается "жесткое" фиксированное соответствие: GUID товара из старой базы, GUID товара из новой базы, и признак "записывать" = "Нет". 9.3) Если соответствия нету, и пользователь решает, что товара из старой базы еще нету в новой базе, он включает признаки "проверено", "записывать". Это значит, что в новой базе надо создать новый товар со сведениями товара из старой базы. В базу записывается просто GUID товара из старой базы и признак "записывать" = "Да". 10) Пользователь нажимает кнопку "Записать". Для каждой строки из списка выделенных строк: — выполняется проверка флажков "проверен" и "записан", если флажки установлены, то выполняется: — запись информации о товаре в базу — запись в таблицу "Флажки" признака "записан" и GUID товара из старой базы, чтобы при повторной работе скрыть уже записанные товары. Вопрос такой. Как правильно разделить этот код на слои View - ViewModel - Model - Repository? В соответствии с пунктами (3)-(6) в памяти надо иметь три таблицы: - "линейная" таблица старых товаров - "линейная" таблица новых товаров - таблица-дерево соответствия старых и новых товаров. По сути это некий "кэш" в памяти. В каком слое программы должны быть эти таблицы? В бизнес-слое? Получается, пользовательский слой должен работать только с таблицей-деревом? Какая должна быть логика взаимодействия между слоями? Например, как выполняется запись в базу товара по узлу соответствия? Программа же должна "поддерживать" наш "кэш" в корректном состоянии. Подскажите, пожалуйста.
0
|
|
| 22.09.2023, 22:33 | |
|
Ответы с готовыми решениями:
34
Разделение приложения на слои. Работа с шаблонными типами
В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу |
|
Модератор
|
|||
| 26.09.2023, 16:31 | |||
|
В WPF тоже можно использовать DataTable в GUI, но это неудобно. И используется только в крайних случаях когда по другому невозможно реализовать. Опять таки, не зная вашей среды разработки я не могу подсказать насколько верным будет собирание Дерева из Таблиц на уровне View. Возможно в вашей среде это и вовсе невозможно. DataTable поддерживает уведомления об изменении строк и ячеек, которые корректно автообнавляют WPF элементы. Поэтому обновление DataTable в Репозитории не вызовет никаких проблем в WPF. Насколько верно это для вашей среды с ValueTable я тоже не могу сказать.
0
|
|||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
|||
| 26.09.2023, 17:25 [ТС] | |||
|
Так-то можно вообще, используя Binding, привязать элемент формы к таблице из Репозитория. Но везде пишут, что это плохо.
0
|
|||
|
Модератор
|
||
| 26.09.2023, 17:56 | ||
|
Например, в "стандартном" WPF-Репозиторий более комфортным является работа с коллекциями сущностей представляющими записи таблиц (более верно парсинг запросов к БД). Но эти же сущности создаёт Репозиторий. Каким образом (EF, Реадер, DataTable) не суть важно. В ваших условиях вам удобнее использовать ValueTable вместо коллекций. Но это же не противоречит функциям репозитория. ValueTable можно возвращать из Репозитория, так же как и DataTable.
0
|
||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
||
| 27.09.2023, 09:13 [ТС] | ||
|
А как эта ValueTable попадет в пользовательский интерфейс? Пользовательский интерфейс ведь не работает (не "общается") с Репозиторием.
0
|
||
|
Модератор
|
||
| 27.09.2023, 13:43 | ||
|
Добавлено через 7 минут Я всё равно не совсем понимаю нюансов вашей среды. Например, в "обычной реализации", в VM+View можно создаться сущность, отредактировать её, после этого послать в Модель, которая её сохранит через Репозиторий. Репозиторий обновит или пересоздаст сущность при сохранении и вернёт её. Если есть какие-то коллекции, то обновлённая сущность записывается во все где она используется. Это достаточно про и понятно для реализации и последующей поддержки. В случае же DataTable, нужно передавать не сущность, а коллекцию данных либо в параметрах метода, либо через словарь. Репозиторий конвертирует их в Строку DataTable. И в такой реализации теряется самая основная "фишка" ООП - сам объект с которым по сути и идёт работа. В вашем случае это так же происходит? И для вашей среды обработки это норм? Там не используется ООП?
0
|
||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
||||||||
| 27.09.2023, 17:19 [ТС] | ||||||||
|
Модель ведь может работать только с объектами бизнес-логики, то есть с сущностями и их коллекциями. Как сюда "втиснуть" ValueTable? Может быть сделать какую-то обертку вокруг ValueTable? Модель будет думать, что это какая-то особенная коллекция. А когда эта коллекция "дойдет" до ViewModel, то ViewModel попытается вызвать у этой коллекции метод типа "GetValueTable()". Насколько такой способ нарушает принципы "правильного" дизайна и взаимодействия View-ViewModel-Model? Какой объект отвечает за обновление коллекций при изменении сущности? Репозиторий? Тогда ему придется "помнить" все коллекции. Так ведь? VM+View умеет работать только с одной сущностью? Разве нету каких-либо "специальных" View и ViewModel, которые умеют работать с коллекциями сущностей? Представьте, если пользователю надо работать с таблицей сущностей. Тогда как будет выполняться этот сценарий для VM+View? Как коллекция сущностей отобразится у пользователя? Как изменения, внесенные пользователем в эту таблицу, "дойдут" до Модели и будут там обработаны? Как я понимаю, в "классическом" ООП для этого нужно делать двойное преобразование данных: - первое выполняет Репозиторий: получает запросом RecordSet и делает из полученного RecordSet-а коллекцию, - а второе преобразование делает ViewModel, когда из коллекции заполняет таблицу на форме. Так? Это множество записей можно назвать как угодно - коллекция, таблица записей, набор записей, массив записей, таблица значений - это не принципиально. Важно то, что DataTable позволяет очень легко показать их пользователю в табличном виде, не выполняя маппинга туда-сюда. В принципе, этот тип может быть использован как основа для реализация коллекции. Один объект - одна строка DataTable. Для Репозитории эта конвертация очень простая. Он ведь скорее всего получает результаты запросов в виде похожем на DataTable, что-то типа RecordSet. Надо просто пройтись по всем строкам RecordSet-а, и каждую запись один-в-один записать в DataTable. Для "обычной" работы Модели Репозиторий по прежнему может возвращать или Сущность или Коллекцию сущностей. Ясно, что какие-то бизнес-правила могут быть реализованы только для объекта. "Классическая" Модель не должна работать с записями DataTable. Она должна получить объект из строки DataTable (пока не понятно как), и затем работать с объектом. А вот для особенных случаев, для оптимизации, когда нужно просто отобразить таблицу данных пользователю можно использовать DataTable. Получается, что DataTable может быть использвана в "одностороннем" порядке - при отображении. Также у меня крутится мысль: а может быть сделать отдельный Репозиторий для работы с DataTable? Модель будет знать, что один Репозиторий - это настоящий для базы данных, а второй - это для временного хранения то есть для DataTable. И модель будет манипулировать ими по необходимости. Надо получить объект из БД - Модель запрашивает Репозиторий-1, надо получить объект из строки DataTable - запрашивает Репозиторий-2. Модель ведь может работать с любым количеством Репозиториев? Но это все мои рассуждения. Как делать правильно - я не знаю ![]() В общем получается такая картина. Во многих средах разработки есть что-то типа DataGridView + DataTable, а также binding. Это очень удобно, производительно. Но это не вписывается в "классический" ООП, DDD, MVVM. Как это совместить?
0
|
||||||||
|
Модератор
|
||||||||||||||||||||
| 27.09.2023, 18:49 | ||||||||||||||||||||
|
Они были созданы тогда когда ещё были слабые нормальные инструменты ООП для такой работы. Сейчас всё это считается "древним хламом" и используется только в каких-то уникальных заданиях. Как выше описывал, например, в EF есть возможность получить локальный кеш таблицы, связать его с ObservableCollection и вернуть её. В таком сценарии View может использовать коллекцию, которую создал и контролирует Репозиторий. Другой сценарий, когда обмен с Репозиторием происходит только единичными сущностями. И формируются независимые коллекции из них на каждом уровне где это нужно. И есть куча ещё других вариантов реализации в которых работают и с коллекциями, и с единичными сущностями. Но невозможно работать ТОЛЬКО с коллекциями. Как, например, тогда менять только одно свойство одной сущности (одно поле одной записи страницы)? Но в основе всегда будет работа с одной сущностью. Вот вам нужно поставить пользовательский флаг проверено. Его же нужно передать в репозиторий, сохранить. Не будете же вы работать исключительно только с коллекциями.Судя по вашему описанию их у вас просто нет. Вся Бизнес-Логика построена вокруг работы с БД. Например, сейчас принято передавать в Модель+Репозиторий сущность:
В реализации с DataTable придётся делать метод с кучей параметров:
Добавлено через 13 минут Если нет никакой Бизнес Логики кроме работы с БД, то по факту вся "работа" (локальной) Модели - это "дирижирование" Репозиториями. Маппинг таблиц в коллекции (если это нужно) следует делать в Репозитории. Но вполне можно работать и напрямую с Таблицами (кешом) на любом уровне. Для Модели разве это важно где, что хранится? Для неё важна только Бизнес Логика, которой в вашем задании не просматривается. Одна из типичных реализаций, когда для каждой таблице (более верно для каждого типа Бизнес Сущностей) создаётся свой отдельный Репозиторий, хотя при этом они все отражают одну и туже БД. ООП и DDD - согласен. DataTable плохо согласуются с принципами. Поэтому в современном Шарпе их используют крайне редко. "Удобно" - как раз таки категорически нет. Именно поэтому и ушли от DataTable. Добавлено через 1 минуту "производительно" - ??? Что вы имеете ввиду под этим? И как определили? В сравнении с логикой и доступом БД, любой способ работы с ней и её отображения будет производительным. Добавлено через 1 минуту А если требуется суперзаточка под БД с многомиллионными пользователями, так там лучше напрямую использовать SQL.
0
|
||||||||||||||||||||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
|||||||||||
| 28.09.2023, 14:39 [ТС] | |||||||||||
|
Конечно, программа должна работать и с Сущностями, и с их коллекциями. Где-то удобно работать с таблицей (например, отображение в табличном виде на форме) - там можно использовать ValueTable. А где-то надо работать с конкретной сущностью. А еще есть мысль ввести Сущность "СоответствиеТоваров", а также Сущность "ФлагиСоответствия". Код будет примерно таким:
Мне кажется, для бизнес-логики "СтарыйТоварИзФайлаПереноса" и "СтарыйТоварИзValueTable" - это разные сущности.
0
|
|||||||||||
|
Модератор
|
|||||
| 28.09.2023, 18:59 | |||||
|
Бизнес логики у вас нет, кроме работы с БД. Если же разработчкик решает, что на уровнях выше нужны таблицы, а не сущности и их коллекции, то создавать сущности только "для правильного ОПП"... большого смысла в этом я не вижу. Вы искусственно вывели это из функций репозитория и никак не можете "отлипнуть" от этой мысли. Пример. У вас есть супербыстрый SSD, который работает быстрее ОЗУ. На нём все таблицы. Смысла создавать кеши нет. То есть промежуточные ValueTable будут не нужны. Понятно, что в этом случае может поменяться реализация Репозитория, так как она зависит от типа Хранилища. Но изменение Хранилища не должно вызывать изменения Модели. В этом весь смысл выделения репозитория из Модели. А вашей реализации придётся менять Модель. И значит вы неверно выделили функционал репозитория из Модели. Добавлено через 14 минут Но несколько моментов. Если мы "правильно работаем в ООП", то мы работаем с объектами. То есть выше модели у нас не int pID, а сам Узел соответствия. В котором не ид старого товара, а сам старый товар.Так же мне не нравится вынос конвертации ConvertData(lOldTovar, lNewTovar);. На мой взгляд это функция Репозитория.
0
|
|||||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
|||
| 04.10.2023, 12:37 [ТС] | |||
|
Конечно же, бизнес-логика в этой программе есть, и достаточно сложная: старые товары (из разных источников), новые товары, соответствие между товарами по сложным "логическим" правилам, "жесткое" соответствие между товарами по ID-шникам, флажки для "отложенной" записи, признак выполнения записи. Просто эта бизнес-логика явно не сформулирована. Я сразу в начале темы поднял вопрос про работу с БД и с таблицами. Поэтому, бизнес-логика осталась "в тени". А оказалось, что многое "завязано" на бизнес-логику. Тут надо подумать. Как-то мало хороших ресурсов и рабочих примеров по построению Модели и архитектуры. Но много спорных неоднозначных статей с очень примитивными примерами ![]() Вы можете порекомендовать какие-нибудь источники по разработке Модели (бизнес-логики), по взаимодействию Модели с другими слоями приложения, по архитектуре в целом? Добавлено через 44 минуты Для конвертации старого товара в новый необходимо, чтобы пользователь указал дополнительные сведения. Эти сведения пользователь указывает в Форме в нескольких полях. При конвертации, значения этих полей должны использоваться как значения реквизитов нового товара в зависимости от значений реквизитов старого товара. Например, при создании нового товара у него нужно сформировать значение реквизита "Организация", который обозначает предприятие, где был произведен этот товар. В старых базах такого реквизита нету. У старого товара "производителя" можно определить по ID-шнику. На форме (или в настройках программы) указывается "маска" ID-шников и соответствующее этой маске имя "производителя". Программа должна при конвертации посмотреть ID-шник старого товара, найти соответствующего "производителя", и записать его для нового товара в поле "Организация". Получается, тут сведения из самого внешнего слоя UI должны "дойти" до самого нижнего слоя Репозитория через бизнес-логику. Это только один "момент" правил нашей конвертации.
0
|
|||
|
Модератор
|
||||
| 04.10.2023, 14:47 | ||||
|
О БЛ, кроме, работы с Хранилищем. Например, игровое приложение. В нём есть логика по сохранению состояния игры, игроков, всех юнитов. А есть ещё логика самой игры - то есть как юниты взаимодействуют друг с другом, как на игру влияют действия игрока. Когда мы говорим об Архитектуре Приложения в ЦЕЛОМ мы выделяем слои Model, View и сопрягающий слой. В этом случае под Бизнес Логикой понимается вся логика и сохранения, и самой игры. Когда мы говорим об более детальной реализации Модели, о том что надо вынести из неё логику работы с Хранилищем, чтобы Игра могла работать и локально, и в сетке, и на Web сервере - тогда мы под БЛ подразумеваем более узкую функциональность, только ту часть логики которая не относится к работе с Хранилищем. Поэтому в вашем случае, Бизнес Логика у вас есть, но она имеет отношение только к работе с Хранилищем. Какой-то иной логики в вашем ТЗ не просматривается. Следовательно и выделение Репозитория из Модели большого смысла не имеет, поскольку ваш Репозиторий по сути это и есть вся ваша Модель. Добавлено через 48 минут Добавлено через 2 минуты Всё. Больше никакой Логики нет.
0
|
||||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
||
| 04.10.2023, 17:05 [ТС] | ||
|
Он только отмечает флажки "Проверен""Записывать", может указать соответствие между старым и новым товарами. А также пользователь заполняет общие поля, не привязанные ни к какому товару. Эти сведения используются программой при автоматической конвертации. Приведу еще пример бизнес-логики. При загрузке данных из файла-переноса программа пытается установить "логическое" соответствие. Например, программа при загрузке формирует "временные" наименования товаров, которые формируются как преобразования оригинальных наименований (удаление лишних символов и преобразование в верхний регистр). Затем программа по этим "вычисленным" наименованиям сравнивает все старые товары со всеми новыми товарами. Допустим, обнаружено соответствие. Тогда программа для такого соответствия формирует "узел". Формат такого узла я описывал выше: первая строка узла - это наименование товара и флажки "Проверен"-"Записывать", вторая строка узла - это данные о старом товаре, третья строка узла - это данные о товаре из текущей БД. Таблица узлов отображается пользователю. Пользователь смотрит на эти узлы, и если считает нужным, отмечает флажок "Записывать". Программа при включении флажка "Записывать", должна в специальную таблицу в БД (таблица соответствий) записать новую запись с ID старого товара и ID нового товара. Это нужно для того, чтобы при следующем сеансе работы программа для этих товаров определила, что между ними уже установлено "жесткое" соответствие и не выполняла поиск "логического" соответствия по наименованиям (так как наименования могут поменяться). Вот какие из описанных действий надо поместить в Репозитории? Какие - в слой Бизнес-логики? Какие - в Модель? Какие Сущности тут надо выделить? Надо ли например выделить отдельную Сущность "ЖесткоеСоответствие"?
0
|
||
|
Модератор
|
|||
| 04.10.2023, 17:36 | |||
|
Редактирование же это не только ввод текста. Это всё относится к логике Репозитория. Мы же с вами разбирались с этим. Если делать максимально верно, то по сути вам нужна Миграция. Да, сложная, Да, требующая многих сравнений, созданий промежуточных типов, но это Миграция. Другой логике в вашем ТЗ нет. Вопрос как это реализовать - это уже больше к вашим знаниям и опыту. Не можете сделать Миграцию средствами БД или Сервера - делайте на локальном клиенте внешней логикой. Но выше уровня Репозитория здесь нет задачи. Не надо "впихивать" не нужные сущности. Дополнительного слоя с выделенной логикой здесь не нужно. Возможно вас вводит в заблуждение типичные массовые примеры по реализации Репозитория, в которых кроме запроса по одной таблице БД ничего нет. Да, это наиболее типичная для Репозитория задача. Но в общем случае задача Репозитория шире. Он не просто возвращает результат запроса, он работает с Бизнес Сущностями, создаёт их, конвертирует в нужные типы, сохраняет и т.д. Запрос к старой БД -> Получение старого товара -> Отправка его в Репозиторий "Узлов". И там именно репозиторий создаёт из бизнес сущности "Старый товар" новый узел или добавляет его в имеющийся.
0
|
|||
|
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
|
||
| 06.10.2023, 12:53 [ТС] | ||
|
Получается, один Репозиторий может "управлять" другим Репозиторием?
0
|
||
|
Модератор
|
|
| 06.10.2023, 22:03 | |
|
zelenprog, есть Репозиторий СЛОЙ и есть Репозиторий для управления каким-то конкретным Хранилищем для Конкретного типа.
Например, в EF DbContext это аккумуляция DbSet'ов. И каждый из них это Репозиторий определенного типа. В вашем случае Репозиторий СЛОЙ тоже состоит из репозиториев по работе с отдельным типами. Ведь по сути общей логики не важно, например, где хранится УЗЕЛ. В таблице загруженной в памяти, в локальном Кеше выделенной БД, в общей БД с остальными данными и др. То есть у нас есть абстракции для Хранилищ нескольких типов: старый товар, узел, новый товар. И есть абстракция по "дерижированию" этими отдельным репозиториями. Внешние потребители работаю с этим "Дирижёром". То есть с точки зрения архитектуры приложения внешний интерфейс Дирижёра, это и есть интерфейс Модели. Но следущий шаг. Есть ли смысл в реализации этого Дирижёра (Модели) отдельно от ViewModel? В чем функция VM? Отразить Модель в своих свойствах. Но если мы не преследуем цели делать мультисборное приложение, то зачем нам в Модели делать абстрактные методы и события, а не сделать Свойства, Команды и события "понимаемые" WPF? Никакого смысла в этом нет. Это будет только реализация ради соблюдения неких идеалов. Поэтому конкретно в вашем задании реализовать можно (и нужно) сразу как VM. В этом случае, что условно мы будем считать Моделью? Остаются только Репозитории типов. Поэтому мы получаем структуру View - View Model - Репозитории.
0
|
|
| 06.10.2023, 22:03 | |
|
Разделение DataSet на разные слои в сервис-ориентированном приложении. Как правильно? Ошибка "в указанном dsn архитектура драйвера и архитектура приложения" Социальная сеть (сложная архитектура): аудио+видео+чаты+обмен данными +приложения (месенджеры и приложения) Слои приложения, использование одного из другого Архитектура приложения Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
|
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
|