Дерево функций как составить

УДК 004

РАЗРАБОТКА ДИАГРАММЫ «ДЕРЕВО ФУНКЦИЙ»

Бабенко А.В.1, Саганенко А.А.2, Новикова Т.Б.3
1Магнитогорский государственный технический университет им. Г. И. Носова, студентка группы АПИп-14 института Энергетики и Автоматизированных Систем
2Магнитогорский государственный технический университет им. Г. И. Носова, студентка группы АПИп-14 института Энергетики и Автоматизированных Систем
3Магнитогорский государственный технический университет им. Г. И. Носова, кандидат педагогических наук, доцент кафедры прикладной информатики

Аннотация
В данной статье представлено моделирование бизнес-процесса «Разработка диаграммы Дерево функций» с использованием методологии ARIS.

Ключевые слова: дерево функций, методология ARIS, МОДЕЛИРОВАНИЕ БИЗНЕС-ПРОЦЕССА


DEVELOPMENT CHART «TREE OF FUNCTIONS»

Babenko A.V.1, Saganenko A.A.2, Novikova T.B.3
1Nosov Magnitogorsk State Technical University, student group APIp-14 Energy Institute and Automated Systems
2Nosov Magnitogorsk State Technical University, student group APIp-14 Energy Institute and Automated Systems
3Nosov Magnitogorsk State Technical University, Ph.D., Associate Professor, Department of Applied Informatics

Abstract
This article presents the modeling of the business process «diagram Development functions tree» using ARIS methodology.


Библиографическая ссылка на статью:
Бабенко А.В., Саганенко А.А., Новикова Т.Б. Разработка диаграммы «Дерево функций» // Современная техника и технологии. 2016. № 11. Ч. 2 [Электронный ресурс]. URL: https://technology.snauka.ru/2016/11/11393 (дата обращения: 15.04.2023).

Дерево функций позволяет графически описать функции отделов компании и построить их в иерархическом порядке. Диаграмма позволяет организовать внешние отношения компании: отношения с инвесторами, конкурентами, клиентами, а также определить внутреннюю структуру компании. Дерево функций отображает детализацию деятельностей всех отделов организации [1, 2].

Рассмотрим внутреннюю структуру организации и функций, выполняемые отделами на примере магазина G. Разработка дерева функций начинается с определения отделов организации. Такими отделами выступают: «директор» организации, «зам. директора», «менеджер по продажам», «продавец консультант», «главный бухгалтер».

В каждой организации есть работники и их функции, которые входят в обязанности. Диаграмма «дерево функций” наглядно показывает функции каждого работника [3, 4].

Для примера более подробно рассмотрим функции Директора.

  1.  «Финансово-экономическая и хозяйственная деятельность магазина» – контроль за стабильным товарооборотом магазина, контроль издержек, контроль стоимости основных фондов и оборотных средств;
  2. «Работа с законодательными актами» – соблюдение материально-технического обеспечения магазина и продажи товара;
  3. «Работа с нормативными документами магазина» – оформление пакета документов необходимых для открытия магазина и его содержания;
  4. «Мониторинг платежей кредиторов и дебиторов» – учет задолженностей магазина и покупателей;
  5. «Разработка и реализация мер по модернизации магазина» – поиск необходимых способов для усовершенствования магазина;
  6. «Посещение собрания»;
  7. «Организация повышения квалификации персонала» – проведение тренингов, семинаров, лекций для персонала;
  8. «Организация деятельности магазина»

Функции Заместителя директора:

  1. Финансово-экономическая и хозяйственная деятельность магазина- анализ деятельности предприятия
  2. Заключение хозяйственных и финансовых договоров
  3. Составление отчетности, приказов и распоряжений
  4. Мониторинг недостатков работы магазина и мер их ликвидации – прогнозирование недостатков, оперативный анализ
  5. Работа с заказчиками и партнерами – заключение новых договор с партнерами
  6. Организация повышения квалификации персонала магазина- повышение конкурентоспособности предприятия
  7. Помощь директору в управлении магазина

Способ представления функций в виде дерева позволяет уменьшить степень сложности и является статичным описанием функции.Дерево функций  – эффективный инструмент в деятельности аналитика, ИТ-специалиста, даже просто сотрудника организации, т.к. с помощью данной диаграммы можно в простой и наглядной форме представить основные задачи сотрудников на предприятии [5, 6]. Построить её можно в любом графическом редакторе – on-line или of-line. Модель актуальна не только среди специалистов в области ИТ, но и среди студентов по направлениям 09.03.03 «Прикладная информатика» и 38.03.05 «Бизнес-информатика».

  • Результаты данной статьи могут быть использованы при написании диплом работы.

Библиографический список

  1. Давлеткиреева Л.З. Профессиональная подготовка будущих ИТ-специалистов в рамках информационно-предметной среды: учеб.-метод. пособие. -Магнитогорск: МаГУ, 2006. -86 с.
  2. Давлеткиреева Л.З., Скокова И.К. Актуальность и преимущества проведения Интернет-конференции как одной из форм обмена опытом между образовательными учреждениями/Л.З. Давлеткиреева,И.К. Скокова//Современные тенденции развития науки и производства: сборник материалов Международной научно-практической конференции (23-24 октября 2014 года) -в 4-х томах, Том 1. -Кемерово: ООО «ЗапСибНЦ», 2014 -196 с. -C. 99-101.
  3. Давлеткиреева, Л. З. Инновационные информационно-педагогические технологии в образовании: опыт проведения ежегодной одноименной Интернет-конференции-конкурса/Л. З. Давлеткиреева, И. К. Скокова//Современные информационные технологии и ИТ-образование : сб. избранных трудов IX Международной научно-практической конференции. Под ред. проф. В. А. Сухомлина. -М.: ИНТУИТ.РУ, 2014. -957 с. -C. 573-586.
  4. Курзаева Л.В. Введение в теорию систем и системный анализ: учеб.пособие/Л.В. Курзаева. -Магнитогорск: МаГУ, 2015. -211 с.
  5. Курзаева Л.В. Дистанционный курс «Инструментальные методы поддержки принятия решений»: электронный учебно-методический комплекс//Хроники объединенного фонда электронных ресурсов Наука и образование. 2016. -№ 1 (80). -С. 2.
  6. Курзаева Л.В. Дистанционный курс «Основы математической обработки информации»: электронный учебно-методический комплекс//Хроники объединенного фонда электронных ресурсов «Наука и образование». -2014. -Т. 1, № 12 (67). -С. 117.


Все статьи автора «Саганенко Анна»

Дерево
функций (Function Tree) — иерархическая модель
видов деятельности предприятия,
обеспечивающих достижение дерева целей.

Вершиной
дерева функций является главная цель
предприятия, ветви дерева представляют
собой функции (или работы), которые
необходимо реализовать для достижения
главной цели предприятия и подчиненных
ей целей нижнего уровня.

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

Дерево
функций является основой для построения
бизнес-процессов организации.

Дерево
бизнес-процессов — иерархически
упорядоченная совокупность бизнес-процессов.

Дерево
бизнес-процессов является систематизированным
отражением модели предприятия в рамках
процессного управления. Древовидная
структура процессов является простой
моделью совокупности процессов
предприятия, хотя на самом деле модель
предприятия имеет более сложную структуру
и обладает более сложными и не всегда
однозначными связями. Дерево
бизнес-процессов пересекается с системой
стратегического управления предприятием,
а именно, с деревом целей. Дерево целей
разворачивается от миссии через
стратегические цели к оперативным целям
предприятия, оперативные цели в свою
очередь реализуются с помощью
бизнес-процессов.Дерево бизнес-процессов
— это абстрактная модель, структурированная
простейшим образом. Как правило, при
выделении бизнес-процессов разрабатывается
дерево бизнес-процессов, в котором
процессы классифицируются на основные,
обеспечивающие и управленческие.
Основной задачей данной классификации
является облегчение работы по выделению
процессов, снижение вероятности пропуска
важных процессов, а также наглядное
представление выделенных бизнес-процессов,
разбитых на небольшие группы.

72. Основные требования к кадрам в страховом бизнесе

В
соответствии с вышеизложенным работа
с кадрами в страховой компании должна
определяться как комплексное воздействие
на трудовой коллектив для достижения
целей компании.

Управление
кадрами формирует благоприятную среду,
в которой реализуется трудовой потенциал,
развиваются способности; люди получают
удовлетворение от выполненной работы
и общественное признание своих достижений.
Главный акцент делается в сторону
долговременно развития трудового
потенциала страховых работников.
Вложения в человеческие ресурсы и
кадровую работу становятся долговременным
фактором конкурентоспособности страховой
компании в условиях резких изменений
ее внешней среды.

В
связи с тем что существует объективная
связь процессов развития персонала с
развитием страховой компании, развитие
человеческого потенциала (интеллектуального
и социального) является для страховой
компании частью инвестиций, а не расходов.
С этим согласен Анатолий Купчин,
генеральный директор кадрового агентства
«Агентство Контакт»: «К сожалению,
в страховом бизнесе полезность инвестиций
в персонал понимают далеко не все. И
даже те, кто понимает, все равно испытывают
на себе кадровый голод». Тем не менее
в последнее время виден явный прогресс
в отношении к персоналу компаний: из
наемной рабсилы он переходит в новую
ценностную категорию — «человеческий
капитал» (здесь слово «капитал»
ключевое), существенно «прибавив в
весе». Отличительная особенность
капитала — в его самовозрастающей
стоимости. По подсчетам экспертов,
эффект от инвестиций в персонал может
составлять до 300% годовых. Еще одна
характеристика капитала (в основном
овеществленного) — моральный и физический
износ. Эти черты присущи и человеку как
одной из форм интеллектуального капитала.
Но важно помнить главное — именно человек
обеспечивает прирост стоимости
совокупного капитала (в любых его
формах).

Специфика
страховой деятельности предопределяет
особенности персонала страховой
компании. Это связано, прежде всего, с
наличием у страховых работников
определенных профессиональных навыков
и знаний, связанных с общими направлениями
страховой деятельности. Например, многие
специалисты по добровольному медицинскому
страхованию помимо экономического
имеют и медицинское образование, по
страхованию крупных промышленных
объектов — экономическое и техническое
образование. Появление комплексных
продуктов требует расширения диапазона
знаний у страховых специалистов.

Примечание.
Страховые работники должны обладать
определенными профессиональными
навыками и знаниями, связанными с общими
направлениями страховой деятельности.
Появление комплексных продуктов требует
расширения диапазона их знаний.

Классификация
страховых работников

По
функциональным обязанностям страховые
работники сгруппированы в соответствующие
линейные или функциональные структурные
подразделения страховой компании.

Персонал
страховой компании можно разделить на
две большие группы: front-office и back-office.
Соотношение количества персонала в
этих двух группах составляет 70 и 30%
соответственно.

В
группу front-office входят специалисты,
которые связаны с процессом страхования.
Часть подразделений занимается
непосредственно продажей страховых
продуктов. Это сеть различных каналов
продаж страховых продуктов. Большая
часть сотрудников таких подразделений
могут не иметь предшествующего опыта
работы в страховании и при этом быть
весьма успешными специалистами по
продажам. Также в front-office существуют
подразделения, которые занимаются
непосредственно разработкой страховых
продуктов, оценкой страховых рисков,
урегулированием убытков. Эта часть
состоит в основном из сотрудников со
специальным образованием и опытом
работы в страховании. В большинстве
случаев сотрудники front-office специализируются
на определенных видах страхования,
например автострахование, добровольное
медицинское страхование, страхование
имущества, страхование грузов.

Основными
действующими лицами в подразделениях
front-office, связанных с продажей страховых
продуктов, являются агенты и продавцы.
Несмотря на то что нередко неспециалисты
ставят знак равенства между этими двумя
профессиями, существует большая разница
между этими двумя категориями работников.

Агент
— это «вольный» работник, главная
задача которого — приносить бизнес в
компанию и получать комиссионного
вознаграждение, которое непосредственно
зависит от размера страховой премии,
которую получила компания. Агент
планирует свою работу так, как считает
нужным, и нередко работает на несколько
страховых компаний одновременно. У него
нет фиксированного рабочего дня и
зарплаты. Как правило, он не является
штатным работником компании.

Продавец
— это штатный работник компании, работающий
в команде, для которого важны корпоративные
нормы, традиции и принадлежность к
коллективу. Это сотрудник, который
непосредственно заинтересован в
успешности работы его подразделения и
компании в целом, так как он сам является
частью этой системы. Продавец получает
фиксированную заработную плату и
поощрение в виде процента от собранной
страховой премии или бонуса по результатам
выполнения плана. В страховом бизнесе
на сегодняшний день прослеживается
тенденция переноса центра тяжести с
агентов на продавцов. Основное требование,
предъявляемое к продавцам, — успешный
опыт любых продаж, а также, желательно,
высшее образование и, самое главное,
желание работать с людьми.

В
категорию back-office входят подразделения,
которые непосредственно не связаны с
процессом страхования, однако обеспечивают
функционирование бизнеса. Как правило,
в эту часть входят следующие подразделения:
финансовая служба, бухгалтерия,
администрация, маркетинг, реклама,
пресс-служба. Для большинства специалистов
back-office опыт работы в страховании не
является обязательным, но учитывается
как положительный фактор при приеме на
работу. Особенно важен этот опыт для
специалистов финансовой и методологической
служб страховой компании, а также
отдельных позиций в маркетинге и рекламе,
поскольку именно там существует ярко
выраженная отраслевая специфика.

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

Место
оценки персонала в системе управления
персоналом

страховой
организации

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

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

В
связи с вышесказанным описание целей
ежегодной аттестации одной из основных
составляющих системы оценки персонала
может выглядеть следующим образом:

1.
Принятие решений, связанных с изменением
компенсационного пакета, имеющих
конкретные материальные последствия
для работников:


изменение заработной платы;


изменение системы поощрения (наказания);


повышение мотивации.

2.
Принятие решений, связанных с развитием
организации (приведение в соответствие
человеческих ресурсов с планами
организации):


получение обратной связи;


выявление потенциала;


информирование сотрудников о том, чего
ждет от них фирма;


развитие карьеры;


личное развитие;


корректировка планов организации;


информация для планирования человеческих
ресурсов.

3.
Принятие решений, связанных с оценкой
текущей деятельности (положения) всей
организации и выявлением рабочих
проблем. При этом в ходе аттестации
работника оцениваются:


прошлая деятельность;


достижение результатов;


потребность в обучении;


выявление рабочих проблем;


улучшение деятельности.

Эффективная
система оценки дает возможность
совершенствовать используемые методы
отбора кадров. Специалисты, занимающиеся
отбором, при этом получают важную
информацию, позволяющую определить
качество и прогностический потенциал,
действующий в организации систем отбора.
Результаты оценки показывают возможность
прогноза профессиональной успешности
кандидатов на основе используемых
методов и процедур отбора. Без такого
рода обратной связи совершенствование
системы отбора было бы невозможно.

Выявляя
работников, способных выполнять более
сложную и ответственную работу (кандидатов
на продвижение), оценка рабочих показателей
помогает решить задачи формирования
кадрового резерва, планирования карьеры
работников и кадрового планирования.
Оценка рабочих показателей позволяет
получить ценную информацию о той пользе,
которую дает участие работников в тех
или иных учебных программах.

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

Рассмотрим
подробнее процесс постановки
формализованной системы оценки персонала
на примере страховой компании и ее
интеграции в систему управления компании
в целом.

Пример
оценки персонала в российской страховой
компании

Российская
страховая компания основными своими
целями на ближайшие три года поставила:


повышение объема сбора страховых премий
не менее чем на 25% ежегодно;


расширение филиальной сети;


повышение узнаваемости своего бренда.

Исходя
из этого, приоритетными задачами в
области управления персоналом должны
быть:


подбор квалифицированного продающего
персонала — в первую очередь в регионах;


повышение качества обслуживания
клиентов;


повышение компетентности сотрудников
в области предлагаемых продуктов
страхования, задействованных в процессах
продаж и обслуживания клиентов;


разработка системы оплаты труда,
стимулирующей сотрудников на достижение
целей компании.

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

Словарь
управления персоналом. Деловая оценка
персонала — целенаправленный процесс
установления соответствия качественных
характеристик персонала (способностей,
мотиваций и свойств) требованиям
должности или рабочего места.

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

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

Можно
выделить два вида критериев оценки:
количественные и качественные. С помощью
количественных критериев оценки, их
еще называют KPI <1>, мы можем оценивать,
достигают ли сотрудники необходимых
компании результатов или нет. Эти
показатели строятся на планах компании
и подразделений, отражают то, что может
быть измерено и подчитано. Для страховых
компаний это могут быть:


план сбора страховой премии;


достижение желаемого уровня рентабельности;


количество жалоб клиентов;


принятие на страхование «качественных
рисков» — показателем может быть
уровень выплат.

———————————

<1>
Key performance indicators — ключевые показатели
эффективности деятельности сотрудников.

Качественные
критерии оценки (их еще называют
компетенции) позволяют оценить уровень
профессионального развития и потенциала
сотрудников. Кроме того, компетенции
сами по себе являются описанием эталонного
поведения сотрудников. Это очень важный
аспект в оценке, поскольку для реализации
целей бизнеса очень важно не только
понимать, к какому результату мы
стремимся, но и знать, за счет чего этого
результата можно достичь. Поэтому
компетенции, проистекающие из качественных,
стратегических целей компании и ее
ценностей, являются своего рода
стратегическим стержнем системы
управления персоналом. Для страховой
компании данные критерии могут быть
следующими:


клиентоориентированность;


повышение качества страховых продуктов.

Вместе
KPI и компетенции определяют, что и как
должен делать персонал, и на основании
этого могут быть построены:


система оценки: каким образом, с помощью
каких инструментов оценивается
соответствие сотрудников установленным
критериям, и система подбора: какие
сотрудники принимаются на работу;


система мотивации: за какие достижения
платить сотрудникам, за что поощрять
нематериально;


система обучения: какие качества
развивать в сотрудниках.

Обратимся
к нашему примеру и рассмотрим качественные
и количественные критерии для специалистов
по страхованию (табл.).

Цель

Количественные
критерии (KPI)

Качественные
критерии

(компетенции)

Повышение

качества

обслуживания

клиентов


Количество договоров,

заключенных
повторно


Объем страховой премии


Количество жалоб на качество

обслуживания


Количество благодарностей

от
страхователей


Уровень удовлетворенности

страхователей
качеством

обслуживания
по результатам

опросов


Соблюдение стандартов

качественного
обслуживания

клиентов
+ уровень

развития
компетенции

«Клиентоориентированность»


Содержание отзывов

клиентов
о работе данного

специалиста

Роль
же, отводящаяся в такой интегрированной
системе управления персоналом системе
оценки, как мы уже говорили, особая и
вот почему. На результатах оценки, как
уже отмечалось выше, строятся все решения
в области управления персоналом.
Оперативная оценка работы сотрудника,
которая неформально проводится линейным
руководителем ежедневно, в конце месяца,
квартала, года, формализуется и определяет
размер премии сотрудников. Оценка
профессионального уровня и потенциала
сотрудника определяет размер его оклада,
что стимулирует сотрудников повышать
свой профессиональный уровень за счет
обучения. Недочеты, выявившиеся в ходе
ежегодной оценки сотрудников на основе
компетенций, определяют тематический
план обучения сотрудников. В графическом
виде этот алгоритм представлен на рис.
1. Построенная таким образом система
управления персоналом позволяет влиять
на поведение сотрудников и прогнозировать
его, а особая роль оценки в этом процессе
еще раз подтверждает тезис, вынесенный
нами в заголовок статьи: оценка является
универсальным инструментом управления.

Процесс
разработки критериев оценки и интеграции

подсистем
управления персоналом

┌─────────────────────────────┐

│ Цели
компании │

└──────────────┬──────────────┘

┌────────────────────────┴────────────────────────┐

│/
│/

┌──────────────┴────────────────────┐
┌────────────────────┴──────────────┐

│ Качественные
показатели │ │ Количественные показатели

│ (имидж,
качество обслуживания │ │ (объем продаж,
количество │

│ клиентов,
развитие новых │ │ новых клиентов,
рентабельность, │

│ направлений
деятельности) │ │ узнаваемость бренда
и т.п.) │

└──────────────┬────────────────────┘
└────────────────────┬──────────────┘

│/
│/

┌──────────────┴────────────────────┐
┌────────────────────┴──────────────┐

│ Оценочные
компетенции │ │Ключевые показатели
эффективности -│

│ профессионально
важные качества, │ │ нормативы, плановые
показатели │

│которыми
должны обладать сотрудники│ │которых
должны достигать сотрудники│

│ для
того, чтобы выполнять свою │ │ для того,
чтобы цели и задачи │

│ работу
на «отлично» │ │ компании были
выполнены │

│ │ │ Индивидуальны
для каждой должности│

└──────────────┬────────────────────┘
└────────────────────┬──────────────┘

│/
│/

┌──────────────┴────────────────────┐
┌────────────────────┴──────────────┐

│ Система
плановой ежегодной оценки │ │ Система
оперативной оценки │

│ профессионального
потенциала │ │ деятельности сотрудников

│ │ │ (результаты
работы) │

└──────┬───────────────────┬────────┘
└────────────────────┬──────────────┘

│/
│ │/

┌──────┴────────────────┐
│ ┌──────────────────────────────────┴──────────────┐

│ Система
обучения, │ │ │ Система оплаты труда

│ направленная
│ │ ├─────────────────────────┬───────────────────────┤

│ на
восполнение │ │ │ Постоянная часть │
Переменная часть │

│ недостатков
и развитие│ │ │вознаграждения —
окладно-│вознаграждения — премии│

│ профессионально
важных│ │ │ разрядная сетка. Размер │
и бонусы, привязанные │

│ качеств,
необходимых │ │ │ оклада привязан к
уровню│ к выполнению ключевых │

│ для
успешной работы │ └─>│ должности и
уровню │ показателей │

│ │<────┤
квалификации сотрудника │ эффективности

│ │ │ на
данной должности │ │

└───────────────────────┘
└─────────────────────────┴───────────────────────┘

Рис.
1

Однако
реалии сегодняшнего бизнеса таковы,
что для большинства страховых компаний
реализация описанного выше подхода —
это задача даже не ближайшего, а
среднесрочного развития. Поскольку
управлению персоналом во многих компаниях
не уделяется должного внимания, так как
она требует большой работы и от менеджмента
компании, и от службы управления
персоналом в целом. Кадровая служба
по-прежнему рассматривается как
второстепенное подразделение. Она слабо
влияет на стратегию и тактику управления
страховой компанией. В настоящее же
время основное внимание службы управления
персоналом, как правило, сосредоточено
на осуществлении кадрового документооборота
(прием и увольнение сотрудников), помощи
сотрудникам в решении их индивидуальных
рабочих проблем, проверки состояния
трудовой дисциплины, а оценка персонала
(даже в форме традиционной аттестации)
до сих пор является наименее распространенной
процедурой в системе управления
персоналом российских компаний. Сегодня
в большинстве случаев она существует
в неформализованном управленческом
виде — руководитель по известным ему
одному критериям оценивает сотрудников,
находящихся у него в непосредственном
подчинении. На основании этой оценки
он принимает управленческие решения,
подчас без обратной связи с подчиненными
— как он оценивает их работу, их
профессиональный потенциал, чего он от
них ждет и почему принимает именно
такие, а не другие решения о премировании,
наказании, перемещении сотрудников.

В
таком виде оценка не может считаться
настоящим управленческим инструментом,
поскольку не позволяет влиять на
поведение сотрудников и прогнозировать
его — люди просто не знают и не понимают,
чего от них ждет компания в целом и их
непосредственный руководитель в
частности. Отсюда так много разговоров
о самодурстве отдельных начальников,
так много демотивированных сотрудников,
относящихся к компании потребительски:
сотрудники нелояльны к компании,
поскольку «игра» с ними ведется не
в открытую, отношения строятся не на
партнерской основе взаимных соглашений
(«я жду от тебя такой-то работы и за
это готов вознаграждать тебя вот таким
образом»), а на основе власти, принуждения
и манипуляций. От такой ситуации страдают
и бизнес, сотрудники которого работают
спустя рукава, а подчас и занимаясь
откровенным вредительством, и сами
сотрудники. Или, напротив, отношения
между работниками и работодателем могут
строиться на жалости и сострадании, не
позволяющей работодателю предъявлять
к сотруднику элементарные требования,
— в этом случае страдает в первую очередь
бизнес, а не наемный сотрудник.

«Между
тем западные исследования достоверно
показывают, что компании, применяющие
формализованную и системную оценку в
управлении персоналом, значительно
эффективнее и успешнее аналогичных
компаний, не использующих оценочные
процедуры» [3]. И такие данные вполне
логичны: ведь оценка персонала позволяет
представлять себе реальное качество
человеческих ресурсов, имеющихся в
распоряжении компании, и управлять ими:
отбраковывать худших, стимулировать
средних и вознаграждать лучших
сотрудников. В такой ситуации вполне
правомерно говорить об оценке персонала
как о важном инструменте управления —
ведь она является основой для принятия
важных кадровых и управленческих
решений. По нашему мнению, отсутствие
надежных систем оценки персонала может
привести к тому, что организацией могут
быть потеряны способные работники.

Тем
не менее идеология кадровой работы,
соответствующая новым рыночным реалиям
современной России, уже формируется, и
опыт страховых компаний — лидеров
российского рынка позволяет выделить
новые типичные черты в подходах к
управлению персоналом:


повышение эффективности системы подбора,
найма и расстановки сотрудников;


система мотивации и оплаты труда
справедлива по отношению к другим
страховым компаниям и является хорошо
управляемой;


индивидуальные проблемы отдельных
страховых работников решаются быстро,
справедливо и эффективно;


заработная плата страховых работников
базируется на результатах индивидуального
труда и эффективности работы
соответствующего структурного
подразделения страховой компании;


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

«Теория систем и системный анализ»

И. Б. Родионов

Лекция 4: Функциональное описание и моделирование систем

Изучение любой системы предполагает создание модели системы, позволяющей произвести анализ и предсказать ее поведение в определенно диапазоне условий, решать задачи анализа и синтеза реальной системы. В зависимости от целей и задач моделирования оно может проводиться на различных уровнях абстракции.

Модель — описание системы, отражающее определенную группу ее свойств.

Описание системы целесообразно начинать с трех точек зрения: функциональной, морфологической и информационной.

Всякий объект характеризуется результатами своего существования, местом, которое он занимает среди других объектов, ролью, которую он играет в среде. Функциональное описание необходимо для того, чтобы осознать важность системы, определить ее место, оценить отношения с другими системами.

Функциональное описание (функциональная модель) должно создать правильную ориентацию в отношении внешних связей системы, ее контактов с окружающим миром, направлениях ее возможного изменения.

Функциональное описание исходит из того, что всякая система выполняет некоторые функции: просто пассивно существует, служит областью обитания других систем, обслуживает системы более высокого порядка, служит средством для создания более совершенных систем.

Как нам уже известно, система может быть однофункциональной и многофункциональной.

Во многом оценка функций системы (в абсолютном смысле) зависит от точки зрения того, кто ее оценивает (или системы, ее оценивающей).

Функционирование системы может описываться числовым функционалом, зависящем от функций, описывающих внутренние процессы системы, либо качественным функционалом (упорядочение в терминах «лучше», «хуже», «больше», «меньше» и т.д.)

Функционал количественно или качественно описывающий деятельность системы называют функционалом эффективности.

Функциональная организация может быть описана:

  • алгоритмически,
  • аналитически,
  • графически,
  • таблично,
  • посредством временных диаграмм функционирования,
  • вербально (словесно).

Описание должно соответствовать концепции развития систем определенного класса и удовлетворять некоторым требованиям:

  • должно быть открытым и допускать возможность расширения (сужения) спектра функций, реализуемых системой;
  • предусматривать возможность перехода от одного уровня рассмотрения к другому, т.е. обеспечивать построение виртуальных моделей систем любого уровня.

При описании системы будем рассматривать ее как структуру, в которую в определенные моменты времени вводится нечто (вещество, энергия, информация), и из которой в определенные моменты времени нечто выводится.

В самом общем виде функциональное описание системы в любой динамической системе изображается семеркой:

Sf = {T, x, C, Q, y, φ, η},

где T — множество моментов времени, х — множество мгновенных значений входных воздействий, С = {c: T → x} — множество допустимых входных воздействий; Q — множество состояний; y — множество значений выходных величин; Y = {u: T → y} — множество выходных величин; φ = {T×T×T×c → Q} — переходная функция состояния; η:T×Q → y — выходное отображение; с — отрезок входного воздействия; u — отрезок выходной величины.

Такое описание системы охватывает широкий диапазон свойств.

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

Примем, что система S выполняет N функций ψ1, ψ2, …, ψs, …, ψN, зависящих от n процессов F1, F2, …, Fi, …, Fn. Эффективность выполнения s-й функции

Эs = Эss) = Э(F1, F2, …, Fi, …, Fn) = Эs({Fi}), i = 1…n, s = 1…N.

Общая эффективность системы есть вектор-функционал Э = {Эs}. Эффективность системы зависит от огромного количества внутренних и внешних факторов. Представить эту зависимость в явной форме чрезвычайно сложно, а практическая ценность такого представления незначительна из-за многомерности и многосвязности. Рациональный путь формирования функционального описания состоит в применении такой многоуровневой иерархии описаний, при которой описание более высокого уровня будет зависеть от обобщенных и факторизованных переменных низшего уровня.

Иерархия создается по уровневой факторизацией процессов {Fi} при помощи обобщенных параметров {Qi}, являющихся функционалами {Fi}. Предполагается, что число параметров значительно меньше числа переменных, от которых зависят процессы. Такой способ описания позволяет построить мост между свойствами взаимодействующих со средой элементов (подсистемами низшего уровня) и эффективностью системы.

Процессы {Fi(1)} можно обнаружить на выходе системы. Это процессы взаимодействия со средой. Будем называть их процессами первого уровня и полагать, что они определяются:

  1. параметрами системы первого уровня — Q1(1), Q2(1), …, Qj(1), …, Qm(1);
  2. активными противодействующими параметрами среды, непосредственно направленными против системы для снижения ее эффективности — b1, b2, …, bk, …, bK;
  3. нейтральными (случайными параметрами среды) c1, c2, …, cl, …, cL;
  4. благоприятными параметрами среды d1, d2, …, dp, …, dP.

Среда имеет непосредственный контакт с подсистемами низших уровней, воздействуя через них на подсистемы более высокого уровня иерархии, так что Fi* = Fi*({bk}, {cl}, {dp}). Путем построения иерархии (параметры β-го уровня — процессы (β-1)-го уровня — параметры (β-1)-го уровня) можно связать свойства среды с эффективностью системы.

Параметры системы {Qj} могут изменяться при изменении среды, они зависят от процессов в системе и записываются в виде функционалов состояния Qj1(t).

Собственным функциональным пространством системы W называется пространство, точками которого являются все возможные состояния системы, определяемое множеством параметров до уровня b:

Q = {Q(1), Q(2), … Q(β)}.

Состояние может сохраняться постоянным на некотором интервале времени Т.

Процессы {Fi(2)} не могут быть обнаружены на выходе системы. Это процессы второго уровня, которые зависят от параметров Q(2) подсистем системы (параметров второго уровня). И так далее.

Образуется следующая иерархия описания: эффективность (конечное множество функционалов) — процессы первого уровня (функции) — параметры первого уровня (функционалы) — процессы второго уровня (функции) — параметры второго уровня (функционалы) и т.д. На каком-то уровне наши знания о функциональных свойствах системы исчерпываются, и иерархия обрывается. Обрыв может произойти на разном уровне для разных параметров (процессов), причем как на процессе, так и на параметре.

Внешние характеристики системы определяются верхним уровнем иерархии, поэтому часто удается ограничиться описанием вида ({Эi},{ψS}, {Fi(1)}, {Qj(1)}, {bk}, {cl}, {dp}). Число уровней иерархии зависит от требуемой точности представления входных процессов.

Графические способы функционального описания систем

Выше был рассмотрен способ обобщенного аналитического функционального описания систем. Очень часто при анализе и синтезе систем используется графическое описание, разновидностями которого являются:

  • дерево функций системы,
  • стандарт функционального моделирования IDEF0.

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

  • целевая функция;
  • базисные функции системы;
  • дополнительные функции системы.

Целевая функция системы соответствует ее основному функциональному назначению, т.е. целевая (главная) функция — отражает назначение, сущность и смысл существования системы.

Основные функции отражают ориентацию системы и представляют собой совокупность макрофункций, реализуемых системой. Эти функции обусловливают существование системы определенного класса. Основные функции — обеспечивают условия выполнения целевой функции (прием, передача приобретение, хранение, выдача).

Дополнительные (сервисные) функции расширяют функциональные возможности системы, сферу их применения и способствуют улучшению показателей качества системы. Дополнительные функции — обеспечивают условия выполнения основных функций (соединение (разведение, направление, гарантирование)).

Описание объекта на языке функций представляется в виде графа.

Описание объекта на языке функций в виде графа

Рис. — Описание объекта на языке функций в виде графа

Формулировка функции внутри вершин должна включать 2 слова: глагол и существительное «Делать что».

Дерево функций системы представляет декомпозицию функций системы и формируется с целью детального исследования функциональных возможностей системы и анализа совокупности функций, реализуемых на различных уровнях иерархии системы. На базе дерева функций системы осуществляется формирование структуры системы на основе функциональных модулей. В дальнейшем структура на основе таких модулей покрывается конструктивными модулями (для технических систем) или организационными модулями (для организационно-технических систем). Таким образом, этап формирования дерева функций является одним из наиболее ответственных не только при анализе, но и при синтезе структуры системы. Ошибки на этом этапе приводят к созданию «систем-инвалидов», не способных к полной функциональной адаптации с другими системами, пользователем и окружающей средой.

Исходными данными для формирования дерева функций являются основные и дополнительные функции системы.

Формирование дерева функций представляет процесс декомпозиции целевой функции и множества основных и дополнительных функций на более элементарные функции, реализуемые на последующих уровнях декомпозиции.

При этом каждая из функций конкретно взятого i-ого уровня может рассматриваться как макрофункция по отношению к реализующим ее функциям на (i+1)-го уровня, и как элементарная функция по отношению к соответствующей функции верхнего (i-1)-го уровня.

Описание функций системы с использованием IDEF0-нотации основано на тех же принципах декомпозиции, но представляется не в виде дерева, а набора диаграмм.

Краткое описание методологии IDEF0

Объектами моделирования являются системы.

Описание IDEF0 модели построено в виде иерархической пирамиды, в вершине которой представляется самое общее описание системы, а основание представляет собой множество более детальных описаний.

IDEF0 методология построена на следующих принципах:

  • Графическое описание моделируемых процессов. Графический язык Блоков и Дуг IDEF0 Диаграмм отображает операции или функции в виде Блоков, а взаимодействие между входами/выходами операций, входящими в Блок или выходящими из него, Дугами.
  • Лаконичность. За счет использования графического языка описания процессов достигается с одной стороны точность описания, а с другой — краткость.

Необходимость соблюдения правил и точность передачи информации. При IDEF0 моделировании необходимо придерживаться следующих правил:

  • На Диаграмме должно быть не менее 3-х и не более 6-и функциональных Блоков.
  • Диаграммы должны отображать информацию, не выходящую за рамки контекста, определенного целью и точкой зрения.
  • Диаграммы должны иметь связанный интерфейс, когда номера Блоков, Дуги и ICOM коды имеют единую структуру.
  • Уникальность имен функций Блоков и наименований Дуг.
  • Четкое определение роли данных и разделение входов и управлений.
  • Замечания для Дуг и имена функций Блоков должны быть краткими и лаконичными.
  • Для каждого функционального Блока необходима как минимум одна управляющая Дуга.
  • Модель всегда строится с определенной целью и с позиций конкретной точки зрения.

В процессе моделирования очень важным является четко определить направление разработки модели — ее контекст, точку зрения и цель.

Контекст модели очерчивает границы моделируемой системы и описывает ее взаимосвязи с внешней средой.

Точка зрения определяет позицию автора, т.е. что будет рассматриваться и под каким углом зрения.

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

Цель отражает причину создания модели и определяет ее назначение. При этом, все взаимодействия в модели рассматриваются именно с точки зрения достижения поставленной цели.

В рамках методологии IDEF0 модель системы описывается при помощи Графических IDEF0 Диаграмм и уточняется за счет использования FEO, Текстовых и Диаграмм Глоссария. При этом модель включает в себя серию взаимосвязанных Диаграмм, разделяющих сложную систему на составные части. Диаграммы более высокого уровня (А-0, А0) — являются наиболее общим описанием системы, представленным в виде отдельных Блоков. Декомпозиция этих Блоков позволяет достигать требуемого уровня детализации описания системы.

Разработка IDEF0 Диаграмм начинается с построения самого верхнего уровня иерархии (А-0) — одного Блока и интерфейсных Дуг, описывающих внешние связи рассматриваемой системы. Имя функции, записываемое в Блоке 0, является целевой функцией системы с принятой точки зрения и цели построения модели.

При дальнейшем моделировании Блок 0 декомпозируется на Диаграмме А0, где целевая функция уточняется с помощью нескольких Блоков, взаимодействие между которыми описывается с помощью Дуг. В свою очередь, функциональные Блоки на Диаграмме А0 могут быть также декомпозированы для более детального представления.

В результате, имена функциональных Блоков и интерфейсные Дуги, описывающие взаимодействие всех Блоков, представленных на Диаграммах, образуют иерархическую взаимосогласованную модель.

Хотя вершиной модели является Диаграмма уровня А-0, настоящей «рабочей вершиной или структурой» является Диаграмма А0, поскольку она является уточненным выражением точки зрения модели. Ее содержание показывает, что будет рассматриваться в дальнейшем, ограничивая последующие уровни в рамках цели проекта. Нижние уровни уточняют содержание функциональных Блоков, детализируя их, но, не расширяя границ модели.

Описание синтаксиса языка моделирования

Основными элементами на IDEF0 Диаграммах являются Блоки и Дуги.

Блоки служат для отображения функций (действий), выполняемых моделируемой системой. Сформулированные функции должны содержать глагольный оборот.

глагол + объект действия + [дополнение].

Например: обрабатывать деталь на станке, передать документы в отдел, разработать план-график проведения анализа, опубликовать материалы…

Дуги служат для отображения информации или материальных объектов, которые необходимы для выполнения функции или появляются в результате ее выполнения (объекты, обрабатываемые системой). Под объектами в рамках функционального моделирования могут пониматься документы, физические материалы, инструменты, станки, информация, организации и даже системы.

Место соединения дуги с блоком определяет тип интерфейса.

Управляющие выполнением функции данные входят в блок сверху, в то время как информация, которая подвергается воздействию функции, показана с левой стороны блока; результаты выхода показаны с правой стороны.

Механизм (человек или автоматизированная система), который осуществляет функцию, представляется дугой, входящей в блок снизу (см.рис.).

Типы дуг

Рис. — Типы дуг

Функциональный блок преобразует входную информацию (данные, материалы, средства, задачи, цели и др.) в выходную (что требуется получить в результате выполнения данной функции). Управление определяет, когда и как это преобразование может или должно произойти. Механизм (или исполнители) непосредственно осуществляют это преобразование.

За каждой Дугой закрепляется Замечание, которое отображает суть информации или объекта. Замечание формулируется в виде оборота существительного, отвечающего на вопрос: «Что?».

Дуги, как ограничивающие и уточняющие факторы Блока

Рис. — Дуги, как ограничивающие и уточняющие факторы Блока

Пример А0 диаграммы

Рис. — Пример А0 диаграммы

Функциональные Блоки на Диаграмме изображаются в виде прямоугольников, внутри которых записывается имя функции и номер Блок (в правом нижнем углу прямоугольника).

Блоки располагаются на Диаграмме согласно их степени важности (по мнению автора модели). При этом доминирующим является тот Блок, выполнение функции которого оказывает влияние на выполнение всех остальных функций, представленных на Диаграмме. К примеру, это может быть Блок, содержащий контролирующую или планирующую функцию, выходы которого являются управляющими для всех остальных функциональных Блоков Диаграммы.

Доминирующий Блок помещается, как правило, в верхнем левом углу листа Диаграммы, а наименее важный Блок — в правом нижнем углу. Таким образом, ступенчатость Блоков на Диаграмме отражает мнение автора о доминировании одних Блоков относительно других.

Очень важно помнить, что доминирование блоков на диаграмме не задаёт чёткой временной зависимости операций.

Стороны Блока также имеют определенное значение. К левой границе Блока присоединяются входные Дуги, к верхней — управляющие Дуги, к правой — выходные Дуги, а к нижней — Дуги механизмов.

Дуги на IDEF0 Диаграмме изображаются в виде стрелок.

При IDEF0 моделировании используются пять типов взаимосвязей между Блоками, для описания их отношений.

  • Взаимосвязь по управлению, — когда выход одного Блока влияет (является управляющей) на выполнение функции в другом Блоке.

    Взаимосвязь по управлению

    Рис. — Взаимосвязь по управлению

  • Взаимосвязь по входу, — когда выход одного Блока является входом для другого.

    Взаимосвязь по входу

    Рис. — Взаимосвязь по входу

  • Обратная связь по управлению, — когда выходы из одной функции влияют на выполнение других функций, выполнение которых в свою очередь влияет на выполнение исходной функции.

    Обратная связь по управлению

    Рис. — Обратная связь по управлению

  • Обратная связь по входу, — когда выход из одной функции является входом для другой функции, выход которой является для него входом.

    Обратная связь по входу

    Рис. — Обратная связь по входу

  • Взаимосвязь «выход-механизм», — когда выход одной функции является механизмом для другой. Иначе говоря, выходная Дуга одного Блока является Дугой механизма для другого. Такой тип связи встречается редко и относится чаще всего к подготовительным операциям.

    Взаимосвязь «выход-механизм»

    Рис. — Взаимосвязь «выход-механизм»

Поскольку содержание IDEF0 Диаграмм уточняется в ходе моделирования постепенно, Дуги на Диаграммах редко изображают один объект. Чаще всего они отображают определенный набор объектов и могут иметь множество начальных точек (источников) и определенное количество конечных точек (приемников). В ходе разработки графической Диаграммы для отражения этой особенности используют механизм разветвления/слияния Дуг. Это позволяет не только уточнить с использованием Замечаний содержание каждой ветви разветвленной Дуги (потока объектов), но и более точно описать из каких наборов объектов состоит входящая в функциональный Блок Дуга, если она получена путем слияния.

Пример

Рассмотрим немного надуманный пример системы — некоторый отдел контроля, созданный для оценки эффективности управления и функционирования библиотеки (с равным успехом, можно было бы также рассмотреть отдел финансового контроля на некотором предприятии, налогового контроля и т.п.).

Диаграмма верхнего уровня А-0, отражающая целевую функцию системы

Рис. — Диаграмма верхнего уровня А-0, отражающая целевую функцию системы

Диаграмма А0, отражающая декомпозицию целевой функции на основные функции А1, А2, А3

Рис. — Диаграмма А0, отражающая декомпозицию целевой функции на основные функции А1, А2, А3

Декомпозиция блока А1

Рис. — Декомпозиция блока А1

Декомпозиция блока А2

Рис. — Декомпозиция блока А2

Декомпозиция блока А3

Рис. — Декомпозиция блока А3

В этой статье мы поговорим о написании хорошего кода и о проблемах, с которыми мы при этом сталкиваемся. Понятный, декларативный, компонуемый и тестируемый — эти термины употребляются, когда речь заходит о написании хорошего кода. Решением проблем часто называют чистые функции. Но написание веб-приложений, в основном, связано с побочными эффектами и сложными асинхронными потоками операций, концепциями, которые по своей сути не являются чистыми. Ниже описан подход, который позволяет охватывать работу с побочными эффектами и сложными асинхронными потоками, сохраняя преимущества чистых функций.

Написание хорошего кода

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

function add(numA, numB) {
  return numA + numB
}

Полезным свойством чистых функций является то, что их легко тестировать.

test.equals(add(2, 2), 4)

Компонуемость тоже является их сильной стороной.

test.equals(multiply(add(4, 4), 2), 16)

К тому же их очень легко использовать декларативно.

const totalPoints = users
  .map(takePoints)
  .reduce(sum, 0)

Но давайте взглянем на ваше приложение. Какая его часть действительно может быть выражена чистыми функциями? Насколько часто речь идёт о преобразовании значений, которые традиционно выполняют чистые функции? Могу предположить, что большая часть вашего кода работает с побочными эффектами. Вы выполняете сетевые запросы, DOM манипуляции, используете вебсокеты, локальные хранилища, изменяете состояние приложения и так далее. Это всё описывает разработку приложения, по крайней мере в Интернете.

Побочные эффекты

Как правило, мы говорим про побочные эффекты, в подобном случае:

function getUsers() {
  return axios.get('/users')
    .then(response => ({users: response.data}))
}

Функция getUsers указывает на что-то «вне себя» — axios. Возвращаемое значение не всегда совпадает, так как это ответ сервера. Тем не менее, мы все еще можем использовать эту функцию декларативно и компоновать её во множестве различных цепочках:

doSomething()
  .then(getUsers)
  .then(doSomethingElse)

Но тестирование будет даваться нам с трудом, так как axios находится вне нашего контроля. Перепишем функцию, чтобы она принимала axios в качестве аргумента:

function getUsers(axios) {
  return axios.get('/users')
    .then(response => ({users: response.data}))
}

Теперь её легко протестировать:

const users = ['userA', 'userB']
const axiosMock = Promise.resolve({data: users})

getUsers(axiosMock).then(result => {
  assert.deepEqual(result, {users: users})
})

Но у нас будут проблемы компоновки функции в различные цепочки, так как axios должен быть явно передан на вход.

doSomething() // Должен вернуть axios
  .then(getUsers) // чтобы передать сюда
  .then(doSomethingElse)

Функции, работающие с побочными эффектами на самом деле являются проблематичными.

Популярный совет в проектах наподобие Elm, Cycle, и реализациях в redux (redux-loop): «сдвигайте побочные эффекты к краю вашего приложения». В основном это означает, что бизнес-логика вашего приложения хранится чистой. Всякий раз, когда вам необходимо произвести побочный эффект, вы должны отделить его. Проблемой этого подхода, вероятно, является то, что это не помогает улучшить читаемость. Вы не можете выразить целостно сложный поток операций. Ваше приложение будет иметь несколько несвязанных циклов, скрывающих отношения одного побочного эффекта, которое может стать причиной другого побочного эффекта и так далее. Это не имеет значения для простых приложений, потому что вы редко имеете дело с более чем одним дополнительным циклом. Но в больших приложениях, в конечном итоге, вы столкнётесь с большим количеством циклов, и вам будет трудно понять как они соотносятся друг с другом.
Позвольте мне объяснить это более подробно на примерах.

Типичный поток приложения

Допустим, у вас есть приложение. Когда оно начало работу, вы хотите получить данные о пользователе, чтобы проверить, вошёл пользователь в систему или нет. Затем вы хотите получить список заданий. Они связаны с другими пользователями. Поэтому, на основании полученного списка заданий, вам надо динамически получить информацию и о этих пользователях тоже. Что же мы будем делать чтобы описать этот поток действий в понятном, декларативном, компонуемом и тестируемом виде?

Рассмотрим на примере простой реализации, используя redux:

function loadData() {
  return (dispatch, getState) => {
    dispatch({
      type: AUTHENTICATING
    })
    axios.get('/user')
      .then((response) => {
        if (response.data) {
          dispatch({
            type: AUTHENTICATION_SUCCESS,
            user: response.data
          })
          dispatch({
            type: ASSIGNMENTS_LOADING
          })
          return axios.get('/assignments')
            .then((response) => {
              dispatch({
                type: ASSIGNMENTS_LOADED_SUCCESS,
                assignments: response.data
              })
              const missingUsers = response.data.reduce((currentMissingUsers, assignment) => {
                if (!getState().users[assigment.userId]) {
                  return currentMissingUsers.concat(assignment.userId)
                }
                return currentMissingUsers
              }, [])
              dispatch({
                type: USERS_LOADING,
                users: users
              })
              return Promise.all(
                missingUsers.map((userId) => {
                  return axios.get('/users/' + userId)
                })
              )
                .then((responses) => {
                  const users = responses.map(response => response.data)
                  dispatch({
                    type: USERS_LOADED,
                    users: users
                  })
                })
            })
            .catch((error) => {
              dispatch({
                type: ASSIGNMENTS_LOADED_ERROR,
                error: error.response.data
              })
            })
        } else {
          dispatch({
            type: AUTHENTICATION_ERROR
          })
        }
      })
      .catch(() => {
        dispatch({
          type: LOAD_DATA_ERROR
        })  
      })
  }
}

Здесь просто всё неправильно. Этот код непонятен, недекларативен, некомпонуем и нетестируем. Однако есть одно преимущество. Всё что происходит при вызове функции loadData определено так как оно выполняется, упорядоченно и в одном файле.

Если мы отделим побочные эффекты «на край приложения», это будет выглядеть больше как демонстрация некоторых частей потока:

function loadData() {
  return (dispatch, getState) => {
    dispatch({
      type: AUTHENTICATING_LOAD_DATA
    })
  }
}

function loadDataAuthenticated() {
  return (dispatch, getState) {
    axios.get('/user')
      .then((response) => {
        if (response.data) {
          dispatch({
            type: AUTHENTICATION_SUCCESS,
            user: response.data
          })
        } else {
          dispatch({
            type: AUTHENTICATION_ERROR
          })
        }
      })
  }
}

function getAssignments() {
  return (dispatch, getState) {
    dispatch({
      type: ASSIGNMENTS_LOADING
    })
    axios.get('/assignments')
      .then((response) => {
        dispatch({
          type: ASSIGNMENTS_LOADED_SUCCESS,
          assignments: response.data
        })
      })
      .catch((error) => {
        dispatch({
          type: ASSIGNMENTS_LOADED_ERROR,
          error: error.response.data
        })
      })
  }
}

Каждая часть читается лучше, чем в предыдущем примере. И их легче компоновать в другие цепочки. Однако, проблемой становится разрозненность. Трудно понять, как эти части связаны друг с другом, потому что вы не можете видеть какие функции приводят к вызову другой функции. Перемещаясь между файлами, мы вынуждены воссоздавать в своей голове как отправка (dispatch) одного действия (action) порождает побочный эффект, который вызывает отправку нового действия, порождающего другой побочный эффект, который, в свою очередь, снова приводит к отправке нового действия.

Вынося побочные эффекты к краю вашего приложения, вы действительно получаете преимущества. Но это также оказывает негативное влияние: становится сложнее рассуждать о потоке. Об этом, конечно, можно и даже нужно поспорить. Надеюсь, я смог донести свою точку зрения через примеры и рассуждения выше.

На пути к декларативности

Представим, что мы можем описать этот поток следующим образом:

[
  dispatch(AUTHENTICATING),
  authenticateUser, {
    error: [
      dispatch(AUTHENTICATED_ERROR)
    ],
    success: [
      dispatch(AUTHENTICATED_SUCCESS),
      dispatch(ASSIGNMENTS_LOADING),
      getAssignments, {
        error: [
          dispatch(ASSIGNMENTS_LOADED_ERROR)
        ],
        success: [
          dispatch(ASSIGNMENTS_LOADED_SUCCESS),
          dispatch(MISSING_USERS_LOADING),
          getMissingUsers, {
            error: [
              dispatch(MISSING_USERS_LOADED_ERROR)
            ],
            success: [
              dispatch(MISSING_USERS_LOADED_SUCCESS)
            ]
          }
        ]
      }
    ]
  }
]

Обратите внимание на то, что это валидный код, который мы сейчас разберём более подробно. А также, что мы не используем здесь какие-либо магические API, это просто массивы, объекты и функции. Но самое главное, мы в полной мере воспользовались декларативной формой записи кода, чтобы создать согласованное и читаемое описание сложного потока приложения.

Function Tree

Мы только что определили (задекларировали) дерево функции (function tree). Как я уже упоминал, мы не использовали никаких специальных API чтобы определить его. Это всего лишь функции определённые в дереве…, в дереве функции. Любая из функций, используемых здесь, а также фабрики функций (dispatch) могут быть повторно использованы в любом другом определении дерева. Это показывает простоту композиции. Не только каждая функция может состоять в других деревьях. Вы можете включать целые деревья в другие деревья, что делает их особенно интересными с точки зрения композиции.

[
  dispatch(AUTHENTICATING),
  authenticateUser, {
    error: [
      dispatch(AUTHENTICATED_ERROR)
    ],
    success: [
      dispatch(AUTHENTICATED_SUCCESS),
      ...getAssignments
    ]
  }
]

В этом примере мы создали новое дерево getAssignments, которое также является массивом. Мы можем компоновать одни деревья в другие, используя оператор разворачивания (spread operator).

Давайте посмотрим как работают деревья функций, прежде чем перейти к тестируемости. Давайте его запустим!

Выполнение дерева функций

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

import FunctionTree from 'function-tree'

const execute = new FunctionTree()

function foo() {}

execute([
  foo
])

Созданный экземпляр FunctionTree является функцией, которая позволяет вам выполнять деревья. В приведенном выше примере будет выполнена функция foo. Если мы добавим больше функций, они будут выполнены по порядку:

function foo() {
  // Сначала я
}

function bar() {
  // Потом я
}

execute([
  foo,
  bar
])

Асинхронность

function-tree умеет работать с обещаниями (promises). Когда функция возвращает обещание, или вы определяете функцию как асинхронную, используя ключевое слово async, функция исполнения (execute) дождётся пока обещание не будет выполнено (resolve) или отклонено (reject) прежде чем двигаться дальше.

function foo() {
  return new Promise(resolve => {
    setTimeout(resolve, 1000)
  })
}

function bar() {
  // Я запущусь через 1 секунду
}

execute([
  foo,
  bar
])

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

Контекст

Все функции выполняемые с помощью function-tree принимают один аргумент. context — это единственный аргумент с которым должны работать функции определённые в дереве. По умолчанию контекст имеет два свойства: input и path.

Свойство input содержит полезную нагрузку (payload), переданную при запуске дерева.

// Мы используем деструктурирование аргумента
function foo({input}) {
  input.foo // "bar"
}

execute([
  foo
], {
  foo: 'bar'
})

Когда функция хочет передать новую полезную нагрузку вниз по дереву ей нужно будет возвращать объект, который будет объединен с текущей полезной нагрузкой.

function foo({input}) {
  input.foo // "bar"
  return {
    foo2: 'bar2'
  }
}

function bar({input}) {
  input.foo // "bar"
  input.foo2 // "bar2"
}

execute([
  foo,
  bar
], {
  foo: 'bar'
})

Не имеет значения, синхронная функция или асинхронная, надо просто вернуть объект или выполненное обещание с объектом.

// Синхронный
function foo() {
  return {
    foo: 'bar'
  }
}

// Асинхронный
function foo() {
  return new Promise(resolve => {
    resolve({
      foo: 'bar'
    })
  })
}

Перейдём к изучению механизма выбора путей для выполнения.

Пути

Результат, возвращаемый из функции, может определить дальнейший путь выполнения в дереве. Благодаря статическому анализу, свойство path контекста уже знает по каким путям возможно продолжение выполнения. Это означает, что доступны только пути выполнения, которые определены в дереве.

function foo({path}) {
  return path.pathA()
}

function bar() {
  // Я сработаю
}

execute([
  foo, {
    pathA: [
      bar
    ],
    pathB: []  
  }
])

Вы можете передать полезную нагрузку, передавая объект к методу пути.

function foo({path}) {
  return path.pathA({foo: 'foo'})
}

function bar({input}) {
  console.log(input.foo) // 'foo'
}

execute([
  foo, {
    pathA: [
      bar
    ],
    pathB: []  
  }
])

Чем же хорош механизм путей? Прежде всего, он носит декларативный характер. Здесь нет выражений if или switch. Это повышает удобочитаемость.

Гораздо важнее то, что пути не имееют дела с «выбрасыванием» (throw) ошибок. Часто потоки мыслятся как: «сделай это или бросай всё, если произойдёт ошибка». Но не в случае с веб-приложениями. Есть много причин, почему вы решите пойти вниз по различным путям выполнения. Решение может быть основано на роли пользователя, возвращаемом ответе сервера, некотором состоянии приложения, переданном значении и так далее. Дело в том, что function-tree не отлавливает ошибки, не делает всплытия ошибок и тому подобных техник. Оно просто выполняет функции и позволяет им возвращать пути там, где исполнение должно расходиться.

Есть ещё несколько небольших скрытых особенностей. Например, вы можете определить дерево функции без реализации чего-либо. Это означает, что все возможные пути выполнения определены заранее. Это заставляет вас думать о том, какие случаи надо обработать. И значительно снижает вероятность, что вы проигнорируете или забудете о сценариях, которые могут произойти.

Провайдеры

На одних только input и path сложное приложение не построить. Поэтому function-tree построен на концепции провайдеров. На самом деле input и path тоже провайдеры. В комплекте c function-tree поставляется несколько готовых. И конечно же вы можете сами их создавать. Предположим вы хотите использовать Redux:

import FunctionTree from 'function-tree'
import ReduxProvider from 'function-tree/providers/Redux'
import store from './store'

const execute = new FunctionTree([
  ReduxProvider(store)
])

export default execute

Теперь у вас есть доступ к методам dispatch и getState в ваших функциях:

function doSomething({dispatch, getState}) {
  dispatch({
    type: SOME_CONSTANT
  })
  getState() // {}
}

Вы можете добавить любые другие инструменты используя ContextProvider:

import FunctionTree from 'function-tree'
import ReduxProvider from 'function-tree/providers/Redux'
import ContextProvider from 'function-tree/providers/Context'
import axios from 'axios'
import store from './store'

const execute = new FunctionTree([
  ReduxProvider(store),
  ContextProvider({
    axios
  })
])

export default execute

Скорее всего вы захотите использовать DebuggerProvider. В сочетании с расширением для Google Chrome вы сможете отлаживать вашу текущую работу. Добавим провайдер отладчика к примеру выше:

import FunctionTree from 'function-tree'
import DebuggerProvider from 'function-tree/providers/Debugger'
import ReduxProvider from 'function-tree/providers/Redux'
import ContextProvider from 'function-tree/providers/Context'
import axios from 'axios'
import store from './store'

const execute = new FunctionTree([
  DebuggerProvider(),
  ReduxProvider(store),
  ContextProvider({
    axios
  })
])

export default execute

Это позволяет видеть всё что происходит при выполнении этих деревьев в вашем приложении. Провайдер отладчика автоматически обернёт и будет отслеживать всё что вы разместите в контексте:

Chrome Extension Debugger

Если же вы решите использовать function-tree на серверной стороне, можете подключить NodeDebuggerProvider:

Node Debugger

Тестируемость

Но, скорее всего самое важное, это возможность проверки дерева функции. Как выясняется, это очень легко сделать. Чтобы протестировать отдельные функции в дереве, просто вызывайте их со специально подготовленным контекстом. Рассмотрим тестирование функции создающей побочный эффект:

function setData({window, input}) {
  window.app.data = input.result
}

const context = {
  input: {result: 'foo'},
  window: { app: {}}
}

setData(context)

test.deepEqual(context.window, {app: {data: 'foo'}})

Тестирование асинхронных функций

Многие библиотеки для тестирования позволяют вам создавать заглушки для глобальных зависимостей. Но нет причин делать это для function-tree, потому что функции используют только то, что доступно через аргумент контекста. Например, следующая функция, использующая axios для получения данных, может быть протестирована следующим образом:

function getData({axios, path}) {
  return axios.get('/data')
    .then(response => path.success({data: response.data}))
    .catch(error => path.error({error: error.response.data}))
}

const context = {
  axios: {
    get: Promise.resolve({
      data: {foo: 'bar'}
    })
  }
}

getData(context)
  .then((result) => {
    test.equal(result.path, 'success')
    test.deepEqual(result.payload, {data: {foo: 'bar'}})
  })

Тестирование всего дерева

Вот здесь становится ещё интереснее. Мы можем протестировать всё дерево точно так же, как мы тестировали функции отдельно.

Давайте представим простое дерево:

[
  getData, {
    success: [
      setData
    ],
    error: [
      setError
    ]
  }
]

Эти функции используют axios для получения данных, а затем сохраняют их в свойстве объекта window. Мы протестируем дерево, создав новую функцию выполнения с заглушками для передачи в контекст. Затем мы запускаем дерево и проверяем изменения после окончания выполнения.

const FunctionTree = require('function-tree')
const ContextProvider = require('function-tree/providers/Context')
const loadData = require('../src/trees/loadData')

const context = {
  window: {app: {}},
  axios: {
    get: Promise.resolve({data: {foo: 'bar'}})
  }
}
const execute = new FunctionTree([
  ContextProvider(context)
])

execute(loadData, () => {
  test.deepEquals(context.window, {app: {data: 'foo'}})
})

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

Фабрики

Так как дерево является функциональным, вы можете создавать фабрики, которые будут ускорять вашу разработку. Вы уже видели использование фабрики dispatch в примере с Redux. Она была объявлена следующим образом:

function dispatchFactory(type) {
  function dispatchFunction({input, dispatch}) {
    dispatch({
      type,
      payload: input
    })
  }
  // Свойство `displayName` переопределяет имя функции,
  // для отображения в отладчике.
  dispatchFunction.displayName = `dispatch - ${type}`

  return dispatchFunction
}

export default dispatchFactory

Создавайте фабрики для вашего приложения, чтобы избегать создания специфичных функций для всего. Предположим вы решите использовать baobab, единое дерево состояния, для хранения состояния вашего приложения.

function setFactory(path, value) {
  function set({baobab}) {
    baobab.set(path.split('.'), value)
  }

  return set
}

export default set

Эта фабрика позволит вам выражать изменения состояния прямо в дереве:

[
  set('foo', 'bar'),
  set('admin.isLoading', true)
]

Вы можете использовать фабрики, чтобы построить собственный DSL вашего приложения. Некоторые фабрики на столько обобщённые, что мы решили сделать их частью function-tree.

debounce

Фабрика debounce позволяет придержать выполнение на указанное время. Если срабатывают новые исполнения одного и того же дерева, существующее будет уходить по пути discarded. Если за указанное время нет новых срабатываний, последнее пойдёт по пути accepted. Обычно такой поход используется при поиске по мере ввода.

import debounce from 'function-tree/factories/debounce'

export default [
  updateSearchQuery,
  debounce(500), {
    accepted: [
      getData, {
        success: [
          setData,
        ],
        error: [
          setError
        ]
      }
    ],
    discarded: []
  }
]

В чём отличие от Rxjs и цепочек обещаний?

И Rxjs, и Обещания управляют контролем исполнения. Но ни один из них не имеет декларативного условного определения путей исполнения. Вам придётся разносить потоки, писать выражения if и switch или выбрасывать ошибки. В выше приведённых примерах мы смогли разделить пути исполнения success и error также декларативно, как наши функции. Это улучшает читаемость. Но эти пути могут быть абсолютно любыми. Например:

[
  withUserRole, {
    admin: [],
    superuser: [],
    user: []
  }
]

Пути не имеют ничего общего с обработкой ошибок. function-tree позволяет вам выбрать путь на любом шаге исполнения, в отличие от обещаний и Rxjs, где бросание ошибок единственный способ прекратить исполнение текущего пути.

Rxjs и обещания основаны на преобразовании значений. Это значит, что следующей функции доступны только значения переданные как результат выполнения предыдущей. Это отлично работает, когда вам действительно надо преобразовывать значения. Но события в вашем приложении это не тот случай. Они работают с побочными эффектами и проходят по одному или многим путям исполнения. В этом и заключается главное отличие function-tree.

Где можно применять?

function-tree может помочь, если вы создаёте приложение работающее с побочными эффектами в сложных асинхронных цепочках. Преимущества «принудительного» разбиения логики вашего приложения на блоки «lego» и их тестируемости могут быть достаточно весомыми доводами. В основном это позволяет вам писать более читаемый и поддерживаемый код.

Проект доступен в репозитории на Github, а расширение отладчик для Google Chrome может быть найдено в Chrome Web Store. Обязательно посмотрите пример приложения в репозитории.

Первоисточником проекта function-tree можно считать cerebral. Вы можете считать реализацию сигналов в Cerebral абстракцией с собственным представлением над function-tree. В настоящее время Cerebral использует свою собственную реализацию, но в Cerebral 2.0 function-tree будет использоваться в качестве основы для фабрики сигналов. Выражаю благодарность Алексею Guria за переработку и оттачивание идей сигналов Cerebral, что привело к созданию самостоятельного и общего подхода.

Расскажите что вы думаете о данном подходе в комментариях ниже. Поделитесь, если у вас есть ссылки на другие шаблоны и методы решения проблем, обсуждаемых в этой статье. Спасибо за прочтение!

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти обращение в стим поддержку
  • Как найти площадь прямоугольника если ширина неизвестна
  • Как найти денежный поток по проекту
  • Как найти дело на сайте московского суда
  • Как найти высококвалифицированных специалистов

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии