Modo de agente do padrão de design java (7)

Não perca a paciência à vontade.Na vida, é impossível para uma pessoa fazer amizade com todos que conhece. Um verdadeiro amigo não pode ser forçado, e Deus não estipula quem deve ser amigo de quem. Tudo deve ser relutante em fazer. Tudo na vida pode ser relutante. Apenas o "amor" não pode ser relutante, e a amizade é o mesmo.

Aprendizagem de padrões de design, vou postar no blog sobre 23 padrões de design em um futuro próximo , fique ligado ~
—9/01/2021

definição

Fornece um proxy para outros objetos para controlar o acesso a este objeto. Em alguns casos, um objeto não é adequado ou não pode se referir diretamente a outro objeto, e o objeto proxy pode desempenhar um papel intermediário entre o cliente e o objeto de destino.

Enciclopédia Baidu

Classificação de papéis

  • Função abstrata: Um método de negócios implementado por uma interface ou classe abstrata que declara uma função real.
  • Função do agente: realiza a função abstrata, que é o agente da função real.O método abstrato é realizado através do método da lógica de negócios da função real, e você pode anexar suas próprias operações.
  • Função real: implementar funções abstratas, definir a lógica de negócios a ser implementada por funções reais, para funções de agente chamarem

análise

Suponha que eu queira alugar uma casa, devo primeiro ir a uma agência para ver a casa e, em seguida, escolher uma casa adequada para alugar;

De onde veio a casa? Deve ser o senhorio, certo?

Aqui, o locador é uma pessoa que precisa de um corretor, e o corretor é a casa, então deixe o corretor ser um corretor, deixe o corretor nos ajudar a alugar.

beneficiar:

  • O locador não mudou nada, mas a casa é representada pelo corretor, e o corretor nos aluga a casa após a compra da casa, e cobra uma taxa de corretor, etc.

UML类图(1.1):


análise:

  • O verdadeiro papel do HouseMaster refere-se ao senhorio aqui
  • A função abstrata IHouse refere-se à casa aqui
  • A função do agente HouseProxy aqui se refere ao intermediário

Implementação de proxy estático:

IHouse (casa):

public interface IHouse {
    
    
    void showHouse();
}

HouseMaster (Host):

public class HouseMaster implements IHouse {
    
    

    @Override
    public void showHouse() {
    
    
        Log.i("代理模式:", "我是房东,我要出租房");
    }
}

HouseProxy (intermediário):

public class HouseProxy {
    
    

    IHouse house;
    //吧房子交给中介 (吧IHouse 接口组合到 HouseProxy 上)
    public HouseProxy( IHouse house) {
    
    
        this.house = house;
    }

    public void showHouse(){
    
    
        house.showHouse();//房东的房子
    }

}

Use o código:

//创建代理类 传入需要代理的类
HouseProxy houseProxy = new HouseProxy(new HouseMaster());

houseProxy.showHouse();

Log图(2.1):


Talvez todo mundo ainda esteja fascinado pelo modelo de agência, vou explicar em detalhes

Agora, só usamos HouseProxy (intermediário) para ver a casa do senhorio A, ele também pode fazer outras operações, por exemplo, podemos deixá-lo nos levar para ver outras casas, e também podemos dar uma gorjeta ao corretor:

Classe HouseProxy (intermediário):

public class HouseProxy {
    
    

    IHouse house;
    public HouseProxy( IHouse house) {
    
    
        this.house = house;
    }

    public void showHouse(){
    
    
        money();//收取消费
        house.showHouse();//房东的房子
        seeHouse();//带用户看房
    }
    public void money(){
    
    
        Log.i("代理模式:","我是中介,我要收取消费");
    }
    public void seeHouse(){
    
    
        Log.i("代理模式:","我是中介,我带用户看房");
    }
}

Log图(2.2):


房东并没有发生变化,变化的只是中介
比如说在项目中,一个类用到了很多地方现在让这个这个类前面输出一句话,
咋们是不是就可以不在改变原有代码的基础上来达到这句话的显示呢?

Resumo do modo de proxy estático:

vantagem:

  • Sem alteração do código original, atendendo ao princípio de abertura e fechamento (fechado para modificação)
  • O código público é entregue à classe agente para realizar a divisão do trabalho
  • Não se preocupe com outros assuntos que não sejam de sua responsabilidade e conclua uma transação concluída por meio do agente posterior.O resultado incidental é que a programação é simples e clara.

Desvantagens:

  • Uma classe precisa criar uma classe de proxy, a quantidade de código dobrará e a eficiência de desenvolvimento será reduzida

Modo proxy dinâmico

Proxy dinâmico significa: a classe do proxy pode mudar com a mudança do proxy.

Simplificando, eu quero que A seja representado por proxy, apenas um proxy, quero que B seja representado por B, sem criar muitas classes de proxy

Funções:

  • Manipulador de chamadas InvocationHandler
  • Proxy

O que é InvocationHandler?

JDK1.8CHW图(3.1):


JDK1.8CHW download Código de extração: lfoz

InvocationHandler é uma interface implementada pelo manipulador de invocação da instância do proxy .


InvocationHandler é uma interface que precisa ser reescrita para
invocar o método (proxy de objeto, método de método, args de objeto [])

Explicação do método de invocação:

  • Parâmetro um (proxy de objeto): a instância de proxy que chama o método
  • Parâmetro dois (método do método): A classe declarada do objeto do método será a interface declarada pelo método, e pode ser a superinterface da classe de proxy que herda a interface de proxy do método. (Não importa se você não entende aqui)
  • Parâmetro três (Object [] args): A matriz de objetos que contém a chamada do método, passando os valores dos parâmetros da instância do proxy, ou nulo se o método de interface não tiver parâmetros. Parâmetros de tipos primitivos estão contidos em instâncias de classes de wrapper primitivas apropriadas, como java.lang.Integer ou java.lang.Boolean.

Esta é a explicação em jdk: não importa se a explicação do método aqui não é clara.

JDK1.8CHW图(3.2):

O que é proxy?

JDK1.8CHW图(3.3):


O proxy fornece métodos estáticos para a criação de classes e instâncias de proxy dinâmico e também é a superclasse de todas as classes de proxy dinâmico criadas por esses métodos. (Palavras oficiais)

Meu entendimento: Proxy é obter uma instância do proxy

Você definitivamente não quer ler tantas palavras. Simplificando: Proxy trabalha com InvocationHandler para completar a geração automática de classes de proxy.

Se você obtiver a instância do proxy:

Proxy.newProxyInstance(
		ClassLoader loader,
        Class<?>[] interfaces,
        InvocationHandler h);

Análise do parâmetro Proxy.newProxyInstance:

  • Parâmetro 1: a localização da classe carregada
  • Parâmetro dois: interface de proxy
  • Parâmetro 3: representar a si mesmo: InvocationHandler

Código:

ProxyInvocationHandler 类:

public class ProxyInvocationHandler implements InvocationHandler {
    
    

    Object object;

    //参数一:object 具体接口的实现类
    public ProxyInvocationHandler(Object object) {
    
    
        this.object = object;
    }

    //生成代理类  返回的是被代理的接口 (返回的是object接口)
    public Object getProxy(){
    
    
        /**
         * this.getClass().getClassLoader() 加载类所在位置
         * object.getClass().getInterfaces() 代理的接口
         * this  表示本身:InvocationHandler
         */
       return Proxy.newProxyInstance(
			       this.getClass().getClassLoader(),
			       object.getClass().getInterfaces(),
			       this
	     	 );
    }

    /**
     * @param proxy 调用该方法的代理实例
     * @param method  所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
     * @param args 包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。
     *             原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
     * @return
     * @throws Throwable
     */
    @Override  //处理代理实例,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        Object invoke = method.invoke(object, args);
        return  invoke;
    }
}

usar:

//需要代理 真实角色
HouseMaster houseMaster = new HouseMaster();

//代理类生成器  传入需要代理的类
ProxyInvocationHandler pit =
			 new ProxyInvocationHandler(houseMaster);

//生成代理类 (必须返回接口)
IHouse proxy = (IHouse) pit.getProxy();

//输出租房子
proxy.showHouse();

Log图(2.3):


HouseMaster (classe proxy) gera automaticamente o IHouse (interface) correspondente por meio do mecanismo de reflexão da classe ProxyInvocationHandler (manipulador de chamadas)

Nota:


Use o mecanismo de reflexão de InvocationHandler para obter o método atualmente chamado:

public class ProxyInvocationHandler implements InvocationHandler {
    
    

	.....
	
    @Override  //处理代理实例,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        msg(method.getName());
        Object invoke = method.invoke(object, args);
        return  invoke;
    }

    public void msg(String msg){
    
    
        Log.i("代理模式","代理了"+ msg +"方法");
    }
}

流程图(4.1):


Aqui está o nome do método showHouse () obtido

Log图(2.4):

Agora, este ProxyInvocationHandler é uma classe de proxy pública, passada em uma classe que precisa de um proxy e, em seguida, um objeto da classe de proxy pode ser retornado por meio de getProxy () (desde que a classe de proxy passada implemente a classe de proxy retornada)

vantagem:

  • Sem alteração do código original, atendendo ao princípio de abertura e fechamento (fechado para modificação)
  • O código público é entregue à classe agente para realizar a divisão do trabalho
  • O agente proxy dinâmico é uma interface, geralmente um negócio correspondente
  • Um proxy dinâmico pode fazer proxy de várias interfaces, desde que implemente a mesma interface. Em comparação com o proxy estático, cada classe de proxy precisa criar uma classe de proxy, que é mais flexível

Se você realmente não entende este artigo, você pode usá-lo, porque o código dinâmico é relativamente fixo!

Apenas saiba que cada classe desempenha um papel correspondente e será usada.

  • Manipulador de chamadas ProxyInvocationHandler (usado para gerar classes proxy automaticamente)

  • O verdadeiro papel do HouseMaster (precisa ser representado (este artigo se refere ao locador que aluga a casa))

  • Função abstrata IHouse (aqui se refere à casa)

  • pit.getProxy () retorna a função abstrata (aqui se refere a retornar para a casa)

  • proxy.showHouse (); implementação específica (referente ao aluguel de uma casa)

Projeto completo

Vá para a página inicial de Padrões de Design / Princípios de Design

Originalidade não é fácil, seus gostos são o seu maior apoio para mim, por favor, gostem de me apoiar ~

Acho que você gosta

Origin blog.csdn.net/weixin_44819566/article/details/112390541
Recomendado
Clasificación