Skip to content

Commit

Permalink
добавление структуры
Browse files Browse the repository at this point in the history
  • Loading branch information
leobrn committed Feb 23, 2024
1 parent bb7aff3 commit 902c2ca
Show file tree
Hide file tree
Showing 39 changed files with 965 additions and 530 deletions.
8 changes: 8 additions & 0 deletions docs/extra/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Дополнительно",
"position": 3,
"link": {
"type": "generated-index",
"description": "Примеры использования паттернов в 1С"
}
}
33 changes: 33 additions & 0 deletions docs/extra/mvc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# MVC (Model-View-Controller)

## Теория
**MVC** - составной паттерн, состоящий из паттернов **Наблюдатель**, **Стратегия**, **Компоновщик**.

**Модель** использует паттерн **Наблюдатель**, чтобы наблюдатели оповещались об изменениях состояния, без формирования сильных связей.

**Контроллер** определяет стратегию для представления. **Представление** может использовать разные реализации контроллера для обеспечения разного поведения.

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

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

---
## Применимость в 1С

**Модель (Model)** - это объекты метаданных (документы, справочники и т.д.), а также бизнес-логика работы с данными (модули объектов метаданных, обработки, общие модули).

**Представление (View)** - это интерфейсные формы отвечающие за отображение данных пользователю.

**Контроллер (Controller)** - обычно это модуль формы, который связывает модель и представление. Контроллер получает входные данные с формы, передает их в модель для обработки, получает результаты и передает их в представление для вывода.

Применение **MVC** в 1С позволяет:

- Отделить интерфейс от бизнес-логики
- Изменять представление данных без изменения модели
- Повторно использовать модель в разных частях системы с разными представлениями.

## Примеры
- [(Статья) Шаблон MVC для управляемого интерфейса](https://infostart.ru/1c/articles/791341/)
- [(Статья) Программирование интерфейсов в 1С или паттерн MVC для 1С](https://infostart.ru/1c/articles/155589/)
- [(Видео) Кружок 1С #4. Использование паттерна MVC в 1С](https://youtu.be/060qtsBQyHw?si=DaKwEW7L6HkrX21a)
- [(Видео) Вебинар "Паттерн проектирования MVC для 1С"](https://youtu.be/N5ci6ZSlq5k?si=Vrx2Xz7N7bZIq9eF)
136 changes: 136 additions & 0 deletions docs/extra/principle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# SOLID

Принципы SOLID это важные принципы объектно-ориентированного программирования, которые применимы и к разработке в 1С.

## S (Single Responsibility)
Принцип единственной ответственности. Каждый метод должен нести ответственность только за одну вещь. Например, процедура не должна выполнять и вычисления, и запись в регистры, и форматирование данных.

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

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

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

## O (Open/Closed)

Принцип открытости/закрытости. Модули должны быть открыты для расширения, но закрыты для изменения. Например, в 1С это реализуется через общие модули с постфиксом **Переопределяемые** или **Локализация**.

## L (Liskov Substitution)

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

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

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

## I (Interface Segregation)

Принцип разделения интерфейса:
- Функциональность следует разделять на отдельные модули, а не объединять всё в один большой модуль.
- Также не стоит загромождать интерфейсы модулей методами, которые не нужны. Лучше разделить на несколько интерфейсов по областям.

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

## D (Dependency Inversion)

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

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

# Основные принципы

## Программируйте на уровне интерфейсов
Представим, что мы разрабатываем в 1С подсистему для отправки электронной почты.
Можно было бы напрямую обращаться к классам поставщиков:

// Плохо
Почта = ПочтовыйСервисYandex();
Почта.ВвестиАдресатов(Контрагенты);
Почта.ВвестиТекстПисьма(ТекстПисьма);
Почта.ОтправитьПисьмо();

Почта = ПочтовыйСервисMail();
Почта.ЗадатьПолучателей(Контрагенты);
Почта.ЗадатьТекст(ТекстПисьма);
Почта.Отправить();

Но так мы "зашьемся" на конкретном поставщике и его методах. Гораздо лучше ввести универсальный интерфейс:

// Хорошо
Почта = ПочтовыйСервис.Создать(Поставщик);
Почта.УстановитьПолучателей(Контрагенты);
Почта.УстановитьТекст(ТекстПисьма);
Почта.Отправить();

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

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

// Плохо
Процедура НапечататьДокумент(Док)

Документ = Док; // сильная связанность

Если ТипЗнч(Док) = Тип("ДокументСчетФактура") Тогда
// печатаем счет-фактуру
ИначеЕсли ТипЗнч(Док) = Тип("ДокументСкладскаяНакладная") Тогда
// печатаем накладную
И Так Далее...

КонецПроцедуры

Это плохо - процедура сильно зависит от конкретных типов документов. Лучше использовать интерфейс:

Процедура НапечататьДокумент(ДокОбъект)

ДокОбъект.Напечатать();

КонецПроцедуры

// а типы документов реализуют интерфейс
Процедура Напечатать() Экспорт

// печать текущего документа

КонецПроцедуры

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

Проблема в том, что редактирование старого рабочего кода чревато ошибками. Поэтому лучше сделать код расширяемым:

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

Тогда новый код можно добавлять безопасно, не изменяя старый. Это в разы снижает риски поломки системы при расширении функционала.
## Принцип одной обязанности
Функция или процедура должна выполнять только одну задачу. Например, плохим решением будет процедура, которая формирует отчет, отправляет его по email и еще распечатывает на принтере.

// Плохо
Процедура СформироватьОтчет()
Отчет.Сформировать();
ОтправкаПоЭлектроннойПочте(Отчет);
УправлениеПечатью
КонецПроцедуры
// Хорошо
Функция СформироватьОтчет()
Отчет.Сформировать();
КонецФункции

Процедура ОтправитьОтчет(Отчет)
ОтправкаПоЭлектроннойПочте(Отчет);
КонецПроцедуры

Процедура РаспечататьОтчет(Отчет)
УправлениеПечатью(Отчет);
КонецПроцедуры
Loading

0 comments on commit 902c2ca

Please sign in to comment.