Bridge, Adapter e Proxy: Três padrões essenciais para o design de sistemas flexíveis

Padrão Bridge

O que é o padrão Bridge?

O padrão Bridge é um padrão de design estrutural que tem a intenção de “desacoplar uma abstração de sua implementação, de modo que as duas possam variar independentemente”. Parece complexo? Vamos simplificar: imagine que você tem um controle remoto de TV. A forma como o controle funciona é a abstração, e a marca ou modelo do controle é a implementação. Com o padrão Bridge, você pode alterar a forma como o controle funciona ou mudar a marca ou modelo sem que um interfira no outro.

Quando usar o padrão Bridge?

Recomendo a utilização do padrão Bridge quando você quer evitar um vínculo permanente entre a abstração e a implementação. Isso pode ser útil quando a implementação deve ser selecionada ou alterada em tempo de execução.

C#
using System;

// Abstração
abstract class Abstraction
{
    protected Implementor implementor;

    public Abstraction(Implementor implementor)
    {
        this.implementor = implementor;
    }

    public abstract void Operation();
}

// Implementação
interface Implementor
{
    void OperationImp();
}

// Implementação Concreta A
class ConcreteImplementorA : Implementor
{
    public void OperationImp()
    {
        Console.WriteLine("Implementação A sendo executada.");
    }
}

// Implementação Concreta B
class ConcreteImplementorB : Implementor
{
    public void OperationImp()
    {
        Console.WriteLine("Implementação B sendo executada.");
    }
}

// Abstração Refinada
class RefinedAbstraction : Abstraction
{
    public RefinedAbstraction(Implementor implementor) : base(implementor)
    {
    }

    public override void Operation()
    {
        Console.WriteLine("Abstração sendo executada.");
        implementor.OperationImp();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Cria as implementações concretas
        Implementor implementorA = new ConcreteImplementorA();
        Implementor implementorB = new ConcreteImplementorB();

        // Cria a abstração refinada associada com a implementação A
        Abstraction abstraction = new RefinedAbstraction(implementorA);
        abstraction.Operation();

        Console.WriteLine();

        // Altera a implementação associada à abstração para a implementação B
        abstraction.implementor = implementorB;
        abstraction.Operation();

        Console.ReadLine();
    }
}

// Fonte: ChatGPT

Neste exemplo, temos a abstração Abstraction que possui uma referência para a interface Implementor. As classes ConcreteImplementorA e ConcreteImplementorB são as implementações concretas da interface Implementor. A classe RefinedAbstraction é uma abstração refinada que estende a classe Abstraction. O programa principal cria as implementações concretas, associa a abstração refinada com a implementação A, executa a operação e, em seguida, altera a implementação para B e executa novamente a operação.

Padrão Adapter

O que é o padrão Adapter?

Agora vamos falar sobre o padrão Adapter. Ele é um padrão de design estrutural que permite que duas interfaces incompatíveis trabalhem juntas. É como um tradutor entre dois idiomas incompatíveis. Em outras palavras, o padrão Adapter cria uma ponte entre duas interfaces que de outra forma não poderiam trabalhar juntas devido a suas interfaces incompatíveis.

Quando usar o padrão Adapter?

Você deve considerar o uso do padrão Adapter quando quiser usar uma classe existente que seja incompatível com o restante do seu código. Ou quando quiser criar uma classe reutilizável que coopere com classes não relacionadas ou não previstas.

C#
using System;

// Interface existente
interface ITarget
{
    void Request();
}

// Classe existente
class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Método SpecificRequest da classe Adaptee sendo chamado.");
    }
}

// Adapter
class Adapter : ITarget
{
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee)
    {
        this.adaptee = adaptee;
    }

    public void Request()
    {
        Console.WriteLine("Adapter chamando o método SpecificRequest da classe Adaptee.");
        adaptee.SpecificRequest();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Cria a instância da classe Adaptee
        Adaptee adaptee = new Adaptee();

        // Cria o Adapter e passa a instância do Adaptee
        ITarget target = new Adapter(adaptee);

        // Chama o método Request do Adapter
        target.Request();

        Console.ReadLine();
    }
}

// Fonte: ChatGPT

Neste exemplo, temos a interface ITarget que define a interface esperada pelo cliente. A classe Adaptee é a classe existente que possui uma interface incompatível com ITarget. A classe Adapter implementa a interface ITarget e atua como um adaptador entre o cliente e a classe Adaptee. No programa principal, criamos uma instância de Adaptee, criamos um Adapter passando a instância do Adaptee e chamamos o método Request do Adapter, que internamente chama o método SpecificRequest da classe Adaptee.

Padrão Proxy

O que é o padrão Proxy?

Chegamos agora ao padrão Proxy. Esse padrão de design estrutural fornece um substituto ou espaço reservado para outro objeto para controlar o acesso a ele. É como um intermediário que pode adicionar funcionalidades extras ao objeto sem mudar sua interface.

Quando usar o padrão Proxy?

O padrão Proxy é útil quando você precisa controlar o acesso a um objeto, seja para adicionar uma camada de segurança, otimizar o desempenho, entre outros.

C#
using System;

// Interface do objeto real e do proxy
interface ISubject
{
    void Request();
}

// Objeto real
class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("RealSubject: Processando a requisição.");
    }
}

// Proxy
class Proxy : ISubject
{
    private RealSubject realSubject;

    public void Request()
    {
        // Cria o objeto real sob demanda
        if (realSubject == null)
        {
            Console.WriteLine("Proxy: Criando uma instância do RealSubject.");
            realSubject = new RealSubject();
        }

        // Executa a requisição através do objeto real
        realSubject.Request();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Cria o proxy
        ISubject proxy = new Proxy();

        // Chama o método Request do proxy
        proxy.Request();

        Console.ReadLine();
    }
}

// Fonte: ChatGPT

Neste exemplo, temos a interface ISubject que define a interface tanto para o objeto real (RealSubject) quanto para o proxy (Proxy). A classe RealSubject representa o objeto real com a funcionalidade que desejamos controlar o acesso. O Proxy atua como um substituto do objeto real e controla o acesso a ele. No programa principal, criamos uma instância do Proxy e chamamos o método Request, que internamente verifica se o objeto real já foi criado ou não. Se não foi criado, o Proxy cria uma instância do RealSubject e em seguida realiza a requisição através do objeto real.

Como esses padrões ajudam no design de sistemas flexíveis

Os padrões de design Bridge, Adapter e Proxy contribuem para o desenvolvimento de sistemas flexíveis e adaptáveis. Cada um desses padrões oferece uma maneira diferente de garantir que as partes do seu sistema possam variar independentemente umas das outras.

Como esses padrões podem beneficiar o negócio

Em um contexto de negócios, a utilização desses padrões de design pode trazer vários benefícios, como maior flexibilidade, redução de custos com manutenção e evolução do sistema, além de permitir a integração com outros sistemas de forma mais fácil.

Conclusão

Para finalizar, os padrões de design são ferramentas poderosas que podem ajudar a criar sistemas mais flexíveis, de fácil manutenção e interoperáveis. Espero que este artigo tenha ajudado a esclarecer a importância dos padrões Bridge, Adapter e Proxy no design de sistemas. Lembre-se: a melhor prática é sempre aquela que melhor se adequa ao seu caso!

Esse conteúdo é parte do material disponibilizado para os participantes do meu grupo de estudos de Padrões de Projeto. Você quer participar desse grupo? Clique aqui e veja como funciona.

Dúvidas Frequentes

Qual a diferença entre os padrões Bridge, Adapter e Proxy?
A principal diferença é a finalidade de cada um deles. O padrão Bridge é usado para separar a abstração da implementação, o Adapter é utilizado para compatibilizar interfaces incompatíveis, e o Proxy controla o acesso a objetos.

Os padrões de design podem ajudar no desenvolvimento de software?
Sim, os padrões de design podem ajudar no desenvolvimento de software, tornando-o mais organizado, eficiente e fácil de manter.

Todos os sistemas precisam usar esses padrões?
Não necessariamente. O uso de padrões depende dos requisitos e complexidade do sistema.

O uso de padrões de design pode ter um impacto negativo?
Se usados incorretamente, os padrões de design podem tornar o sistema excessivamente complexo e difícil de entender. É importante usar os padrões de design de forma adequada.

Qual padrão de design devo usar?
Depende das necessidades do seu sistema. Cada padrão tem suas próprias vantagens e desvantagens, e a decisão de usar um padrão específico deve ser baseada nas necessidades específicas do seu sistema.

Quer se aprofundar neste tema?

Então participe do grupo de estudos de Padrões de Projeto.

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Participe do
grupo intensivo de

Padrões de Projeto

com

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Participe do
grupo intensivo de

Padrões de Projeto

com

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Veja outros artigos relacionados

Quer Melhorar Seu Design? Aplique CQS

Nesse mundo cada vez mais acelerado da tecnologia da informação, uma das metas constantes para desenvolvedores é a otimização e...

Você Precisa Conhecer o State Pattern

Em minha jornada como desenvolvedor de software, a descoberta e compreensão do State Pattern foi um divisor de águas, assim...

Como padrões ajudam a reduzir o impacto da escassez de recursos

Quando pensamos em software development, um dos grandes desafios é criar sistemas eficientes especialmente em ambientes com recursos limitados. Diante...

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Programa ElemarJR de Aceleração, Do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Programa ElemarJR de Aceleração, Do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Mentoria em Arquitetura de Software

Ênfase em Systems Design

Para se candidatar nesta turma aberta, preencha o formulário a seguir:

Reproduzir vídeo

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Bridge, Adapter e Proxy: Três padrões essenciais para o design de sistemas flexíveis:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Bridge, Adapter e Proxy: Três padrões essenciais para o design de sistemas flexíveis:

Bridge, Adapter e Proxy: Três padrões essenciais para o design de sistemas flexíveis

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Bridge, Adapter e Proxy: Três padrões essenciais para o design de sistemas flexíveis:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

× Precisa de ajuda?