Всем привет. Пытаюсь построить часть архитектуры взаимодействия объектов следующим образом. В основном классе объекта (он MonoBehaviour) перечисляю классы (не MonoBehaviour) которые придают некое поведение объекта. Далее в эти классы закидываю все исходные данные, которые необходимые для их работы. В тех классах, для которых требуются данные, которые передаются по значению - они имеют ссылку на анонимный метод, где в базовом классе объекта вытягивает нужное поле из соответствующего класса. Это позволяет класс с поведением цеплять к разным объектам, лишь бы были инициализированы исходные данные. Может я слишком все усложняю и можно проще все сделать, насколько такой подход адекватный / или нет?
В тех классах, для которых требуются данные, которые передаются по значению - они имеют ссылку на анонимный метод, где в базовом классе объекта вытягивает нужное поле из соответствующего класса.
Почему нельзя в конструктор этого класса передать ссылку на сам MonoBehaviour и пусть он сам берет любые данные какие ему нужны?
Цитата
Может я слишком все усложняю и можно проще все сделать, насколько такой подход адекватный / или нет?
Подход называется композицией и в целом хорош и адекватен
Сообщение отредактировал drcrack - Четверг, 22 Апреля 2021, 13:56
Почему нельзя в конструктор этого класса передать ссылку на сам MonoBehaviour и пусть он сам берет любые данные какие ему нужны?
Потому что главные классы MonoBehaviour для разных обьектов свои, и те классы (скажем компоненты), которым нужны исходные данные, нужно будет приводиться к конкретному главному классу, чтобы вытащить оттуда данные, как по мне - это не совсем правильно. Вместо этого, я из любого уголка в главном классе могу дергнуть данные и положить в компонент.
Потому что главные классы MonoBehaviour для разных обьектов свои, и те классы (скажем компоненты), которым нужны исходные данные, нужно будет приводиться к конкретному главному классу, чтобы вытащить оттуда данные, как по мне - это не совсем правильно. Вместо этого, я из любого уголка в главном классе могу дергнуть данные и положить в компонент.
Правильней нужные компоненту данные выделить в интерфейс и пусть разные MonoBehaviours их реализуют согласно своему внутреннему устройству, а компонент при создании получает ссылку на главный обьект в виде интерфейса и использует его. В целом то же самое что ты делаешь, только красиво и правильно
Сообщение отредактировал drcrack - Четверг, 22 Апреля 2021, 17:46
Правильней нужные компоненту данные выделить в интерфейс и пусть разные MonoBehaviours их реализуют согласно своему внутреннему устройству, а компонент при создании получает ссылку на главный обьект в виде интерфейса и использует его. В целом то же самое что ты делаешь, только красиво и правильно
В какой-то статье на хабре читал, что класс не должен заниматься инициализацией данных, это не его обязанность, в принципе с чем я и согласен. Класс должен только обрабатывать данные и куда-то возвращать результат. По поводу интерфейсов, мне нравится идея и так у меня было реализовано ранее. Все хорошо, пока данные перечислены списком в интерфейсе из-за чего в главном классе, реализующем интерфейс была мусорка из данных. Как только я захотел обернуть данные в класс, это общие данные, которые нельзя приписать к какому-то конкретному компоненту, столкнулся со следующей проблемой. Главный класс содержит обертку из общих данных и списка компонентов. Если интерфейс реализующийся главным классом, захочет получить переменную из обертки, нужно будет тут-же в главном классе дублировать переменную - свойство, которое будет вытягивать данные из обертки. Я сново вернусь к мусорке. Можно заставить класс - обертку реализовать интерфейс, но тогда туда я должен записать ссылки на компоненты, если они потребуются для интерфейса.
Сообщение отредактировал urbemAngeli - Четверг, 22 Апреля 2021, 19:07
Без конкретных примеров разобраться сложно. Не совсем понятно зачем что-то дублировать если можно в реализации метода/свойства интерфейса просто достать нужные данные из "обертки"?
Цитата
Я сново вернусь к мусорке.
Мусорка неизбежна если класс большой и хочется сделать "правильно", поэтому его нужно разбивать на части, вынося часть логики в компоненты и на другие уровни иерархии наследования (по ситуации).
Без конкретных примеров разобраться сложно. Не совсем понятно зачем что-то дублировать если можно в реализации метода/свойства интерфейса просто достать нужные данные из "обертки"?
Простецкий пример мусорки. При n - м количестве свойств, главный скрипт захламлен реализациями интерфейсов.
Код
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class MainClass : MonoBehaviour, IInitDataForLogicTypeOne, IInitDataForLogicTypeTwo {
public Data data = new Data();
private LogicTypeOne logicOne = new LogicTypeOne(); private LogicTypeOne logicTwo = new LogicTypeOne();
public string valueA { get { return data.valueA; } } public string valueB { get { return data.config.valueB; } } public string valueC { get { return data.config.valueC; } }
Это не конкретный пример, а просто ты кодом написал то, что до этого писал словами Мой ответ не меняется,
Цитата
Мусорка неизбежна если класс большой и хочется сделать "правильно", поэтому его нужно разбивать на части, вынося часть логики в компоненты и на другие уровни иерархии наследования (по ситуации).
PS Для красоты и правильности создавать компоненты логичнее в Awake, тогда в них можно сделать readonly поля
Добавлено (22 Апреля 2021, 20:39) --------------------------------------------- И кстати реализация интерфейсов в данном примере занимает 3 строчки, что сложно назвать мусоркой. Сколько у тебя таких свойств будет, 500 штук что ли?
Сообщение отредактировал drcrack - Четверг, 22 Апреля 2021, 20:40