Раз уж кстати об этом пошла речь, че то есть настроение высрать ещё лонгрид
Я заранее извиняюсь, я всё таки как программист - самоучка, и хорошему проектированию всё ещё учусь постоянно, и до сих пор я вообще нихуя не знаю.
Но я попробую пояснить так, как могу.
Говорят, когда че то объясняешь - начинаешь понимать лучше.
Я просто пару раз в приступе какой-то шизофрении задумывался о том, чтобы написать какой-то паблик сервер с нуля, и в целом просто выложить его бесплатно - просто ради тренировки и каких-то новых знаний. Идея эта слава богу пошла по пизде, потому что то нейротянки, то теперь игры в веб аппках в телеграмме, то зовут менеджером куда-то и чужой код чекать приходится, но.
Но когда я о какой-то структуре думал, я тоже задумывался о том, что какую-то его часть можно сделать полностью закрытым, ну скомпилированной дллкой, которую ты подгружаешь в проект.
И собственно почему бы и нет?
А как какать?
Введение в лонгрид
В рейдже как и во всех таких паблик штуках, которые постоянно пишутся разработчиками-любителями, всё
крайне хуёво с пониманием того, что вообще такое программирование на каком-то более менее адекватном уровне.
На базовом, хуёвом уровне, программирование - это просто написание кода, чтобы что-то, что ты написал - работало. Работало так, как задумано.
На 85 уровне разработчика - важны
долговечность,
понятность и
масштабируемость кода.
И это на самом деле чуть сложнее, чем звучит.
Чтобы этого достичь - "чтобы работало" недостаточно. Это - хуёвый подход, который детектит зародыш разработчика.
Ты должен быть уверен в том, что код легко поддерживать. И это ну, не просто комментарии - это читаемость кода вообще без комментариев, на самом деле.
Гарантировать, то что изменения в любой одной части кода - ничего не сломают никогда в другой.
Ну и понимать, что такое
принцип единственной ответственности и вообще весь
солид, например.
"Эта часть" твоего кода - вообще не должна нихуя знать про "вот ту" - например класс
Player должен отвечать только за данные игрока, а не за то, как они сохраняются в базе данных.
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба они должны зависеть
только от абстракций.
Например, бизнес-логика должна использовать интерфейс для работы с БД, а не напрямую обращаться к образной
MySqlConnection.
Ведь завтра ты можешь захотеть переехать на EF - и тогда при правильном раскладе ты затронешь ровно 0 строчек старого кода, просто дописав новую реализацию интерфейса.
(пример с еф на самом деле хуёвый, но похуй)
Интуитивно совсем простой пример реализации такой истории, просто для попробовать - можно реализовать например интерфейсами или абстрактными классами.
Сначала ты пишешь себе консольное приложение, любое, заканчиваешь его, а потом решаешь переписать его на винформы. (ну например)
И когда ты первый раз после базового уровня разработки сюда попадаешь - ты такой "ага, ебать, теперь мне переписывать 75% моего кода со всеми зависимостями, заебись".
И если в этот момент возникает мысль -
а можно ли блять писать код так, чтобы ему было не важно, где будет выход - в консоли, в винформах, на фтп сервере блять - то поздравляю, ты буквально в этот момент начинаешь во что-то окукливаться из личинки разработчика.
В этот момент ты задумываешься про дизайн своего кода.
(Если ты не долбоёб) Когда есть несколько слоёв никак не зависящей друг от друга логики - ввода-вывода например, презентации данных и бизнес-логики приложения.
И начинаешь понимать, насколько важна архитектура.
Ты нахуй этот тут пишеш слыш
Дальше, неизменно следующим шагом будет собственно проектирование той самой архитектуры.
У код-дизайна есть буквально основы, которые описаны уже в сотнях книг, наверное, например
слоистая архитектура.
* пока я в этом месте два часа говорил с человеком в дискордике, появилась ещё пара постов выше, ну ничо, не отвлекаемся *
Че вообще такое нахуй слои?
Ну начнём с того что я никогда не видел вообще хоть сколько-нибудь грамотного подхода к архитектуре ни в одном жта проекте.
Даже к разделению солюшена на проекты с хоть КАКИМ ТО БЛЯТЬ подобием - такое ощущение что у коммьюнити врожденное отвращение.
Ограничимся давайте блять CORE и CLIENT которые один от другого зависят, вот и всё, вот и заебись.
Ладно
Это абстрактные понятия, которые фактически как именно код - не то чтобы существуют, это вроде концепции.
Ну разве что как разные проекты внутри решения (хотя никто не мешает тебе связать их без какой-либо слоистой ответственности вообще, если ты дурачок).
Обычно они делятся на концепты:
Доменного слоя - каркаса с описанием объектов (например Player, Vehicle, House) с описанием базовых правил-проверок вроде проверок отрицательности денег у игрока. Буквально база, каркас. Это "
где хранить", если можно так выразиться.
Доменной логики - то, что происходит внутри доменного слоя. Правила, сценарии - например "аренда машины" там, или "покупка дома". Это "
что делать".
Это не отдельный типа "слой", на самом деле, это часть доменного слоя, но тем не менее, для понимания проще выделять.
Доменному слою похуй на всё остальное, ему плевать на формат, базы данных и взаимодействие с его данными и кодом.
Он существует единолично и комплексно сам по себе.
Ты буквально пишешь эту часть так - что её можно вытащить и использовать в вообще другой игре.
Бизнес-логики - (связывание доменных объектов с реализующими их сценариями - проверка баланса игрока при покупке дома например, процесс передачи дома или тачки там, списания бабок) Например если чел купил дом - бизнес логика распоряжается, что нужно вызывать уведомления, писать что то в бд и отправить админу в личку сообщение что ты читак, потому что домов на сервере нет, как нам подсказал доменный слой.
Бизнес логика знает о доменном слое, она содержит правила и сценарии по работе с ним, она использует репозиторий (например) инфраструктуры, о наличии которой - тоже в курсе, но при этом понятия не имеет как именно работает инфраструктура и в каком виде и где хранит на самом деле описанные в домене объекты.
Например, бизнес-логика может вызвать Save(player), но она не знает, как это реализовано - через скуль, носкуль, да хоть через тхт файлики.
Ну и
инфраструктурный слой - это всё наше взаимодействие с чем-то вовне. Работа с апишкой какой-нибудь, базами данных, файлами - что там ещё может в воспалённую голову прийти. Инфраструктура - предоставляет репозитории, с которыми работает бизнес-логика. Бизнес логика - знает только о реализациях интерфейсов, описанных в инфраструктуре.
Т.е. бизнес-логика юзает какую нибудь реализацию интерфейса IPlayerRepository, которая описана как PlayerRepository - не имея ни малейшего понятия о том, что эта реализация использует DbContext, например. Этот слой нихуя не знает о бизнес-логике, ему похуй. Но знает о доменном слое, потому что работает с его сущностями.
- Доменный слой — "где хранить".
- Доменная логика — "что делать".
- Бизнес-логика — "как связать всё вместе".
- Инфраструктура — "как делать" на уровне технической реализации.
Очень интересно но нахуя мне эта информация
Да очень просто на самом деле - когда ты правильно проектируешь, тебе очень легко понять, какие части изолированной логики ты можешь легко держать в скомпилированном виде, например.
Ну например, ты можешь вообще в своём проекте написать инфраструктурный слой, который будет реализовывать все технические детали - как взаимодействие с бдшкой так и вообще скроет под своим капотом всё взаимодействие с рейдж-апи и даже с вызовами цефок, например.
Твоя бизнес-логика в результате будет работать с каким-то новым твоим IRageApi (например), не имея ни малейшего понятия о том, как они реализованы.
Т.е. пользователь сможет буквально писать свои новые правила и сценарии - но уже с твоим "апи".
Ты полностью скрываешь инфраструктуру (что по мне звучит довольно логично), оставляя для пользователя только твои, новые точки взаимодействия с ней.
По сути ты предоставляешь готовый инструмент для работы с апишкой, обёртку.
Ну и готовые доменный слой с бизнес-логикой, которая работает с твоей инфраструктурой, и будет работать с новыми своими кусочками.
Ты убираешь сложность - но оставляешь гибкость.
Ещё вариант - компилировать бизнес-логику, тем самым убирая у человека возможность сломать что-то в логике твоего сервера, но делая свой продукт скорее конечным, потому что это конечно убирает любую гибкость в плане имплементации (
ебать слово, я хоть правильно его написал то) новых сценариев.
Или мб компилировать доменный слой?
Кароче бляяяяять
Если хочется заебаться - можно создать базовый доменный слой
Меня заебало объяснять, я буду показывать
Ну типа
Код:
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
}
И компилировать и его тоже, если хочется.
Но оставить открытую часть доменного слоя - ну типа
Код:
public class CustomPlayer : Player
{
public int Reputation { get; set; }
public bool IsAdmin { get; set; }
}
Разумно и интересно, но я бы так не делал, я бы лучше компилировал только инфру в закрытую конечную дллку, которая бы содержала мой собственный апи-враппер и весь контекст взаимодействий с бдшками и клиенткой.
Это звучит просто ещё логичнее и оставляет клиенту наибольший простор для собственной кастомизации.
При этом, так как ты управляешь по факту всей инфраструктурой - ты можешь буквально зашить в неё валидацию сборки через какой-нибудь свой апи, проверку лицензии, да вообще что угодно.
Это буквально звучит как
best practice.
А просто так переделать бизнес-логику которая уже написана с использованием твоих реализацией интерфейсов инфраструктуры и по факту твоих апи-врапперов ....
Не ну возможно конечно, наверное, но это прям надо мощнейше заебаться
Человеку который сможет это сделать - легче будет свой сервак просто написать, немного сэкономив на описании доменных сущностей.
К чему я всё это высрал
...
Я не знаю
Где я? Кто здесь?
Говорят, когда лишний раз что-то рассказываешь, ты чуть-чуть лучше это понимаешь сам лишний раз.
А это всегда полезно, потому что я всё ещё нихуя не знаю.
Это всё ещё никак не отменяет моего тейка про то что сразу ориентироваться на то чтобы "всё залочить" - это хуёво, который я озвучил в первом посте.
И на мой взгляд какая-то часть всегда должна быть бесплатной, пусть не самая свежая и клёвая.
Но базируясь на всём том бреде сумасшедшего что я озвучил уже в этом посте - довольно вроде бы очевидно, что именно нужно компилировать и накрывать, чтобы прятать от пользователя. Я бы делал именно так.
А прятать то, что по сути вообще находится за инфраструктурой даже, причём зачастую самую кастомизируемую часть (ну цефки)
Причём то что достаточно легко можно подменить, в целом
Ну хууууууууууууууууууууууй знает