Форум   Статьи   Новости   Файлы   Bugtraq   Сниффер   Друзья   О Клубе
Вернуться   HPC / Кодинг / .NET / C#
   
  Страница 1
  , 11:54   #1
Местный
 
Локация: Cyberspace
Регистрация: 01.07.2008
Сообщений: 122

Репутация: 75 / 1
Exclamation Небольшой опыт - автоматы

По рабочей деятельности пришлось столкнуться с разработкой надстройки под Autodesk Vault. Надо было спроектировать модуль задач - элемент СЭД. Учитывая специфику платформы разработку вели с 0. Еще один маленький момент : карточка задачи не ограничивалась элементарными состояниями создана / в работе / выполнена / отклонена. Согласно ТЗ она проходила несколько дополнительных стадий согласования. Вот такая вот вундервафля должна была получиться на выходе. Вот как раз о состояниях и решение их обработки я сейчас хочу рассказать.

Когда у карточки мало состояний - можно обойтись парой методов с case или if условий. Когда же их много то начинается путаница и усложняется поддержка кода, вот пример подобных ужасов:

Hide:
Чтобы просмотреть данный текст, авторизуйтесь на форуме.


И это только стартовая установка состояний компонентов формы. Как вы понимаете эта дорожка до добра не доведет. Тогда был выбран другой путь - через автоматы. В универскую бытность я как раз писал небольшой проект по детерминированным и недетерминированным автоматам. В моей задачи было достаточно детерминированного автомата.

Цитата:
Детерминированным конечным автоматом (ДКА) называется такой автомат, в котором нет дуг с меткой ε (предложение, не содержащее ни одного символа), и из любого состояния по любому символу возможен переход в точности в одно состояние.
Давайте в краце рассмотрим данный метод и простейший вариант реализации. В моей задаче был построен следующий автомат:
Состояния - состояние в котором находится в данный момент карточка задания
Словарь - возможные действия с заданием, такие как: согласование, исполнение, отклонение
Переходы - к какому из внутренних состояний карточка задания может перейти по действию пользователя.

И так, проблему Мы в кратце рассмотрели перейдем к реализации

Для начала надо описать что такое шаг между состояниями, по каким символам он происходит.
Соответственно класс Step будет выглядеть примерно вот так:

Hide:
Чтобы просмотреть данный текст, авторизуйтесь на форуме.


code:
Кстати
[DebuggerDisplay("Symbol={Symbol} States=[{Begin},{End}] Action={StepAction.ToString()}")]
позволяет описать как конкретно будет отображаться объект нашего класса 
во время дебагинга в Watch
Обратите внимания, что мы создаем делегат StepAction, в дальнейшем он пригодится для задания автомату функции которая выполнится при переходе. Перечисление StepResult будет давать понять автомату: в последнее состояние мы пришли, сделали или нет переход и тп.
Теперь имеет смысл описать что-же такое состояние.
Соответственно класс State будет выглядеть примерно вот так:
Hide:
Чтобы просмотреть данный текст, авторизуйтесь на форуме.

Думаю тут, как и в предыдущем классе особых комментариев не требуется =)

Теперь перейдем к сердцу нашего автомата.
Соответственно класс Automat будет выглядеть примерно вот так:
Hide:
Чтобы просмотреть данный текст, авторизуйтесь на форуме.


Рассмотрим его по порядку. Для начала у автомата должен быть набор состояний, переходов и символов перехода. Их мы как раз уже определили выше. В данном классе они описываются:
C# highlight
        private readonly List<Step> _steps = new List<Step>();
        private readonly List<State> _states = new List<State>();
        private readonly List<string> _symbols = new List<string>();
        private State _last = null;
        private State _current = null;
Состояния _last и _current соответственно состояния в котором находится автомат сейчас и конечное состояние автомата.
Перед использование автомата его необходимо описать. Первое - это все состояния автомата:

C# highlight
public void AddState(string stateName, StepAction action, bool isLast = false)
В данной функции мы задаем имя, действие которое необходимо произвести и флаг того,
что это состояние конечное. Далее необходимо описать переходы.

C# highlight
public void AddStep(string begin, string end, string symbol, StepAction action)
Тут begin, end - это имена состояний между которыми происходит переход, symbol -
символ по которому будет осуществлен переход(После добавления перехода символ автоматически добавляется в соответствующий словарь), ну и action как и с состоянием действие которое производится при переходе. Замечу, что если функция вернет false -
переход осуществлен не будет.

C# highlight
public void SetStartState(string name)
Задает состояние автомата откуда он начнет работать.

C# highlight
public StepResult Move(string symbol)
Инициирует автомат к переходу по заданному символу.
Теперь рассмотрим как он используется. Я приведу пример инициализации автомата и 1 действия

Hide:
Чтобы просмотреть данный текст, авторизуйтесь на форуме.


Как видно данное решение более элегантно нежели куча if и case.
Надеюсь кому-нибудь поможет и не судите строго=)
__________________
Live long and prosper.
[SIGPIC][/SIGPIC]

Последний раз редактировалось FANGarh; 18.09.2015 в 11:57.
Пользователь вне форума    
Наши Спонсоры
 

Метки
automat

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Pаздача от Kontika Kontik Раздачи 248 19.09.2015 17:47
Раздача WoT al1916 Раздачи 80 30.06.2015 15:58
Раздача всего от CHECHENMEN CHECHENMEN Раздачи 80 01.06.2014 19:41
Небольшой конкурс от «vpnlux». Проигравших не будет! openssource Раздачи 0 11.01.2014 15:22
Раздача аккаунтов WoT Lolka124 Раздачи 11 05.09.2013 22:10



Часовой пояс GMT +2
Powered by vBulletin® 3.x.x Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.

Copyright © 2008 - 2013 «HPC» Реклама на сайте Правила Форума Пользовательское соглашение Работа на сайте
При копировании материалов ставьте ссылку на источник
Все материалы представлены только в ознакомительных целях, администрация за их использование ответственности не несет.