De acordo com sua defini¸c˜ao inicial, o padr˜ao de projetos Proxy tem por objetivo principal: “Prover um substituto ou ponto atrav´es do qual um objeto possa controlar o acesso a outro” [Gamma et al., 1994]. Em muitos casos este padr˜ao de projetos ´e utilizado principalmente quando ´e necess´ario que haja uma comunica¸c˜ao remota entre duas m´aquinas que estejam utilizando um mesmo sistema. A utiliza¸c˜ao deste padr˜ao tem por finalidade
Figura 4.18: Execu¸c˜ao do exemplo para o padr˜ao Flyweight em ooErlang. principal a de facilitar o controle de acesso entre determinados objetos de um sistema.
Semelhante a outros padr˜oes de projeto, o padr˜ao Proxy pode ser utilizado em diferentes situa¸c˜oes, mas em todas elas, existem uma ou mais classes que funcionam como sendo um ponto de acesso para determinado objeto. Os principais tipos de objetos “Proxy” s˜ao: Proxy remoto, utilizado para controlar acesso a um objeto remoto, ou seja, localizado em outra m´aquina, Proxy virtual, que tem por objetivo criar e acessar objetos complexos de forma simplificada e Proxy de prote¸c˜ao, cuja finalidade ´e controlar o acesso a um objeto original, geralmente possuidor de diferentes direitos de acesso.
4.8.1
Exemplo utilizado para este padr˜ao
Para demonstrar a utiliza¸c˜ao do padr˜ao Proxy, ´e utilizado um exemplo retirado de [Bo- oks, 2013], no qual ´e implementado um sistema que simula o carregamento de arquivos de imagem para visualiza¸c˜ao do usu´ario. Nesse sistema, s˜ao instanciados objetos para receber as imagens a serem carregadas e, dessa forma, o usu´ario poder visualiz´a-las.
Logicamente, considerando que a implementa¸c˜ao deste exemplo ´e apenas uma simu- la¸c˜ao da utiliza¸c˜ao do padr˜ao Proxy, n˜ao s˜ao utilizadas imagens reais, apenas cadeias de
Padrão Proxy 108
caracteres para funcionarem como se fossem imagens carregadas no sistema. A figura 4.19 mostra, com mais detalhes, um diagrama de classes da implementa¸c˜ao deste exemplo, para melhor entendimento.
Figura 4.19: Diagrama de classes do exemplo para o padr˜ao Proxy.
4.8.2
Compara¸c˜ao das implementa¸c˜oes em Java e ooErlang
Conforme pode ser visto pelo diagrama mostrado em 4.19, ´e implementada uma simples interface chamada Image, com a assinatura de um m´etodo que tem por responsabilidade mostrar uma imagem para o usu´ario ser capaz de visualizar. Este m´etodo ´e implementado por duas classes, RealImage e ProxyImage. Ambas as classes devem possuir a implemen- ta¸c˜ao deste m´etodo, j´a que estendem esta interface. Os c´odigos mostrados em 4.8.1 e 4.8.2 apresentam as implementa¸c˜oes da classe RealImage em Java e ooErlang, nesta ordem.
Levando-se em considera¸c˜ao que este exemplo ´e de um sistema visualizador de imagens que utiliza o padr˜ao de projetos Proxy, percebe-se que, cada objeto que representa uma imagem deve ser instˆancia de uma classe de imagens, neste caso, RealImage. Esta classe representa o objeto imagem propriamente dito. ´E o objeto que passa a ter seu acesso intermediado pela classe “Proxy”, que neste exemplo ´e a classe ProxyImage.
1 class RealImage implements Image { 2
3 private String filename = null; 4
5 public RealImage(final String FILENAME) { 6 filename = FILENAME;
7 loadImageFromDisk(); 8 }
9
10 private void loadImageFromDisk() {
11 System.out.println("Loading " + filename); 12 }
13
14 public void displayImage() {
15 System.out.println("Displaying " + filename); 16 }
17 }
C´odigo 4.8.1: Classe RealImage em Java
1 -class(realImage). 2 -implements(image).
3 -export([new/1, load_image_from_disk/0, display_image/0]). 4 -constructor([new/1]). 5 6 attributes. 7 8 Filename. 9 10 methods. 11 12 new(Filename) -> 13 self::Filename = Filename, 14 load_image_from_disk(). 15 16 load_image_from_disk() -> 17 io:format("Loading ~p~n",[self::Filename]). 18 19 display_image() -> 20 io:format("Displaying ~p~n", [self::Filename]).
C´odigo 4.8.2: Classe RealImage em ooErlang
A classe RealImage possui como atributo o nome da imagem que cada instˆancia desta classe deve possuir. Al´em disso, a classe possui um construtor e outros dois m´etodos. Um deles tem por objetivo simular o carregamento da imagem no disco r´ıgido do computador (loadImageFromDisk()) e o outro ´e especificamente o m´etodo respons´avel por mostrar a imagem ao usu´ario (displayImage()). Os c´odigos mostrados em 4.8.3 e 4.8.4 mostram a
Padrão Proxy 110
implementa¸c˜ao em Java e ooErlang da classe ProxyImage.
1 class ProxyImage implements Image { 2
3 private RealImage image = null; 4 private String filename = null; 5
6 public ProxyImage(final String FILENAME) { 7 filename = FILENAME;
8 } 9
10 public void displayImage() { 11 if (image == null) {
12 image = new RealImage(filename); 13 }
14 image.displayImage(); 15 }
16 }
C´odigo 4.8.3: Classe ProxyImage em Java
1 -class(proxyImage). 2 -implements(image). 3 -export([new/1, display_image/0]). 4 -constructor([new/1]). 5 6 attributes. 7 8 Image; 9 Filename. 10 11 methods. 12 13 new(Filename) -> 14 self::Filename = Filename. 15 16 display_image() -> 17 Temp = self::Image, 18 if 19 (Temp == []) -> 20 self::Image = realImage::new(self::Filename); 21 true -> 22 io:format("") 23 end, 24 Temp2 = self::Image, 25 Temp2::display_image().
C´odigo 4.8.4: Classe ProxyImage em ooErlang
A classe ProxyImage, conforme est´a especificado na utiliza¸c˜ao do padr˜ao Proxy, controla o acesso e a utiliza¸c˜ao dos m´etodos da classe RealImage. Desta forma, sempre que uma
imagem for instanciada e posteriormente visualizada pelo usu´ario, a classe ProxyImage ´
e a intermediadora entre a classe principal e a classe real da imagem (RealImage). Isto significa dizer que as chamadas de m´etodos utilizados na classe RealImage passam primeiro pela classe ProxyImage.
A classe ProxyImage possui dois atributos principais, sendo que um deles ´e o nome do arquivo de imagem a ser instanciado e posteriormente visualizado, e o outro ´e uma instˆancia da classe RealImage. Esta classe tamb´em possui dois m´etodos, sendo eles um construtor e o m´etodo respons´avel por mostrar a imagem (displayImage()), chamados pela classe principal. Os c´odigos mostrados em 4.8.5 e 4.8.6 apresentam, respectivamente, as implementa¸c˜oes da classe principal ProxyExample.
1 class ProxyExample { 2
3 public static void main(String[] args) {
4 final Image IMAGE1 = new ProxyImage("HiRes_10MB_Photo1"); 5 final Image IMAGE2 = new ProxyImage("HiRes_10MB_Photo2"); 6
7 IMAGE1.displayImage(); // loading necessary 8 IMAGE1.displayImage(); // loading unnecessary 9 IMAGE2.displayImage(); // loading necessary 10 IMAGE2.displayImage(); // loading unnecessary 11 IMAGE1.displayImage(); // loading unnecessary 12 }
13 14 }
C´odigo 4.8.5: Classe principal ProxyExample em Java
1 -class(proxyExample). 2 -export([main/0]). 3 4 class_methods. 5 6 main() -> 7 Image1 = proxyImage::new("HiRes_10MB_Photo1"), 8 Image2 = proxyImage::new("HiRes_10MB_Photo2"), 9
10 Image1::display_image(), %%loading necessary 11 Image1::display_image(), %%loading unnecessary 12 Image2::display_image(), %%loading necessary 13 Image2::display_image(), %%loading unnecessary 14 Image1::display_image(). %%loading unnecessary
Padrão Proxy 112
Nesta classe principal inicialmente s˜ao instanciados dois objetos que representam dois arquivos de imagem a terem sua visualiza¸c˜ao simulada por meio da utiliza¸c˜ao do padr˜ao Proxy. Ap´os as devidas instancia¸c˜oes, o m´etodo displayImage(), cujas classes RealImage e ProxyImage implementam, ´e utilizado seguidamente para verificar o funcionamento do simulador de visualiza¸c˜ao de imagens.
A classe ProxyImage sempre que recebe uma chamada do m´etodo displayImage(), ve- rifica se a instˆancia referente `a imagem real j´a foi criada. Em caso negativo, esta classe instancia um novo objeto da classe RealImage, passando por parˆametro o nome do arquivo correspondente `a imagem. Se o objeto referente `a imagem j´a tiver sido previamente ins- tanciado, o objeto ProxyImage apenas repassa a responsabilidade de mostrar a imagem ao objeto da classe RealImage. A execu¸c˜ao desta classe ´e mostrada em Java e ooErlang pelas figuras mostradas em 4.20 e 4.21.
Figura 4.21: Execu¸c˜ao do exemplo para o padr˜ao Proxy em ooErlang.
Na classe RealImage, sempre que um objeto novo for instanciado, antes de ele po- der ser visualizado, o mesmo dever´a ser carregado em disco. Isto ´e simulado dentro do construtor da classe RealImage. Neste construtor ´e realizada a chamada do m´etodo loa- dImageFromDisk(), sendo que, a partir da segunda chamada de visualiza¸c˜ao de imagens, este carregamento em disco n˜ao ´e mais necess´ario. Portanto, as imagens a serem testadas devem possuir apenas um carregamento antes das respectivas visualiza¸c˜oes.
Diversas s˜ao as situa¸c˜oes em que ´e poss´ıvel e at´e mesmo necess´ario utilizar o padr˜ao de projetos Proxy. Este padr˜ao de projetos ´e mais comumente utilizado em sistemas que necessitem ter acesso remoto a outra m´aquina, e manipular objetos muito complexos. E para facilitar este trabalho, ´e utilizada uma classe intermedi´aria, que faz o papel de representar de forma simplificada o objeto a ser acessado, reduzindo erros de comunica¸c˜ao na execu¸c˜ao do referido sistema.
Tratando-se deste exemplo, verificou-se outra forma de se utilizar o padr˜ao Proxy. Neste caso, o usu´ario possui um sistema visualizador de imagens, e tem por objetivo visualiz´a- las da forma mais eficiente possivel. Por´em, sempre que uma imagem ´e visualizada, ela deve primeiramente ser carregada na mem´oria vol´atil do computador. Utilizando-se deste
Conclusões dos Padrões de Projeto Estruturais em ooErlang 114
padr˜ao, implementou-se um objeto intermedi´ario para tratar das visualiza¸c˜oes, assim como o usu´ario pode verificar quando uma imagem est´a sendo carregada pela primeira vez.
Algumas consequˆencias podem ser verificadas na utiliza¸c˜ao do padr˜ao Proxy. Em se tratando de sistemas com acesso remoto, uma classe Proxy remota consegue esconder o fato de que o objeto acessado reside em um diferente endere¸co eletrˆonico. Em se tratando de um Proxy virtual (caso do exemplo utilizado), ´e poss´ıvel realizar otimiza¸c˜oes na cria¸c˜ao de diversos objetos. Em rela¸c˜ao a um Proxy de prote¸c˜ao, verifica-se um melhor controle de seguran¸ca ao objeto que est´a sendo acessado por interm´edio da classe Proxy.