Pool de Objetos


Na empresa onde trabalho, desenvolvemos alguns objetos que são muito custosos durante a sua criação. São checagens, a nível de segurança e também a dados dentro de um determinado banco de dados. Quando inciamos a fase de testes, notamos que o construtor e alguns trabalhos que fazemos durante os métodos e propriedades estava levando muito tempo para serem executados e, na maioria das vezes, eles fazem sempre as mesmas validações.

Para contornar a situação, optamos por implementar uma espécie de pool de objetos. Depois de muito ler e efetuarmos testes, chegamos a uma forma que, até então, parece-me trabalhar bem. Essa técnica trata-se da criação de um membro privado estático, do tipo Stack<T> que será o responsável por armazenar os objetos dentro do pool. Logo depois da criação, via construtor, o objeto é automaticamente adicionado a Stack. Como não poderia deixar de ser, mais dois métodos estáticos forem criados: um para extrair o objeto do pool e outro para finalizar o pool, caso não precisar mais dele na aplicação. Além disso, optamos também por criar uma propriedade que irá determinar se aquele objeto deve ou não ser armazenado no pool ou se deve ser descartado diretamente.

public class Order
{
    private static Stack<Order> _orderPool = new Stack<Order>();

    public Order()
    {
        _orderPool.Push(this);
    }

    public static Order GetOrderFromPool()
    {
        return _orderPool.Pop();
    }

    public static void ClosePool()
    {
        _orderPool = null;
    }

    protected virtual bool CanBePooled
    {
        get
        {
            return true;
        }
    }

    ~Order()
    {
        if (_orderPool != null && this.CanBePooled)
        {
            GC.ReRegisterForFinalize(this);
            _orderPool.Push(this);
        }
    }
}

O único código que merece um comentário adicional é com relação ao destrutor da classe Order. Dentro dele verificamos se o pool não está nulo (isso quer dizer que a aplicação não precisa mais dele) e, além disso, a propriedade CanBePooled deve estar definida como True, o que indica que o objeto pode ser adicionado ao pool. Se essas condições forem atendidas, chamamos o método ReRegisterForFinalize da classe GC, passando a instancia corrente da classe para que o mesma seja ressucitada e, como podemos notar, a instancia é devolvida para o pool via método Push. Thanks JeffreyR 😉

Publicidade

2 comentários sobre “Pool de Objetos

  1. E o estado do objeto amigo?
    Porque quando você armazena a instância nesse pool, na verdade é uma referência para um objeto que você pode muito bem modificar o seu estado; posteriormente, quando for recuperar esse objeto, ele irá vir com um estado diferente do esperado. E ai?

    Isso na realidade é um "Singleton mais elegante" e complicado.

    A idéia é muito boa, inclusive já havia pensado nisso em um projeto para um dispositivo móvel. Mas existem esses problemas citados acima.

    Diga-me se você se deparou com esses mesmos problemas; por favor.
    Até mais, obrigado 🙂

  2. Boas Symon,

    Sim, o estado do objeto é algo que você precisa se preocupar. Mas lembre-se que você opta por guardar um objeto no pool, quando quer manter alguns valores (pertinentes ao estado do objeto) que são custosos para serem criados a todo momento (instância).

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s