Как сделать доступным одноэлементный экземпляр для всей службы? - PullRequest
1 голос
/ 03 августа 2020

Вот как я реализую одноэлементный класс

import { AClient } from 'libbrary'
import { Container, Service } from 'typedi';

@Service()
class MyClass {
    private client: AClient;
    
    static getInstance(): MyClass {
        return Container.get(MyClass);
    }
    
    getClient(): AClient {
        if(this.client !== null){
            return this.client;
        }
        this.client = new AClient();
        return this.client;
    }
}

Здесь основное внимание уделяется использованию Acliet ().
И я реализую методы этого клиента следующим образом.

class AClientMethodsImplementation {
    async getSomeData() {
        // I need client here so that I can use client.get()
    }
}

Теперь я должен использовать эти методы в своем сервисе.

class NeedDataHere {
    // Not only here, in the entire project I need this many places.
    // should I create AClientMethodsImplementation() instance everytime?
    // If that is the case what is the point of a singleton?
    // How to achieve this? What is the correct approach?
}

Соблюдаю ли я подходить? Или как лучше всего справиться с этим сценарием? Я говорю, что это проблема, потому что я заметил, что нажатие getSomeData () путем создания нового класса AClientMethodsImplementation каждый раз дает тот же результат, даже если я изменяю входные данные для этой функции. Сомневаюсь, что это где-то кешируется.

1 Ответ

2 голосов
/ 03 августа 2020

Это действительно зависит от вашего сценария. Если AClientMethodsImplementation должен быть без состояния (он не будет хранить данные, связанные с экземпляром, между вызовами методов), вы должны объявить все его члены static:

class AClientMethodsImplementation {
    static async getSomeData() {
        AClient client = MyClass.getInstance().getClient();
    }
}

class NeedDataHere {
   
   // Call static methods
   let data = AClientMethodsImplementation.getSomeData();
}

Если AClientMethodsImplementation должен хранить экземпляр связанных данных, вам, конечно же, придется создать новый экземпляр (за исключением того, что конкретный метод не изменяет экземпляр. В этом случае это может быть static). Если вы хотите, чтобы этот экземпляр был одинаковым во всем приложении, вы можете реализовать AClientMethodsImplementation как Singleton.

Предпочтительной альтернативой шаблону Singleton является использование Dependency Injection (реализация Io C шаблон). Таким образом, вы можете использовать один и тот же экземпляр, но без ущерба для слабой связи и тестируемости.

Обычно вы используете общие экземпляры (через Dependency Injection или Singleton), когда хотите использовать состояние одного объекта в глобальной области, например объект сеанса как повар ie. Другой вариант использования - создание экземпляра может быть слишком дорогим из-за выделения ресурсов или из-за того, что создание экземпляра занимает слишком много времени. Затем вы выделяете ресурсы один раз, например, соединение с базой данных / сервисом, и повторно используете его (общие ресурсы). Другой вариант использования - предоставить контролируемый доступ к совместно используемому ресурсу, например к кэшу данных. Например, вы обычно используете общий экземпляр регистратора в приложении.

При проверке кода преимуществом общего экземпляра AClient может быть повышенная производительность. Если вы можете сказать, что клиент предоставляет дорогостоящие общие ресурсы или данные или, как правило, слишком дорого для создания нескольких экземпляров, то стоит поделиться экземпляром. Тот факт, что вы по-прежнему создаете несколько экземпляров AClientMethodsImplementation, не делает общий экземпляр избыточным, очевидно.

...