Forwarding
Este artigo não cita fontes confiáveis. (dezembro de 2020) |
Na programação orientada a objetos, encaminhamento significa que o uso de um membro de um objeto (uma propriedade ou um método ) em um objeto diferente: seu uso é encaminhado para outro objeto. O encaminhamento é usado em vários padrões de design, onde alguns membros são encaminhados para outro objeto, enquanto outros são manipulados pelo objeto usado diretamente. O objeto de encaminhamento é freqüentemente chamado de objeto de recebimento e os membros de encaminhamento explícito são chamados de funções de envio .
Delegação
O encaminhamento costuma ser confundido com delegação formalmente, são conceitos complementares. Nos dois casos, existem dois objetos, e o primeiro objeto (o que recebeu, o receptor) usa o segundo objeto (o que foi recebido, o recebido), por exemplo, para chamar um método. Eles diferem no que self refere ao objeto receptor (formalmente, no ambiente de avaliação do método no objeto receptor): na delegação refere-se ao objeto remetente, enquanto no encaminhamento refere-se ao objeto receptor. Observe que self é frequentemente usado implicitamente como parte do envio dinâmico (resolução do método: a qual função um nome de método se refere).
A diferença entre encaminhamento e delegação é a ligação do parâmetro self no o recebido quando chamado pelo receptor. Com a delegação, o parâmetro self é vinculado ao receptor, enquanto o encaminhamento é vinculado ao o recebido. ... O encaminhamento é uma forma de reenvio automático de mensagens; delegação é uma forma de herança com ligação do pai (superclasse) no tempo de execução, em vez de no tempo de compilação / link como na herança 'normal'.
Por exemplo, dado o seguinte código:
// Sender
void n() {
print("n1");
}
// Receiver
void m() {
print("m2, ");
n();
}
void n() {
print("n2");
}
sob delegação, isso tera como saída m2, n1, porque n() é avaliado no contexto do objeto original, enquanto que no encaminhamento, isso produzirá m2, n2, porque n() é avaliado no contexto do objeto de recebimento.
No uso casual, o encaminhamento costuma ser chamado de "delegação" ou considerado uma forma de delegação, mas em uso cuidadoso, eles são claramente diferenciados pelo que self refere. Embora a delegação seja análoga à herança, permitindo a reutilização comportamental (e concretamente a reutilização de código ) sem alterar o contexto da avaliação, o encaminhamento é análogo à composição, pois a execução depende apenas do objeto de recebimento (membro), e não do objeto de envio (original). Nos dois casos, a reutilização é dinâmica, ou seja, determinada em tempo de execução (com base no objeto ao qual o uso é delegado ou encaminhado), em vez de estática, significando determinada em tempo de compilação / link (com base na classe da qual é herdada). Como herança, a delegação permite que o objeto de envio modifique o comportamento original, mas é suscetível a problemas análogos à frágil classe base ; enquanto o encaminhamento fornece um encapsulamento mais forte e evita esses problemas; veja composição sobre herança .
Exemplos
Um exemplo simples de forwarding em Java: uma instância de B encaminha chamadas para o foo método de sua a campo:
class B {
A a;
T foo()
{ return a.foo(); }
}
Observe que, ao executar a.foo(), o objeto this (default) é a (um subtipo de A ), não o objeto original (uma instância de B ). Além disso, a precisa não ser uma instancia de A : pode ser uma instancia de um subtipo(através do casting). De fato, A nem precisa ser uma classe: pode ser uma interface / protocolo .
Contraste com herança, em que foo é definido em uma superclasse A (o qual deve ser uma classe, não uma interface), e quando chamado em um exemplo de uma subclasse B, que usa o código definido em A, mas o objeto this ainda é uma instância de B :
class A {
T frente() { /* ... */ };
}
class B extends A {
}
Neste exemplo Python, classe B para a frente o frente método e a propriedade x para o objeto durante o campo a: usando estes em b (um exemplo de B ) é o mesmo como usá-los no b.a (o exemplo de A para o qual estes são encaminhado).
class A(object):
def __init__(self, x) -> None:
self.x = x
def foo(self):
print(self.x)
class B(object):
def __init__(self, a) -> None:
self.a = a
def foo(self):
self.a.foo()
@property
def x(self):
return self.a.x
@x.setter
def x(self, x):
self.a.x = x
@x.deleter
def x(self):
del self.a.x
a = A(42)
b = B(a)
b.foo() # Prints '42'.
b.x # Has value '42'
b.x = 17 # b.a.x now has value 17
del b.x # Deletes b.a.x.
Caso simples
Neste exemplo de Java, a classe Printer possui um método de impressão. Esse método de impressão, em vez de executar a impressão em si, encaminha para um objeto da classe RealPrinter. Para o mundo exterior, parece que o objeto Impressora está fazendo a impressão, mas o objeto RealPrinter é o que está realmente fazendo o trabalho.
classe tem uma
método. Esse método de impressão, em vez de executar a impressão em si, encaminha para um objeto da classe. Para o mundo exterior, parece que a objeto está fazendo a impressão, mas o objeto é o que realmente está fazendo o trabalho.
Encaminhamento é simplesmente passar um dever para alguém / outra coisa. Aqui está um exemplo simples:
class RealPrinter { // the "receiver"
void print() {
System.out.println("Hello world!");
}
}
class Printer { // the "sender"
RealPrinter p = new RealPrinter(); // create the receiver
void print() {
p.print(); // calls the receiver
}
}
public class Main {
public static void main(String[] arguments) {
// to the outside world it looks like Printer actually prints.
Printer printer = new Printer();
printer.print();
}
}
Caso Complexo
O caso mais complexo é um Padrão Decorator que, usando interfaces, o encaminhamento pode ser mais flexível e seguro . "Flexibilidade" aqui significa que
não precisa se referir a ou de qualquer maneira, como a mudança de encaminhamento é abstraída de. Neste exemplo, classe pode encaminhar para qualquer classe que implemente uma interface. Classe possui um método para alternar para outro encaminhador. Incluindo as cláusulas aprimoram a segurança de tipo, porque cada classe deve implementar os métodos na interface. A principal desvantagem é mais código.
interface I {
void f();
void g();
}
class A implements I {
public void f() { System.out.println("A: doing f()"); }
public void g() { System.out.println("A: doing g()"); }
}
class B implements I {
public void f() { System.out.println("B: doing f()"); }
public void g() { System.out.println("B: doing g()"); }
}
// changing the implementing object in run-time (normally done in compile time)
class C implements I {
I i = null;
// forwarding
public C(I i){ setI(i); }
public void f() { i.f(); }
public void g() { i.g(); }
// normal attributes
public void setI(I i) { this.i = i; }
}
public class Main {
public static void main(String[] arguments) {
C c = new C(new A());
c.f(); // output: A: doing f()
c.g(); // output: A: doing g()
c.setI(new B());
c.f(); // output: B: doing f()
c.g(); // output: B: doing g()
}
}
Aplicações
O encaminhamento é usado em muitos padrões de design. O encaminhamento é usado diretamente em vários padrões:
- Padrão
- Padrão: o objeto decorador adiciona seus próprios membros, encaminhando outros para o objeto decorado.
- Padrão: o objeto proxy encaminha o uso do membro para o objeto real.
O encaminhamento pode ser usado em outros padrões, mas geralmente o uso é modificado; por exemplo, uma chamada de método em um objeto resulta em vários métodos diferentes sendo chamados em outro:
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.