Desmistificação do modo decorador: Integrei o ChatGPT no telemóvel com o decorador

No processo normal de desenvolvimento, geralmente encontramos a necessidade de adicionar funções adicionais a uma classe, mas não queremos destruir a estrutura original da classe. Nessa hora, o modo decorador pode mostrar seu poder! A seguir, levarei você para aprender mais sobre o princípio, vantagens e desvantagens, cenários aplicáveis ​​e como usá-lo com habilidade no desenvolvimento real. Acredito que após a leitura deste artigo, você terá um entendimento mais profundo sobre o padrão decorator.

I. Visão geral

Decorator Pattern (Padrão Decorator) é um padrão de design estrutural que permite que um objeto adicione dinamicamente responsabilidades adicionais sem modificar a estrutura de classe original. A chave para esse padrão é substituir o relacionamento de herança por um relacionamento de composição. Com base no relacionamento de composição, ele cria um objeto wrapper (decorador) para envolver o objeto original, mantém o objeto original inalterado e integra a extensão no objeto decorador . O padrão decorador é uma prática recomendada do princípio aberto-fechado.

Normalmente, para seguir o princípio de abertura e fechamento, quando estendemos a função de uma classe, não modificamos diretamente a classe original, mas integramos a função estendida na subclasse por herança. No entanto, a herança tem características estáticas e alto grau de acoplamento e, com o aumento das funções estendidas, as subclasses irão se expandir. Se não quisermos estender a classe sem adicionar muitas subclasses, podemos usar o relacionamento de composição em vez do relacionamento de herança, que pode fornecer uma expansão mais flexível do que a herança.

Além disso, o objeto decorador e o objeto original geralmente implementam a mesma interface, que tem duas vantagens. Primeiramente, o cliente não precisa distinguir entre o objeto decorador e o objeto decorado, e acessá-los de forma unificada. Em segundo lugar, a camada externa do objeto decorador pode ser coberta com outra camada de decoradores para realizar a combinação das funções dos dois decoradores, o que significa que os decoradores podem ser aninhados em várias camadas para obter combinações de funções mais complexas.
decorador02
O padrão decorador inclui principalmente os seguintes papéis:

  1. Componente abstrato (Component): interface ou classe abstrata, que define o comportamento abstrato da entidade, e os seguintes componentes concretos e decoradores devem implementar essa interface.
  2. ConcreteComponent (ConcreteComponent): Classe de entidade, classe empacotada, realiza o componente abstrato e representa o objeto a ser decorado.
  3. Decorador abstrato (Decorator): geralmente uma classe abstrata que contém uma referência a um componente abstrato e implementa um componente abstrato. Todos os decoradores concretos devem herdar deste decorador abstrato.
  4. Decorador Concreto (ConcreteDecorator): Herdado do decorador abstrato, cada nova função de extensão corresponde a um decorador concreto, e os decoradores concretos podem ser aninhados entre si.

vantagem

  • Estender dinamicamente as funções do objeto: O padrão decorador segue o princípio de abertura e fechamento, permitindo que novas funções sejam adicionadas dinamicamente aos objetos sem modificar a classe original.
  • Garanta a consistência da interface: o objeto decorador usa a mesma interface do objeto decorado, garantindo a consistência da interface e tornando as chamadas do cliente mais concisas.
  • Controle de funcionalidade refinado: O padrão decorador permite um controle refinado sobre a funcionalidade de um objeto. Você pode optar por adicionar diferentes decoradores conforme necessário para combinar combinações funcionais que atendam a necessidades específicas, sem criar uma subclasse independente para cada combinação funcional.
  • Suporte para combinação aninhada de decoradores: O padrão decorador suporta o uso aninhado de vários decoradores e os combina em uma determinada ordem para obter extensões de funções mais complexas. Por meio de combinações aninhadas, combinações funcionais que atendem a necessidades específicas podem ser construídas de forma flexível.

deficiência

  • Maior complexidade: A introdução do padrão decorator adicionará classes e objetos adicionais, aumentando a complexidade do sistema. Se o padrão decorator for usado excessivamente, pode levar a um nível de decorator muito profundo, tornando o código difícil de entender e manter.
  • Potencial impacto no desempenho: cada decorador precisa envolver o objeto decorado e adicionar funcionalidade extra a ele. Isso pode causar alguma degradação de desempenho na manipulação de objetos, especialmente quando há muitas camadas de decoradores.

Cena aplicável

  • Existe a necessidade de estender dinamicamente a funcionalidade de objetos existentes sem modificar seu código.

  • Extensões de função diferentes precisam ser fornecidas para um objeto e essas extensões de função podem ser combinadas arbitrariamente.

  • A capacidade de adicionar, remover ou modificar objetos dinamicamente em tempo de execução é necessária.

  • É necessário manter a consistência da interface para que o código cliente trate de forma transparente o objeto decorado e o objeto decorador.

  • Quando não é possível ou conveniente usar a herança para estender a funcionalidade do objeto, o padrão decorador fornece uma alternativa mais flexível.

Em segundo lugar, a realização do caso

análise de caso

Existe um fabricante de celulares que atualmente produz dois tipos de celulares, um é o celular Huawei e o outro é o celular Xiaomi. Ambos implementam a interface Phone, que define um método ican, que é usado para exibir as funções básicas de o telefone celular atual, incluindo SMS, telefone, 4G, shopping, etc. Agora precisamos expandir duas novas funções, uma é expandir a função 5G e a outra é integrar a função ChatGPT. No futuro, os telemóveis Huawei ou Xiaomi que produzimos podem integrar uma destas funções, ou podem integrar ambas as funções. Para tal cenário, é muito adequado usar o padrão decorador para alcançar.

Código

Passo 1 : Crie componentes abstratos e componentes concretos

public interface Phone {
    
    
    void ican();
}
public class HuaWeiPhone implements Phone{
    
    
    @Override
    public void ican() {
    
    
        System.out.println("huawei capacities:call,sms,4G,huaweiStore");
    }
}
public class XiaoMiPhone implements Phone{
    
    
    @Override
    public void ican() {
    
    
        System.out.println("xiaomi capacities:call,sms,4G,xiaomiStore");
    }
}

Etapa 2 : crie um decorador abstrato que precise implementar a interface Phone e agrupar o objeto Phone type dentro dela.

public abstract class PhoneDecorator implements Phone{
    
    
    protected Phone phone;

    public PhoneDecorator(Phone phone) {
    
    
        this.phone = phone;
    }
    public void ican(){
    
    
        phone.ican();
    }

}

Passo 3 : Crie um decorador específico ---- decorador 5G

public class Phone5GDecorator extends PhoneDecorator {
    
    

    public Phone5GDecorator(Phone phone) {
    
    
        super(phone);
    }

    private void add5G() {
    
    
        System.out.println("extended capacity: 5G");
    }

    @Override
    public void ican() {
    
    
        phone.ican();
        add5G();
    }
}

Passo 4 : Crie um decorador específico----Ai decorador

public class PhoneAiDecorator extends PhoneDecorator{
    
    

    public PhoneAiDecorator(Phone phone) {
    
    
        super(phone);
    }
    private void addAi() {
    
    
        System.out.println("extended capacity: chatGPT");
    }

    @Override
    public void ican() {
    
    
        phone.ican();
        addAi();
    }
}

Passo 5 : Teste do cliente

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //以华为手机为例进行功能扩展
        System.out.println("华为手机:");
        Phone huawei=new HuaWeiPhone();
        huawei.ican();
        System.out.println();

        System.out.println("华为5G手机:");
        PhoneDecorator huawei5G=new Phone5GDecorator(new HuaWeiPhone());
        huawei5G.ican();
        System.out.println();

        System.out.println("集成ChatGPT的华为5G手机:");
        PhoneDecorator huaWeiAi=new PhoneAiDecorator(huawei5G);
        huaWeiAi.ican();
    }
}

Resultado dos testes
imagem-20230531111937128

três, resumo

Este artigo apresenta o princípio e a aplicação do modo decorador em detalhes e ajuda todos a entender o modo decorador em profundidade, simulando o caso da extensão da função do telefone móvel. Este é um padrão de design muito prático, que adiciona dinamicamente novas funções à classe original por meio de composição em vez de herança. A combinação pode tornar a extensão da classe mais flexível e mutável e, ao mesmo tempo, evitar o problema de expansão da subclasse causado pela herança. Espero que todos possam descobrir e usar melhor o padrão decorador no desenvolvimento real no futuro e possam fazer inferências de uma instância para tornar seu código mais elegante.

Obrigado por ler, espero que este artigo possa ser útil para você, se você gostou deste artigo, não se esqueça de curtir e seguir!

1711edbd2bd444b1b647e09c2c3aff0d

Acho que você gosta

Origin blog.csdn.net/qq_36756227/article/details/130958887
Recomendado
Clasificación