Re[3]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 28.09.10 09:18
Оценка:
Здравствуйте, gandjustas, Вы писали:

A>>Не вижу ничего плохого в if-ах, когда они сконцентрированы в одном месте и не мешают восприятию логики (тем более даже фабрика стратегий будет на иф-ах).

G>Избыточное количество ифов банально заменяется таблицей.
Не совсем уверен что ты имеешь ввиду под таблицей, но соглашусь (таблица -- и таблица в БД, и хэш-таблица в памяти)

G>Поймал себя на мысли что полностью прочитал пост ТС только после твоего сообщения.

Бывает, я тоже был уверен, что тут Стратегия, пока не стал отвечать на пост
Автор: ZevS
Дата: 27.09.10
уважаемого ZevS.
Мол как ни крути, а в итоге получиться Стратегия. Потом, что "почти наверняка"... А потом что Стратегия тут нафик не нужна

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[2]: Паттерн для представления разных состояний
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.09.10 09:27
Оценка:
Здравствуйте, Aikin, Вы писали:

A>В данном же случе мне больше по душе сл. подход (но, боюсь, паттернами там и не пахнет):

A>(Непонятно зачем здесь стратегия, раз алгоритм рисования всегда один и тот же?)

A>1) Заводим структуру содержащую всю информацию о стиле:

A>2) Фабрика стилей:
A>3) Использование:
A>Как бонус, этот подход легко расширяем для хранения стилей в базе.

Это как раз то, чего почти никогда не надо делать.

Есть вобщем то готовые решения для статуса. Как правило, раскраска UI это самое меньшее с чем приходится сталкиваться.

Дизабленая кнопка это только пол-проблемы. Для многопользовательского приложения нужно еще и обрабатывать всякие клики с использованием этих состояний.

Т.е. команды, которые будут навешиваться на контролы, должны привязываться к состоянию.

Всего ничего — PageStyle или перестает быть стайлом, потому что в него надо вводить нечто вроде SomeAction или надо вводить точно такой же механизм, но для команд

var commands = Commands.GetCommandsFor(page.State);
    
    //...
    if (commands.Contains(request.Command))
        //execute
    else
        //ignore


Допустим, этот вопрос решен. А что делать, если у пользователей есть разные права ?

Опаньки — надо вводить еще один, точно такой же мехнизм, кк ты показал, но уже для прав.

var permission = Permissions.GetPermissionsFor(Users.CurrentUser);
    
    //...
    if (permission.IsCommandAllowed(request.Command))
        //execute
    else
        //ignore


Итого — всего ничего, а твоя идея уже выдохлась.
Re[3]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 28.09.10 10:03
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Итого — всего ничего, а твоя идея уже выдохлась.

Когда придут такие требования, тогда и будем решать эти проблемы. Нам не нужен десятиколесный велосипед c реактивным двигателем на все случаи жизни.


И самое главное:
ИМО, не стоит валить эти три разных аспекта в кучу. Даже если придут требования в том виде, что ты описал Стиль, Реация на команды и Права лучше оставить разными сущностями.

По порядку:
Реакция на команды перейдет в Контроллер и будт (скорее всего) представлена паттерном Состояние. Т.о. сразу же исключаем ее из рассмотрения.

Что у нас есть в итоге? Стили, Правила показа/скрытия элементов и Права пользователя.
Разделять я из отказываюсь. Но нам хотелось бы иметь дело с одним поставщиком Правил отображения. Заводим этот объект DisplayRule. (Тут могут быть два варианта: DisplayRule один на все типы страниц и прав пользователя либо он так же дополнительно настраивается под контекст. Рассматриваем наиболее простой: один на все случаи).


public class DisplayRule
{
    public DisplayRule(Style style, CommandDisplayRule commRule, Permissions permissions) {}
    
    
    public ShowXYZCommand 
    {
        get { return commRule.ShowXYZCommand && permissions.HasPermissions(Commands.XYZ);}
    }

}

Хотя... стили я все же не агрегировал... стили это стили.


Какие новые требования "выдохнут" мою идею до конца?


СУВ, Aikin

ЗЫ
A>>Как бонус, этот подход легко расширяем для хранения стилей в базе.
I>Это как раз то, чего почти никогда не надо делать.
Да ты что? Судя по моему опыту требование "позволить пользователю менять стили" скоро появится.
Опять же, это не была цель. Это всего лишь то, что я заметил при просметре этого решения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[4]: Паттерн для представления разных состояний
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.09.10 10:28
Оценка:
Здравствуйте, Aikin, Вы писали:

I>>Итого — всего ничего, а твоя идея уже выдохлась.

A>Когда придут такие требования, тогда и будем решать эти проблемы. Нам не нужен десятиколесный велосипед c реактивным двигателем на все случаи жизни.

Они уже пришли. "активировать разные линки в какой-то колонке делать активной ссылку, в другой прятать совсем."

Не было только про права пользователя. Но в любой, боле менее серьезной системе, будут и права.

Вобщем Статус это как раз то, где не надо изобретать велосипед, нужно взять готовое провереное решение.

A>Что у нас есть в итоге? Стили, Правила показа/скрытия элементов и Права пользователя.

A>Разделять я из отказываюсь. Но нам хотелось бы иметь дело с одним поставщиком Правил отображения. Заводим этот объект DisplayRule. (Тут могут быть два варианта: DisplayRule один на все типы страниц и прав пользователя либо он так же дополнительно настраивается под контекст. Рассматриваем наиболее простой: один на все случаи).

Права пользователя ты задвинул в отображение ?

Лихо. Команды в контролер, а права — в отображение.

Вот один из пользователей например не нажмет на рефреш, у него все линки будут видимы и доступны, как ты определишь, есть ли этого пользователя права на выполнение команды ?

I>>Это как раз то, чего почти никогда не надо делать.

A>Да ты что? Судя по моему опыту требование "позволить пользователю менять стили" скоро появится.

Вообще то, если ты не зметил, ответ был на все твое сообщение, а не на отдельные куски.

Итого — PageStyle плавно мигрировал в DisplayRule, появился контроллер. А начало было таким оптимистичным
Re[5]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 28.09.10 10:51
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Они уже пришли. "активировать разные линки в какой-то колонке делать активной ссылку, в другой прятать совсем."

Если ты не заметил, то первое мое решение справляется с таким требованием. Если тебя смущает название Style -- замени его на на что нибудь (DisplayRules, например).

I>Не было только про права пользователя. Но в любой, боле менее серьезной системе, будут и права.

I>Вобщем Статус это как раз то, где не надо изобретать велосипед, нужно взять готовое провереное решение.
Что такое Статус и как Статус соотносится с Правами?

I>Права пользователя ты задвинул в отображение ?

I>Лихо. Команды в контролер, а права — в отображение.
Пример в моем сообщении показывает, что правила отображения рассчитываются на основе правил отображения кнопок и прав пользователя. Ничего другого в этом примере нет.

I>Вот один из пользователей например не нажмет на рефреш, у него все линки будут видимы и доступны, как ты определишь, есть ли этого пользователя права на выполнение команды ?

Больше одной ссылки на объект не допускается? На каком динозавре вы разрабатываете?

I>Итого — PageStyle плавно мигрировал в DisplayRule, появился контроллер. А начало было таким оптимистичным

Контроллер никуда не исчезает и не появляется. Он был, есть и будет. Просто он делегирует часть своих обязанностей объекту DisplayRule.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[6]: Паттерн для представления разных состояний
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.09.10 11:56
Оценка:
Здравствуйте, Aikin, Вы писали:

I>>Они уже пришли. "активировать разные линки в какой-то колонке делать активной ссылку, в другой прятать совсем."

A>Если ты не заметил, то первое мое решение справляется с таким требованием. Если тебя смущает название Style -- замени его на на что нибудь (DisplayRules, например).

На примере — есть кнопка, клик по которой удаляет элемент в базе.

Ты скрыл это кнопку в состоянии А.

Например, есть два разных пользователя которые работают с одним объектом — обычное дело. Или, например десяток исполнителей работают с одним объектом. Один переводит в новое состояние, а другие продолжают кликать.

У одного пользователя после рефреша кнопка спряталась, у другого рефреша не было и кнопка видна.

Очевидно, что раз кнопка спряталась, то у пользователя нет права выполнять действие соотсветствующее кнопке.

Твое решение только на клиентской стороне. Соответственно, другой пользователь сможет выполнить ему не разрешенное.

Нужно решение и на серверной — запретить выполнение команды, операции.

I>>Вобщем Статус это как раз то, где не надо изобретать велосипед, нужно взять готовое провереное решение.

A>Что такое Статус и как Статус соотносится с Правами?

Статус, это о чем идет речь в первом сообщении. Вобщем то обычный функционал для бизнес приложений. Его не надо выдумывать.

Теперь смотрим, что ты пишешь

A>Пример в моем сообщении показывает, что правила отображения рассчитываются на основе правил отображения кнопок и прав пользователя. Ничего другого в этом примере нет.


А что было ?

>Что у нас есть в итоге? Стили, Правила показа/скрытия элементов и Права пользователя. Разделять я из отказываюсь.


Т.е. ты отказался отделять права пользователя от правил показа-сокрытия.



I>>Вот один из пользователей например не нажмет на рефреш, у него все линки будут видимы и доступны, как ты определишь, есть ли этого пользователя права на выполнение команды ?

A>Больше одной ссылки на объект не допускается? На каком динозавре вы разрабатываете?

Например VS2010 + WCF + EF + SL4. Считается ли это динозавром ?

Действие как правило зависит от состояния.

Т.е. нельзя свести права пользователя только к отображению.
Re[7]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 28.09.10 12:47
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Твое решение только на клиентской стороне. Соответственно, другой пользователь сможет выполнить ему не разрешенное.

I>Нужно решение и на серверной — запретить выполнение команды, операции.
Перечитай мое решение еще раз (хинт: передача объекта по ссылке).

I>>>Вобщем Статус это как раз то, где не надо изобретать велосипед, нужно взять готовое провереное решение.

A>>Что такое Статус и как Статус соотносится с Правами?
I>Статус, это о чем идет речь в первом сообщении. Вобщем то обычный функционал для бизнес приложений. Его не надо выдумывать.
1) Тогда почему он с большой буквы?
2) Ну так какое здесь есть " готовое провереное решение"?

>>Что у нас есть в итоге? Стили, Правила показа/скрытия элементов и Права пользователя. Разделять я из отказываюсь.

I>Т.е. ты отказался отделять права пользователя от правил показа-сокрытия.
Понял. Это была описка. Читать не разделять, а объединять. Далее по коду должно было быть понятно, что все три объекта остаются. Но в момент отображения формы мы используем только один объект

A>>Больше одной ссылки на объект не допускается? На каком динозавре вы разрабатываете?

I>Например VS2010 + WCF + EF + SL4. Считается ли это динозавром ?
Ну тогда и говорить не о чем. Делаешь две ссылки на один объект permissions. Один остается в контроллере, а второй отдается DisplayRules.

I>Действие как правило зависит от состояния.

I>Т.е. нельзя свести права пользователя только к отображению.
Кто ж спорит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[8]: Паттерн для представления разных состояний
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.09.10 13:01
Оценка:
Здравствуйте, Aikin, Вы писали:

I>>Статус, это о чем идет речь в первом сообщении. Вобщем то обычный функционал для бизнес приложений. Его не надо выдумывать.

A>1) Тогда почему он с большой буквы?

Потому что это Макро-паттерн

A>2) Ну так какое здесь есть " готовое провереное решение"?


Статус
Re[9]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 28.09.10 15:16
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, Aikin, Вы писали:


I>>>Статус, это о чем идет речь в первом сообщении. Вобщем то обычный функционал для бизнес приложений. Его не надо выдумывать.

A>>1) Тогда почему он с большой буквы?
I>Потому что это Макро-паттерн
Как о Макро-паттерне могла идти речь, если человек совета просил?

A>>2) Ну так какое здесь есть " готовое провереное решение"?

I>Статус
Объясни. Мне лично ничего не говорит это слово.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[10]: Паттерн для представления разных состояний
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.09.10 16:46
Оценка:
Здравствуйте, Aikin, Вы писали:

A>>>1) Тогда почему он с большой буквы?

I>>Потому что это Макро-паттерн
A>Как о Макро-паттерне могла идти речь, если человек совета просил?

Я сообщил свое мнение о твоем решении и ничего не предлагал вопрошающему.

A>>>2) Ну так какое здесь есть " готовое провереное решение"?

I>>Статус
A>Объясни. Мне лично ничего не говорит это слово.

Примерно как в трекере устанавливается статус бага, open, assigned, active, reopened, resolved, verified, closed и тд и тд.

Соответсвенно статус определяет отображение, определяет права групп, пользователей и тд.
Re[3]: Паттерн для представления разных состояний
От: snaphold  
Дата: 28.09.10 18:14
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, okman, Вы писали:


А>>>Какой паттерн для этих случаев использовать ?


O>>State, конечно.

O>>А объекты брать из фабрики, чтобы понапрасну память не дергать.

L>State — не к месту тут. Он нужен, когда у объекта меняется состояние в ходе жизни. Тут, как уже посоветовал gandjustas, больше подходит Статегия.


так если состояние было сначала "не назначено", а потом нажали назначить, то состояние меняется на "на исполнении".
Или "ход жизни" здесь имеете ввиду, что в течение одного клика состояние меняется?
Re[4]: Паттерн для представления разных состояний
От: Lloyd Россия  
Дата: 28.09.10 18:52
Оценка:
Здравствуйте, snaphold, Вы писали:

S>так если состояние было сначала "не назначено", а потом нажали назначить, то состояние меняется на "на исполнении".

S>Или "ход жизни" здесь имеете ввиду, что в течение одного клика состояние меняется?

Тут для начала надо определиться, о каком объекте мы говорим, у кого меняется состояние?
Re[5]: Паттерн для представления разных состояний
От: Аноним  
Дата: 29.09.10 06:05
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, snaphold, Вы писали:


S>>так если состояние было сначала "не назначено", а потом нажали назначить, то состояние меняется на "на исполнении".

S>>Или "ход жизни" здесь имеете ввиду, что в течение одного клика состояние меняется?

L>Тут для начала надо определиться, о каком объекте мы говорим, у кого меняется состояние?


Упрощенно.
есть форма с редкатированием задачи. Не назначенные задачи имеют свой набор контролов, назначенные другой на форме.
Сначала она в статусе "Не назначена" и таблице помечена одним стилем, мы жмем кнопку Назначить.
Тут что?
Re[6]: Паттерн для представления разных состояний
От: Lloyd Россия  
Дата: 29.09.10 06:58
Оценка: +1
Здравствуйте, Аноним, Вы писали:

L>>Тут для начала надо определиться, о каком объекте мы говорим, у кого меняется состояние?


А>Упрощенно.

А>есть форма с редкатированием задачи. Не назначенные задачи имеют свой набор контролов, назначенные другой на форме.
А>Сначала она в статусе "Не назначена" и таблице помечена одним стилем, мы жмем кнопку Назначить.
А>Тут что?

State — это когда в зависимости от состояния объекта вызов его метода должен делать либо одно, либо другое.

Я так понимаю, в предлагаемом вами примере объект — это "задача", а действие — "отрисовка"?
Если вы предлагаете использовать State, то из этого автоматом следует, что вы предлалаете поместить опрерацию отрисовки в объект "задача", что явно не является примером хорошего дизайна.
Если же вы помещаете отрисовку отдельно в объект "рисовальщик", то сразу же пропадает необходимость в State-е, т.к. все гораздо проще — достаточно выбирать тот или иной отрисовщик в зависимости от статуса задачи.

Т.е. полюбому State-у места тут нет.
Re[11]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 29.09.10 10:00
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Примерно как в трекере устанавливается статус бага, open, assigned, active, reopened, resolved, verified, closed и тд и тд.

I>Соответсвенно статус определяет отображение, определяет права групп, пользователей и тд.
Ты либо внимательно прочитай и попытайся понять что я написал в самом первом посту, либо давай закончим обсуждение.

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[7]: Паттерн для представления разных состояний
От: okman Беларусь https://searchinform.ru/
Дата: 29.09.10 11:01
Оценка:
Здравствуйте, Lloyd, Вы меня убедили: лучший Паттерн для представления разных состояний — стратегия.

Ответьте, пожалуйста, только на один вопрос — чем тогда выражать статус проекта ? Магическими числами ?
По-моему, в классе табличной записи все равно окажется поле типа state/status/current, которое будет
представлять разные состояния проекта. И объекту "задача" необязательно себя рисовать.
Главное назначение state здесь может быть связано с выведением нужного типа (для полиморфной обработки
другими классами, например), а вовсе не с отрисовкой.

P.S. Это лишь мое мнение (ну не могут в принципе два компьютерщика прийти к одинаковым выводам).

и зачем я стал программистом ?
Re[8]: Паттерн для представления разных состояний
От: Aikin Беларусь kavaleu.ru
Дата: 29.09.10 11:17
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Lloyd, Вы меня убедили: лучший Паттерн для представления разных состояний — стратегия.

Глупость. Для представления разных состояний никаких паттернов не нужно. Достаточно поля с энумом PageState.

Lloyd пытается тебя убедить, что Стратегия — лучший паттерн для представления разных алгоритмов отрисовки

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[8]: Паттерн для представления разных состояний
От: Lloyd Россия  
Дата: 29.09.10 11:23
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Lloyd, Вы меня убедили: лучший Паттерн для представления разных состояний — стратегия.


Нет, он не лучший. Он просто больше подходит к описанной ситуации.

O>Ответьте, пожалуйста, только на один вопрос — чем тогда выражать статус проекта ? Магическими числами ?


Я бы использовал enum, но это не суть важно, на выбор между State/Strategy это не повлтяет.

O>По-моему, в классе табличной записи все равно окажется поле типа state/status/current, которое будет

O>представлять разные состояния проекта. И объекту "задача" необязательно себя рисовать.
O>Главное назначение state здесь может быть связано с выведением нужного типа (для полиморфной обработки
O>другими классами, например), а вовсе не с отрисовкой.

Совершенно верно. То что вы описали — это и есть Strategy. В зависимости от значения текущего статуса задачи будет выбрана та или иная стратегия отрисовки. State тут ни к чему, только дополнительное усложнение.

O>P.S. Это лишь мое мнение (ну не могут в принципе два компьютерщика прийти к одинаковым выводам).


Могут, но точно не на форуме.
Re[9]: Паттерн для представления разных состояний
От: okman Беларусь https://searchinform.ru/
Дата: 29.09.10 13:49
Оценка:
Да, интересная оказалась тема. Немного поразмышляв, я решил, что лучше всего будет
выразить свои мысли в виде практического примера. Исключительно с целью пояснений,
почему же я отстаиваю State, а вовсе не для каких-то провокаций.

//-----------------------------------------------------------------------------

Итак, у нас есть таблица со списком разных типов проектов, причем каждый проект может
находиться на разной стадии выполнения. Данную таблицу нужно отображать на экране,
причем цвета и текст выбирать в зависимости от сочетания "тип проекта/стадия выполнения".

Пусть будет пять типов проектов — Web, Desktop, Mobile, Embedded, Database, и пять состояний
— Prepare, Coding, Testing, Release, Support. Графически тип проекта будет выражаться цветом фона,
а его состояние пусть записывается соответствующей надписью на этом фоне.

Создаем иерархию классов Project с конкретными потомками — WebProject, DesktopProject и остальными.
Аналогично, создаем иерархию состояний с абстрактным State в верхушке — PrepareState, CodingState и т.д.
И будет еще View — иерархия классов для отображения: HtmlView для отображения на веб-странице,
PrinterView для печати на принтере и другие.

Теперь, собственно, рабочий цикл.
Когда некий проект нужно выразить в HTML-формате, программа создает конкретный экземпляр View,
в данном случае HtmlView, и передает ему список экземпляров Project, которые нужно отобразить.
Список, естественно, обходится в цикле, и вот тут заключается главное.

Пусть (ну пожалуйста, я знаю, что это может показаться некрасивым, но дочитайте) и Project,
и State реализуют интерфейс IDraw (c методом Draw, принимающим указатель на View).
Тогда обход будет исключительно компактным:

// Где-то в недрах HtmlView...

foreach (Project p in projectsDatabase)
    {
    p.Draw(this);
    }


Поясню — Draw конкретного Project-а сначала устанавливает "свой" цвет фона, а затем вызывает Draw
внутреннего объекта State, который, в свою очередь, отвечает за надпись. Разумеется, нужны
реализации Draw с разными типами View — короче, visitor в чистом виде.

А теперь представьте себе, каким будет код обхода элементов, если State — простое перечисление,
а Project вообще не полиморфный. Получаем двадцать пять комбинаций if...else, о чем и писал в самом
начале автор темы (5 типов проектов, помноженных на 5 состояний для каждого).
И вовсе не трудно представить сценарий, когда сочетаний проектов и состояний будет на порядок больше.
Кстати, это только реализация для HtmlView, остались и другие менеджеры отображения.

Я отлично понимаю, почему Вы говорили о неправильном архитектурном дизайне, да мне и самому
сигнатура Project.State.Draw(View) не очень-то по душе.

Наверняка нельзя сказать, но для определенных входных условий такой подход имеет право на жизнь,
хотя бы с позиций упрощения логики программы. А если State и Project в плане отрисовки связаны более
запутанными отношениями, можно построить параллельные иерархии с большими ветками, где будут более
специализированные наследники State — WebPrepareState, DesktopReleaseState и т.д.

Выслушаю любую критику.
Re[10]: Паттерн для представления разных состояний
От: Lloyd Россия  
Дата: 29.09.10 14:02
Оценка:
Здравствуйте, okman, Вы писали:

O>Выслушаю любую критику.


Реализуем Draw как extension-метод и получаем все тот же красивый код, но без косяков типа UI-логика в сущностях.
extension-метод — выбирает подходящую реализацию рисовальщика и зовет его Draw.

State-e оказался орять не нужен.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.