Имеем:
Класс Car с методом Move — перемещающим машину.
В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI.
Как более правильно реадизовать такую проверку?
Напрашивающееся решение — добавить метод CanMove, но насколько это правильно?
Так почти для каждого действия придется заводить соответствующее свойства.
Здравствуйте, Аноним, Вы писали:
А>Имеем: А>Класс Car с методом Move — перемещающим машину.
Эмм... я правильно понимаю, что у вас класс Car отвечает за всю логику перемещения, включая взаимодействие с дорогой, машинами, пешеходами и прочими препятствиями?
А>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>Как более правильно реадизовать такую проверку?
Вынести логику, состояние и вычисление допустимых операций в отдельный слой?
А>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>Так почти для каждого действия придется заводить соответствующее свойства.
Можно возвращать enum.
Re[2]: Взаимодействие UI и домена.
От:
Аноним
Дата:
10.08.11 08:23
Оценка:
Здравствуйте, Sinix, Вы писали:
А>>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>>Как более правильно реадизовать такую проверку? S>Вынести логику, состояние и вычисление допустимых операций в отдельный слой?
А не приведет ли это к анемичной модели?
А>>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>>Так почти для каждого действия придется заводить соответствующее свойства. S>Можно возвращать enum.
Это ты что имеешь в виду:
Каждое св-во возвращает enum? Так это не избавит от кол-ва свойств.
Здравствуйте, Аноним, Вы писали:
S>>Вынести логику, состояние и вычисление допустимых операций в отдельный слой? А>А не приведет ли это к анемичной модели?
Приведёт, но что в этом плохого?
А>Каждое св-во возвращает enum? Так это не избавит от кол-ва свойств.
Нет, просто сделать
Если не нравится — можно каждый метод обернуть в прослойку, реализующую ICommand и выставлять CanExecute индивидуально для каждой команды. Но тут очень легко уйти в реализацию собственного фреймворка только для того, чтобы не тащить в слой логики зависимости от WPF.
Здравствуйте, Аноним, Вы писали:
А>Имеем: А>Класс Car с методом Move — перемещающим машину. А>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>Как более правильно реадизовать такую проверку? А>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>Так почти для каждого действия придется заводить соответствующее свойства.
Да, ты нашел жопу "domain model". Называется она hidden state. Все апологеты фаулера постоянно говорят что "domain model" это круто потому что там можно инкапсулировать состояние, придумывают паттерны типа Aggregate, где скрывается целое поддерево объкетов. Хотя люди не всегда понимают что в этом случае "инкапсулировать" означает "скрыть". Только вот в реальных программах состояние нужно показывать. Нужны интерактивные интерфейсы, которые отключают те или иные действия, нужна валидация, сериализация или еще какая-нибудь -ация, которая должна оперировать состоянием итд.
Тогда создают практически параллельную структуру классов, которые гордо носят имя паттерна DTO, 80% кода начинает состоять из перекладывания данных объекта в DTO и назад.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Аноним, Вы писали:
А>>Имеем: А>>Класс Car с методом Move — перемещающим машину. А>>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>>Как более правильно реадизовать такую проверку? А>>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>>Так почти для каждого действия придется заводить соответствующее свойства.
G>Да, ты нашел жопу "domain model". Называется она hidden state. Все апологеты фаулера постоянно говорят что "domain model" это круто потому что там можно инкапсулировать состояние, придумывают паттерны типа Aggregate, где скрывается целое поддерево объкетов. Хотя люди не всегда понимают что в этом случае "инкапсулировать" означает "скрыть". Только вот в реальных программах состояние нужно показывать. Нужны интерактивные интерфейсы, которые отключают те или иные действия, нужна валидация, сериализация или еще какая-нибудь -ация, которая должна оперировать состоянием итд.
G>Тогда создают практически параллельную структуру классов, которые гордо носят имя паттерна DTO, 80% кода начинает состоять из перекладывания данных объекта в DTO и назад.
Всё ещё хуже: domain model — dto — view model . А ещё есть сервисы, репозитарии и прочие приятности, в результате большинство времени развивается инфраструктура, а не бизнес логика .
Здравствуйте, Аноним, Вы писали: А>Имеем: А>Класс Car с методом Move — перемещающим машину. А>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>Как более правильно реадизовать такую проверку? А>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>Так почти для каждого действия придется заводить соответствующее свойства.
не машина должна себя двигать, а ее контроллер. машина лишь хранит текущее состояние. гуй же у контроллера спрашивает может ли она двигаться или нет
Здравствуйте, __kot2, Вы писали:
__>Здравствуйте, Аноним, Вы писали: А>>Имеем: А>>Класс Car с методом Move — перемещающим машину. А>>В UI в зависимости от того возможно ли переместить машину становятся доступыми элементы UI. А>>Как более правильно реадизовать такую проверку? А>>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>>Так почти для каждого действия придется заводить соответствующее свойства. __>не машина должна себя двигать, а ее контроллер. машина лишь хранит текущее состояние. гуй же у контроллера спрашивает может ли она двигаться или нет
Ага, GUI спрашивает у службы уровня представления, которая в свою очередь спрашивает у службы сервисного слоя которая в свою очередь спрашивает у доменного объекта который спрашивает у доменной службы, инжектированной в доменный объект . А потом задаёмся вопросом почему на добавление кнопочки ушла неделя и отображение грида с объектами занимает 5 минут съедая гиг оперативки .
Здравствуйте, Aviator, Вы писали: A>Ага, GUI спрашивает у службы уровня представления, которая в свою очередь спрашивает у службы сервисного слоя которая в свою очередь спрашивает у доменного объекта который спрашивает у доменной службы, инжектированной в доменный объект . А потом задаёмся вопросом почему на добавление кнопочки ушла неделя и отображение грида с объектами занимает 5 минут съедая гиг оперативки .
да нет, все гораздо проще.
а гриды, сервисный слой, доменная служба это все из области автоматизации документооборота — цитадели аццкой сотоны, кладези говнодизайна
Здравствуйте, gandjustas, Вы писали:
G>Да, ты нашел жопу "domain model". Называется она hidden state. Все апологеты фаулера постоянно говорят что "domain model" это круто потому что там можно инкапсулировать состояние, придумывают паттерны типа Aggregate, где скрывается целое поддерево объкетов. Хотя люди не всегда понимают что в этом случае "инкапсулировать" означает "скрыть". Только вот в реальных программах состояние нужно показывать. Нужны интерактивные интерфейсы, которые отключают те или иные действия, нужна валидация, сериализация или еще какая-нибудь -ация, которая должна оперировать состоянием итд.
G>Тогда создают практически параллельную структуру классов, которые гордо носят имя паттерна DTO, 80% кода начинает состоять из перекладывания данных объекта в DTO и назад.
Здравствуйте, Ronaldo 9, Вы писали:
R9>Здравствуйте, gandjustas, Вы писали:
G>>Да, ты нашел жопу "domain model". Называется она hidden state. Все апологеты фаулера постоянно говорят что "domain model" это круто потому что там можно инкапсулировать состояние, придумывают паттерны типа Aggregate, где скрывается целое поддерево объкетов. Хотя люди не всегда понимают что в этом случае "инкапсулировать" означает "скрыть". Только вот в реальных программах состояние нужно показывать. Нужны интерактивные интерфейсы, которые отключают те или иные действия, нужна валидация, сериализация или еще какая-нибудь -ация, которая должна оперировать состоянием итд.
G>>Тогда создают практически параллельную структуру классов, которые гордо носят имя паттерна DTO, 80% кода начинает состоять из перекладывания данных объекта в DTO и назад.
R9>А что вы предлагаете взамен?
Это же очевидно: мухи отдельно, котлеты отдельно. То есть сделать объекты данных и функции по их обработке.
Здравствуйте, <Аноним>, Вы писали:
А>Напрашивающееся решение — добавить метод CanMove, но насколько это правильно? А>Так почти для каждого действия придется заводить соответствующее свойства.
Если вопрос звучит так "нужен ли нам метод/функция canMove()", то ответ скорее да.
Т.к. "if canMove() then ....", лучше чем "if engine == exist && tiers == GoodYear && ahead != Wall then ...". Особенно, если это все повторяется в коде.
А вот где должен быть этот метод/функция, это вопрос по-сложнее ...
Здравствуйте, gandjustas, Вы писали:
R9>>А что вы предлагаете взамен? G>Это же очевидно: мухи отдельно, котлеты отдельно. То есть сделать объекты данных и функции по их обработке.
Понятно. А метод Move у Car вы бы куда определили: в данные или функции?
Здравствуйте, Ronaldo 9, Вы писали:
R9>Здравствуйте, gandjustas, Вы писали:
R9>>>А что вы предлагаете взамен? G>>Это же очевидно: мухи отдельно, котлеты отдельно. То есть сделать объекты данных и функции по их обработке.
R9>Понятно. А метод Move у Car вы бы куда определили: в данные или функции?
Конечно в функции. И почему он должен быть у Car?
Если метод тривиальный, типа car.Postision = ... , то его можно так и написать в контролере\презентере\viewmodel, если много действий, то можно extension-метод забабахать, а если включает взаимодействие нескольких объектов, то лучше какой-нить сервис сделать.
Re[6]: Взаимодействие UI и домена.
От:
Аноним
Дата:
12.08.11 13:43
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>Конечно в функции. И почему он должен быть у Car? G>Если метод тривиальный, типа car.Postision = ... , то его можно так и написать в контролере\презентере\viewmodel, если много действий, то можно extension-метод забабахать, а если включает взаимодействие нескольких объектов, то лучше какой-нить сервис сделать.
Так у нас в какой-то момент в коде (скорее всего во вью) будет меняться position у машины которая вообще не может ездить (двигателя нет). Как вы от этого обезопаситесь? Сделаете extention Move? В котором будете проверять внутреннее состояние объекта? Но такой подход не защитит от прямой записи в position.
Здравствуйте, Аноним, Вы писали:
А>Так у нас в какой-то момент в коде (скорее всего во вью) будет меняться position у машины которая вообще не может ездить (двигателя нет).
Может, за машиной приехал эвакуатор?
А>Как вы от этого обезопаситесь? Сделаете extention Move?
Зачем? Инварианты модели данных проверяться в ней же — просто добавьте воды ассерты в сеттер.
Здравствуйте, gandjustas, Вы писали:
R9>>>>А что вы предлагаете взамен? G>>>Это же очевидно: мухи отдельно, котлеты отдельно. То есть сделать объекты данных и функции по их обработке.
R9>>Понятно. А метод Move у Car вы бы куда определили: в данные или функции? G>Конечно в функции. И почему он должен быть у Car?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
G>>Конечно в функции. И почему он должен быть у Car? G>>Если метод тривиальный, типа car.Postision = ... , то его можно так и написать в контролере\презентере\viewmodel, если много действий, то можно extension-метод забабахать, а если включает взаимодействие нескольких объектов, то лучше какой-нить сервис сделать.
А>Так у нас в какой-то момент в коде (скорее всего во вью) будет меняться position у машины которая вообще не может ездить (двигателя нет). Как вы от этого обезопаситесь? Сделаете extention Move? В котором будете проверять внутреннее состояние объекта? Но такой подход не защитит от прямой записи в position.
А надо от этого "обезопаситься"? Я например не вижу причин того что машина без двигателя не может ездить?
Почему вообще двигатель будет отдельным классом? Какие задачи он решает?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gandjustas, Вы писали:
R9>>>>>А что вы предлагаете взамен? G>>>>Это же очевидно: мухи отдельно, котлеты отдельно. То есть сделать объекты данных и функции по их обработке.
R9>>>Понятно. А метод Move у Car вы бы куда определили: в данные или функции? G>>Конечно в функции. И почему он должен быть у Car?
А>Э... процедурное программирование?