Top.Mail.Ru
Full-time, 5/2
Формат: удаленный
Вакансия «1С-программист»

Паттерн 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. Периодически встречаются и другие ситуации, когда он выручает. Надеюсь, что будет полезно.

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, в методе есть часть кода под условием, которое не всегда выполняется, но проанализировав задачу от клиента, мы пришли к выводу, что эта часть кода должна выполняться всегда.

Стандартный код класса 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!

Добавить комментарий

Sidebar