Паттерн Singleton в Microsoft Dynamics 365 Finance & Operations
Я Антон, разработчик Axapta в Programming Store. В программировании 7 лет. Сейчас работаю с системой Microsoft Dynamics 365 Finance & Operations (MS D365 F&O). Решаю задачи от расширения стандартного функционала до разработки веб-сервисов для обмена данными.
Singleton понадобился мне со 2-го месяца работы с системой MS D365 F&O, так как принцип доработки стандартного кода в MS D365 F&O заключается в расширении стандартного кода с помощью Chain of Command или Event Handler. Это не позволяет нам дописать стандартный код в середине метода, мы можем только дописаться либо до метода, либо после. Бывает, что нам необходимо дописать код в середине метода или наоборот не выполнять часть кода, в этом может помочь Singleton. В статье приведен пример, когда Singleton впервые пригодился мне в разработке MS D365 F&O. Периодически встречаются и другие ситуации, когда он выручает. Надеюсь, что будет полезно.
Contents
Singleton
Паттерн Singleton — один из наиболее популярных и часто используемых шаблонов проектирования, который гарантирует, что класс будет иметь только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. В контексте MS D365 F&O данный паттерн может быть полезен для управления глобальными настройками, кэшированием данных или другими объектами, которые должны быть уникальными в рамках одной сессии.
Зачем нужен Singleton в MS D365 F&O?
В MS D365 F&O использование Singleton актуально для решения следующих задач:
- Оптимизация производительности: Singleton помогает избежать многократного создания однотипных объектов: конфигурации, параметры или кэшированные данные.
- Глобальные настройки. Например, если необходимо хранить данные конфигурации, которые используются во многих местах кода, такие как параметры модуля, Singleton позволяет создать и использовать эти данные без необходимости их многократного запроса из базы данных.
- Сокращение использования ресурсов. Singleton помогает снизить нагрузку на память и CPU, обеспечивая создание только одного экземпляра, что особенно полезно в высоконагруженных системах.
Реализация Singleton в X++ для MS D365 F&O
Для реализации Singleton в MS D365 F&O используется язык X++. Ниже пример, который демонстрирует, как правильно реализовать паттерн Singleton в MS D365 F&O.
Пример реализации Singleton
public class AllowZeroAmountContext implements System.IDisposable
{
static AllowZeroAmountContext allowZeroAmountContext;
public boolean allowZeroAmount;
// Создаем контекст
public void new()
{
if (allowZeroAmountContext)
{
throw Error(strFmt("Context %1 already exists!", identifierStr(AllowZeroAmountContext)));
}
allowZeroAmountContext = this;
}
// Отчищаем контекст
public void dispose()
{
allowZeroAmountContext = null;
}
// Метод для получения экземпляра Singleton
static public AllowZeroAmountContext current()
{
return allowZeroAmountContext;
}
}
Использование Singleton в коде
[ExtensionOf(classStr(LedgerTransferToJournal))]
public final class LedgerTransferToJournal_Extension
{
void insertLedgerJournalTrans(LedgerJournalTable _ledgerJournalTable, LedgerJournalTrans _ledgerJournalTrans)
{
using(AllowZeroAmountContext context = new AllowZeroAmountContext())
{
context.allowZeroAmount = true;
next insertLedgerJournalTrans(_ledgerJournalTable, _ledgerJournalTrans);
}
}
}
[ExtensionOf(tableStr(LedgerJournalTrans))]
public final class LedgerJournalTrans_Extension
{
public display Amount amount()
{
AllowZeroAmountContext context = AllowZeroAmountContext::current();
Amount amount;
;
amount = next amount();
if (!amount && context && context.allowZeroAmount)
{
amount = 1;
}
return amount;
}
}
Объяснение кода
В классе LedgerTransferToJournal есть метод insertLedgerJournalTrans, в методе есть часть кода под условием, которое не всегда выполняется, но проанализировав задачу от клиента, мы пришли к выводу, что эта часть кода должна выполняться всегда.
Как добиться этого с минимальными жертвами в условиях разработки в MS D365 F&O? Нам необходимо всегда возвращать значение не равное 0 из метода ledgerJournalNewTrans.amount() в этом участке кода, что и реализовано в расширении класса.
В классе LedgerTransferToJournal_Extension в методе insertLedgerJournalTrans мы создаем глобальный контекст, который будет существовать только в пределах using, то есть, когда мы выйдем за пределы using, контекст уже не будет существовать.
После мы расширяем метод ledgerJournalNewTrans.amount(), создаем класс LedgerJournalTrans_Extension и создаем расширение метода amount, далее получаем глобальный контекст и под условиями, если контекст не пустой, то возвращаем нужно нам значение. Теперь всегда в методе insertLedgerJournalTrans при вызове метода ledgerJournalNewTrans.amount() мы будем получать значение не равное 0.
Singleton: преимущества и недостатки
Преимущества:
- Оптимизация производительности за счет повторного использования одного и того же экземпляра
- Централизованный доступ к часто используемым данным и ресурсам
- Снижение нагрузки на систему за счет уменьшения количества создаваемых объектов
Недостатки:
- Глобальное состояние может затруднить тестирование и отладку
- Возможны проблемы с многопоточностью, если Singleton используется в сценариях параллельного выполнения.
Заключение
Паттерн Singleton — инструмент для оптимизации кода и управления ресурсами в MS D365 F&O. Особенно полезен при работе с конфигурациями, кэшированием данных и глобальными настройками системы. При его использовании важно помнить о возможных проблемах с многопоточностью и сложностями тестирования.
Используйте Singleton осознанно, и он поможет сделать ваш код более эффективным и надежным!
Comments
So empty here ... leave a comment!