Storm54
Нет, ты написал какие то свои выдумки про ООП и перемешал это с выдумками про меня причем в оскорбительном виде. Будешь нормально общаться, тогда и поговорим. Если по сути ты не можешь ничего сказать, иди дорогою добра. Серьезно - задай себе вопрос - "почему я не понимаю ООП, какие лекции я пропустил, и зачем я читал по верхам всякую дрянь в интернете"?
upd. Снова оффтопишь, и не слова по делу. Хочешь критиковать мой код - прошу, но не голословно. Почему я решил, что ты не понимаешь ООП, потому что пишешь про это ерунду, большой класс и прочие и не понимаешь, что тебе говорят, вот просто совсем не понимаешь, хотя вроде и не так сложно. И ты уж определись или ты посмотрел мой код или это "Ковыряться в репозитории ноунейма - много чести" ... и кстати, я согласен с дипсиком, просто ты не досмотрел :) вот о чем с тобой говорить?придумал что-то про то, что будет монолитный класс, тебе показали что нет, ты начал изрыгать только свои помои и все, мне тут токсичных диалогов не нужно. Пойми это уже наконец. Дипсик понял после двух предложений, а у тебя какая проблема? Поэтому я вижу, что ты не разобраться хочешь, а потроллить - это тут никому не нужно.
Тебе было сказано, что ты общие по логике поля предлагаешь добавлять в общий класс. Не всегда подходит иерархия, когда дочерние сущности обязательно содержат данные и логику базовых сущностей.
ECS эту проблему (как и много других) решает и подразумевает, что мы можем собирать сущности с нужными компонентами: захотел сделать юнита со здоровьем - накинул компонент здоровья, захотел сделать стул со здоровьем - накинул компонент и т.д. При этом могут быть стулья и без компонента здоровья. Health компонент является простым примером, можешь и на коллайдер заменить его, я лишь показал принцип.
В твоей архитектуре это принципиально невозможно сделать и в перспективе будет один большой базовый класс: и с коллайдером, и со здоровьем, и со звуком и прочими вещами, т.к. по-другому это не организовать в твоем проекте. Могу нарисовать диаграмму, если это поможет донести, но пример то и так простой, разве нет?
tac
Ну вообще, шторм тут прав - partial буквально все что ты добавил в разных файлах под один и тот же класс собирает все в одно целое.
Я вообще, видел его использование под структуры только (и сам пользовал) и это в очень узких моментах (то бишь редко).
Конкретно в твоем примере кода - не понятно, зачем это было сделано.
Storm54
> общие по логике поля предлагаешь добавлять в общий класс
Я не просто предлагаю добавлять, я считаю что они изначально там должны были быть. А partial позволяет их разделить на компоненты. (разницу чувствуешь?) (если будешь придираться к словам, то точнее "не разделять на компоненты", а "выделять связи, с которыми работает/вносит реализованный компонент (другой класс)". Это своего рода инъекция. Ключевое же слово partial просто позволяет делать инъекции. И в этом, ключевая идея. И то, что его использовали чаще для другого это совсем не запрещает его использовать вместо ECS без оферхеда.)
При том при всем, это совсем не большой класс. Вот что я отвечал на похожий вопрос в ютубе:
Нет никаких гигантских классов, все свойства которые и так должны были бы быть в соответствующем классе остаются в нем, просто разделены по функциональным группам в разных компонентах. Их по определению, не больше чем в ООП, а то что ECS на каждое свойство делает свой класс - вот это и не правильно. Опять же на канале уже обсуждались траблы с т.н. SRP (Это ссылка на первую часть, их всего 3 https://www.youtube.com/watch?v=xQGzWWXBgDE)
И это никак мнимых проблем не создает.
Storm54
> ECS эту проблему (как и много других) решает и подразумевает, что мы можем собирать сущности с нужными компонентами
Как раз нет, ECS лишь декларирует, что решает. На самом же деле, эти "компоненты" будут реализованы в одной "куче" с другими, т.е. физически ты себе будешь импортировать целый пакет со всем, что на 80% тебе не нужно. А отделить физически ты просто будешь не в состоянии. После чего с кучей оверхеда будешь прописывать - это вот хочу, это вот пусть работает с этим, и т.д. Т.е. пропишешь больше, чем реализация функциональности которая тебе нужна.
Вместо, этого в моем случае с partial-подходом ты просто скопируешь нужны файлы нужных компонентов и забудешь буквально обо всем. Оно будет работать из коробки.
SaintRQ
> Конкретно в твоем примере кода - не понятно, зачем это было сделано.
Какой пример кода имеется введу? Storm54 привел пример, который ничего и не может показать, он может показать только ООП подход, правильный и понятный. Потому что partial- используется совсем для другого. Но репозиторий он смотреть не захотел, ну что поделать. Не хочет и не понимает. А вот даже Дипсик понял с пару предложений, хотя вначале тоже был обучен шизанутыми ECSниками, но опять же досмотреть у Storm54 нет времени.
Storm54
> в перспективе будет один большой базовый класс: и с коллайдером, и со здоровьем, и со звуком и прочими вещами, т.к. по-другому это не организовать в твоем проекте. Могу нарисовать диаграмму, если это поможет донести, но пример то и так простой, разве нет?
Нет. Даже в игрушечном примере с монстрами и зданиями они не в одном классе, напрягись и посмотри. Да, приводи диаграмму, можешь реальный код написать, можешь ждать когда я выложу реальные примеры. Всюду будет много кода, который не будет один класс.
Но допустим, тебя бомбит от одного класса. Представим, что вот он один. И что? В чем проблема, если этот один поделен на функциональные блоки файлами, а не классами? Или так уверовал в Фаулера, что не понимаешь, что главное не паттерны, а архитектура?
Оказывается, можешь не токсично общаться. Отлично.
tac
> Какой пример кода имеется введу?
namespace Tac.ItemMove
{
public partial class Item2 : Item
{
public bool AllowMove = true;
}
public class ItemMove
{
public void Move(Item2 item, ... ) { ... }
}
}
namespace Tac.ItemRotate
{
public partial class Item2 : Item
{
public bool AllowRotate = true;
}
public class ItemRotate
{
public void Rotate(Item2 item, ... ) { ... }
}
}Почему не вот так?
public class Item2 : Item
{
public bool AllowMove = true;
public bool AllowRotate = true;
public void Move(Item2 item, ... ) { ... }
public void Rotate(Item2 item, ... ) { ... }
}tac
> А partial позволяет их разделить на компоненты. (разницу чувствуешь?) (если будешь придираться к словам, то точнее "не разделять на компоненты", а "выделять связи, с которыми работает/вносит реализованный компонент (другой класс)".
Так это просто разновидность код-стайла. Можно и в одном классе с точно таким же результатом все написать, только это неудобно. Инструменты статического анализа работать нормально с этим не будут, IDE будут отображать все содержимое класса со всеми полями и методами, которые логически должны быть разделены, ведь и по твоей же логике разнесены по отдельным физическим файлам.
tac
> Как раз нет, ECS лишь декларирует, что решает. На самом же деле, эти "компоненты" будут реализованы в одной "куче" с другими, т.е. физически ты себе будешь импортировать целый пакет со всем, что на 80% тебе не нужно.
Так я могу и в случае ECS скопировать файл компонента и файл системы. Это даже легче будет сделать, т.к. мне не придется тянуть основную часть partial класса, в отличие от твоего подхода, где это необходимо. 1:0 в пользу ECS.
tac
> Т.е. пропишешь больше, чем реализация функциональности которая тебе нужна.
Я скопирую все нужные компоненты и системы, а в коде создания сущности напишу именно то, что мне и необходимо. Будет минимально возможный код, абсолютно прозрачный и читаемый:
int entityId = GetNewEntityId(); AddComponent<Health>(entityId); AddComponent<Collider>(entityId); AddComponent<AgentMover>(entityId);
tac
> Вместо, этого в моем случае с partial-подходом ты просто скопируешь нужны файлы нужных компонентов и забудешь буквально обо всем. Оно будет работать из коробки.
Как я и написал выше, как раз-таки в случае с ECS так будет работать. В твоем случае нужно будет реализовать ответную часть partial классов для скопированных.
tac
> А вот даже Дипсик понял с пару предложений, хотя вначале тоже был обучен шизанутыми ECSниками
Он подыгрывает, может и 1+1=3 подтвердить, сути это не меняет.
tac
> Но допустим, тебя бомбит от одного класса. Представим, что вот он один. И что? В чем проблема, если этот один поделен на функциональные блоки файлами, а не классами?
Воооот. Правильный вопрос. У тебя будет класс, каждый экземпляр которого будет занимать сотни (или тысячи) байт в памяти. Это будет прямо влиять на производительность на всех этапах работы с объектами класса. Это приведет к гарантированному оверхэду, хотя ты утверждаешь, что это не так, но если в классе содержатся всевозможные поля и даже не используются, то они так или иначе будут попадать в кэшлайн при чтении нужного поля из памяти. ECS это решает, т.к. данные каждого компонента определенного типа упакованы последовательно, что позволяет несколько компонентов читать за один read из оперативки, практически с нулевым кэшмиссом и обрабатывать, упираясь лишь в производительность вычислений CPU.
tac
Если по твоему варианту с пространством имен, доступ ко всем полям класса не будет между первым и вторым Item2. И в целом, для наследования это вроде нормально - но зачем тогда partial?
Если же тебе надо, чтобы доступ был - зачем тогда namespace разный?
У тебя маленьких класс, который ты будешь расславить по другим файлам. Ну, это как минимум - хреново читаться будет, что там есть и где там искать для тех, кто не ты (кто не писал этот код).
tac
Или это такая попытка заигрывания с полиморфизмом?
Я без иронию, просто не понял зачем так делать? Какие плюсы и минусы от такого подхода и что вообще с этим делать?
У друга "платного жпт" спросил. Что то ты мудришь.
Да, в этом примере есть принципиальный “косяк” (или, мягче, архитектурная нестыковка), и его легко не заметить из-за partial. 1) Это не один Item2, а два разных типа В C# “один и тот же класс” определяется именем + namespace. Поэтому здесь: Tac.ItemMove.Item2 Tac.ItemRotate.Item2 — это два разных класса, и partial их не объединяет, потому что namespace различается. Следствие: метод public void Move(Item2 item, ...) в Tac.ItemMove принимает только Tac.ItemMove.Item2, а Rotate принимает только Tac.ItemRotate.Item2. Один в другой не подставится. 2) Зачем он мог так сделать в Unity Самый вероятный смысл: он хотел не “склеивать” класс, а развести разные компоненты (MonoBehaviour) с одинаковым базовым поведением/данными по разным “модулям”: на объект вешаем компонент Tac.ItemMove.Item2 — получаем AllowMove на объект вешаем компонент Tac.ItemRotate.Item2 — получаем AllowRotate Unity действительно позволяет иметь два MonoBehaviour с одинаковым именем класса, если они в разных namespace (в Add Component они будут различаться по namespace). Но это архитектурно спорно по нескольким причинам: Дублирование состояния. Оба Item2 наследуются от Item : MonoBehaviour, значит если ты повесишь оба компонента на один GameObject, у тебя будет два независимых набора ObjectId/GroupId/ModelName/... — они легко разъедутся. Плохая читаемость и постоянные коллизии имён. Item2 в двух namespace неизбежно приводит к using-конфликтам и необходимости писать полные имена или алиасы. partial тут не нужен вообще. Он ничего не даёт (не объединяет), только вводит в заблуждение. Если цель — два разных класса, то partial надо убрать. 3) Почему “просто не объявить всё в одном классе” Если у тебя реально всегда один тип предмета и ему всегда нужны и Move, и Rotate — то да, проще и правильнее один Item2 (или просто Item) с нужными полями/методами. Но если автор хотел “возможности” как опциональные — Unity-правильный путь обычно не через наследование, а через композицию: Item (данные) MoveComponent (перемещение) RotateComponent (вращение) Так ты не дублируешь ObjectId и прочее, и можешь включать/выключать способности добавлением/удалением компонентов. 4) Резюме по коду автора Если автор думал, что partial “склеит” поля между Tac.ItemMove.Item2 и Tac.ItemRotate.Item2, то это ошибка понимания C#: не склеит. Если он сознательно сделал два разных компонента под разные системы — тогда partial лишний, а название Item2 в обоих местах и наследование от Item : MonoBehaviour создают риск дублирования данных и путаницы.
SaintRQ
> Почему не вот так?
tac
> Вместо, этого в моем случае с partial-подходом ты просто скопируешь нужные файлы нужных компонентов
SaintRQ
> в этом примере есть принципиальный “косяк” (или, мягче, архитектурная нестыковка), и его легко не заметить из-за partial.
tac
> Там была описка, это один и тот же класс, я уже поправил.
Оригинал в репозитории смотри, и не будет проблем и мне повторяться не придётся.
SaintRQ
С остальным разобрался, или еще вопросы остались?
Storm54
> в коде создания сущности напишу именно то, что мне и необходимо. Будет минимально возможный код, абсолютно прозрачный и читаемый
это и есть оверхед, совершенно не нужный, я уже не говорю о том, что ты будешь структуры делать а не классы, и прочий бред ECS, вместо нормального ООП :)
Storm54
> В твоем случае нужно будет реализовать ответную часть partial классов для скопированных.
Это я не понял, снова что-то фантазируешь.
Storm54
> Он подыгрывает, может и 1+1=3 подтвердить, сути это не меняет.
далеко не всегда, попробуй его убедить не соблюдать авторские права :)
Storm54
> Это будет прямо влиять на производительность на всех этапах работы с объектами класса.
Это фантазии ECSшников не более того, в любом случае несущественые потери производительности не стоит деградации подхода назад к машиному коду, пиши тогда прямо на ассемблере, будет эффективнее.
Да, и кажется я давал ссылку на разбор производительности ECS, тоже еще не смотрел?
Ну или досмотрел бы, с дипсиком мы это тоже обсудили, правда он с одного намека понял о чем я. А ты похоже будешь упираться. Хочешь попробую сделать тест, и покажи сколько в реальности ты чего теряешь в производительности. Все это выдумки ECSников, на самом деле они получают производительность только из-за Burst, я же когда действительно будет нужно напишу на C++ с векторными инструкция SIMD, и забуду кошмарные проекты на ECS/
tac
> Оригинал в репозитории смотри, и не будет проблем и мне повторяться не придётся.
Ну, если опечатка, то ок. А то странности.
tac
> Это я не понял, снова что-то фантазируешь.
Если ты что-то не понял, то это не значит, что вокруг дураки. Общайся нормально, раз уж требуешь это от других. Ты не пуп земли.
tac
> это и есть оверхед, совершенно не нужный, я уже не говорю о том, что ты будешь структуры делать а не классы, и прочий бред ECS, вместо нормального ООП :)
В чем именно заключается оверхэд? Твой тезис не является аргументом, аргументы я выше привел, попробуй их парировать.
По существу: у нас не выходит дискуссия. На данный момент ты не смог ни один аргумент опровергнуть, пишешь какие-то полухахоньки, кидаешь ссылки на часовые видосы вместо одного-двух предложений, зачем-то копипастишь дипсик. Если ты не знаком с форматом дискуссий (может нет у тебя высшего образования, всякое бывает - я твоей биографии не знаю), то продолжать смысла нет, удачи.
Storm54
> Если ты что-то не понял, то это не значит, что вокруг дураки.
Ну, объясни тогда ... хотя думаю не понял ты )