Padrão de design C# Flyweight

Resumo : neste tutorial, você aprenderá como usar o padrão flyweight C# para reduzir o uso de memória compartilhando dados entre objetos semelhantes.

Introdução ao padrão C# Flyweight

O padrão Flyweight é um padrão de design estrutural que visa reduzir o uso de memória compartilhando dados entre objetos semelhantes.

Neste padrão, você cria um conjunto de objetos leves para representar dados comuns compartilhados entre vários objetos. Esses objetos leves também são chamados de flyweights, que contêm apenas os dados exclusivos de cada objeto.

Na prática, você usa o padrão Flyweight quando precisa criar um grande número de objetos, mas cada objeto possui apenas uma pequena quantidade de dados exclusivos. Ao usar o padrão Flyweight, você pode reduzir significativamente o uso de memória do aplicativo.

Um exemplo prático de uso do padrão Flyweight é em um aplicativo editor de rich text onde é necessário gerenciar um grande número de objetos de caracteres que representam o texto. Neste aplicativo, cada objeto de personagem possui fonte, tamanho e cor, que são iguais para todos os caracteres do mesmo estilo.

Para gerenciar flyweights, você pode criar um conjunto de flyweights para representar os dados comuns (fonte, tamanho e cor) compartilhados entre vários caracteres. Cada objeto de caractere contém uma referência ao objeto flyweight correspondente, em vez de duplicar os mesmos dados.

Por exemplo, imagine que você deseja criar um documento que contenha muito texto com diferentes estilos, tamanhos e cores de fonte. Em vez de criar um novo objeto para cada personagem, você pode criar um objeto flyweight para cada combinação de estilo e tamanho e, em seguida, atribuir uma referência a esse objeto flyweight para cada objeto de personagem que compartilha essa combinação de estilo e tamanho.

Ao fazer isso, você pode reduzir significativamente o uso de memória do aplicativo rich text. Porque o aplicativo não cria muitos objetos duplicados para as mesmas combinações de estilo e tamanho.

Além disso, o padrão flyweight pode melhorar o desempenho do aplicativo porque pode reduzir o tempo de criação e inicialização de muitos objetos.

Este diagrama UML ilustra como o padrão flyweight:

c# padrão peso mosca

Exemplo de padrão Flyweight em C#

O programa a seguir demonstra como implementar o padrão de design Flyweight em C#:

namespace FlyweightPattern;

// Flyweight interface
public interface ICharacter
{
    void Display();
}

// Concrete flyweight class
public class Character : ICharacter
{
    private readonly char _symbol;
    private readonly int _size;
    private readonly string _font;

    public Character(char symbol, int size, string font)
    {
        _symbol = symbol;
        _size = size;
        _font = font;
    }

    public void Display()
    {
        Console.WriteLine($"Symbol: {_symbol}, Size: {_size}, Font: {_font}");
    }
}

// Flyweight factory class
public class CharacterFactory
{
    private readonly Dictionary<string, ICharacter> _characters = new();

    public ICharacter GetCharacter(char symbol, int size, string font)
    {
        var key = symbol.ToString() + size.ToString() + font;

        if (!_characters.ContainsKey(key))
        {
            _characters.Add(key, new Character(symbol, size, font));
        }

        return _characters[key];
    }
}

// Client code
public class Client
{
    static void Main(string[] args)
    {
        var factory = new CharacterFactory();

        var char1 = factory.GetCharacter('A', 12, "Arial");
        char1.Display();

        var char2 = factory.GetCharacter('B', 14, "Times New Roman");
        char2.Display();

        var char3 = factory.GetCharacter('A', 12, "Arial");
        char3.Display();

    }
}Linguagem de código:  C#  ( cs )

Como funciona.

Primeiro, defina a ICharacterinterface que possui um método Display() que mostra um caractere para o console:

public interface ICharacter
{
    void Display();
}Linguagem de código:  C#  ( cs )

Segundo, defina a Characterclasse que implementa a ICharacterinterface:

public class Character : ICharacter
{
    private readonly char _symbol;
    private readonly int _size;
    private readonly string _font;

    public Character(char symbol, int size, string font)
    {
        _symbol = symbol;
        _size = size;
        _font = font;
    }

    public void Display()
    {
        Console.WriteLine($"Symbol: {_symbol}, Size: {_size}, Font: {_font}");
    }
}Linguagem de código:  C#  ( cs )

A Characterclasse possui três propriedades: símbolo, tamanho e fonte. Ele também implementa o Display()método que mostra essas propriedades ao console.

Terceiro, defina a CharacterFactoryclasse responsável por gerenciar a criação e compartilhamento de objetos flyweight:

public class CharacterFactory
{
    private readonly Dictionary<string, ICharacter> _characters = new();

    public ICharacter GetCharacter(char symbol, int size, string font)
    {
        var key = symbol.ToString() + size.ToString() + font;

        if (!_characters.ContainsKey(key))
        {
            _characters.Add(key, new Character(symbol, size, font));
        }

        return _characters[key];
    }
}Linguagem de código:  C#  ( cs )

Por fim, defina a Clientclasse que utiliza o CharacterFactorypara obter objetos flyweight para diferentes caracteres com diferentes tamanhos e fontes:

public class Client
{
    static void Main(string[] args)
    {
        var factory = new CharacterFactory();

        var char1 = factory.GetCharacter('A', 12, "Arial");
        char1.Display();

        var char2 = factory.GetCharacter('B', 14, "Times New Roman");
        char2.Display();

        // use the flyweight instead of creating new object
        var char3 = factory.GetCharacter('A', 12, "Arial"); 
        char3.Display();

    }
}
Linguagem de código:  JavaScript  ( javascript )

Observe que ao solicitar um objeto flyweight, o CharacterFactoryprimeiro verifica se já existe um objeto com a mesma chave (símbolo, tamanho e fonte) em seu dicionário interno.

Se o objeto não existir, CharacterFactorycria um novo Characterobjeto e o adiciona ao dicionário. Caso contrário, CharacterFactoryretorna o objeto existente.

Ao executar o programa, você deverá ver a saída exibindo o símbolo, o tamanho e a fonte de cada objeto de caractere.

Como o terceiro objeto de caractere é uma duplicata do primeiro, retorna CharacterFactoryo objeto existente em vez de criar um novo.

Resumo

  • Use o padrão flyweight C# para reduzir o uso de memória compartilhando dados entre objetos semelhantes.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *