• Nenhum resultado encontrado

A defini¸c˜ao deste padr˜ao pode ser escrita da seguinte forma: “Garantir que uma classe s´o tenha uma ´unica instˆancia, e prover um ponto de acesso global a ela” [Gamma et al., 1994]. Desta forma pode-se verificar que o padr˜ao de projetos Singleton ´e necess´ario e aplic´avel em situa¸c˜oes onde seja importante possuir apenas uma instˆancia de determinada classe, evitando assim erros de inconsistˆencia de dados, dependendo do sistema que estiver sendo modelado.

Pode-se ent˜ao afirmar que o padr˜ao Singleton deve ser aplicado a sistemas na situa¸c˜ao em que precise haver exatamente uma ´unica instˆancia de uma classe, sendo que esta ins- tˆancia deve ser acess´ıvel para os usu´arios por meio de um ponto de acesso bem conhecido. Outra situa¸c˜ao em que este padr˜ao pode ser utilizado ´e quando a ´unica instˆancia precisa ser estendida por subclasses, permitindo aos usu´arios utilizar a instˆancia estendida sem

Padrão Singleton 54

que seja necess´ario modificar seu c´odigo.

3.6.1

Exemplo utilizado para este padr˜ao

No exemplo utilizado para aplica¸c˜ao deste padr˜ao, retirado de [Freeman et al., 2004], foi modelado um sistema para gerenciamento de uma f´abrica que produz chocolates. A caracter´ıstica principal desta f´abrica ´e a de que existe uma e apenas uma caldeira para realizar o derretimento e o preparo do chocolate a ser produzido. Isto significa dizer que deve-se considerar as a¸c˜oes de fabrica¸c˜ao em rela¸c˜ao `a caldeira, tendo a mesma como referˆencia.

Para se inserir mat´eria prima nesta caldeira, ´e necess´ario verificar se a mesma est´a vazia. Para se retirar chocolate derretido desta caldeira, deve-se primeiramente verificar se esta caldeira possui chocolate. Ou seja, para a modelagem a ser utilizada, ´e necess´ario que exista apenas uma ´unica instˆancia da caldeira desta f´abrica, sendo que a mesma deve possuir um ´unico ponto de acesso global, evitando problemas de fabrica¸c˜ao. A figura 3.13 mostra, para melhor entendimento, um diagrama de classes desta modelagem.

Figura 3.13: Diagrama de classes do exemplo para o padr˜ao Singleton.

ler, que possui o m´etodo principal, e de onde o exemplo ´e executado, e a classe Chocolate- Boiler, respons´avel por possuir em um de seus atributos o atributo uniqueInstance. Esta ´e a ´unica instˆancia referente `a caldeira da f´abrica de chocolates explicada anteriormente.

Os m´etodos da classe ChocolateBoiler permitem ao cliente encher, esvaziar e acender a fornalha da caldeira (fill(), drain() e boil() respectivamente), al´em outros dois m´etodos respons´aveis por verificar o estado atual da caldeira, caso a mesma esteja vazia ou cheia (isEmpty() e isBoiled()). Desta forma, quando se vai encher a caldeira, deve-se verificar se a mesma j´a n˜ao est´a cheia, e vice-versa.

Verifica-se ent˜ao a necessidade de haver apenas uma ´unica instˆancia para a caldeira, assim como apenas um ponto de acesso global a este objeto. Desta forma, se dois objetos tentarem acessar a caldeira ao mesmo tempo, n˜ao v˜ao haver problemas de inconsistˆencias e de erros de execu¸c˜ao. ´E necess´ario portanto que haja um m´etodo espec´ıfico para que se obtenha o ponto de acesso global a esta caldeira, e este m´etodo est´a implementado na classe ChocolateBoiler, e chama-se getInstance().

3.6.2

Compara¸c˜ao das implementa¸c˜oes em Java e ooErlang

As classes ChocolateController e ChocolateBoiler s˜ao implementadas em Java e ooErlang de acordo com suas caracter´ısticas pr´oprias. Em Java, na classe ChocolateBoiler, o m´etodo respons´avel por retornar o ´unico ponto de acesso ´e implementado utilizando-se de um atributo est´atico, e dessa forma, sempre que seja necess´ario acessar este objeto, ´e verificado se o atributo j´a foi instanciado, criando-o em caso negativo e retornando-o em caso positivo. O c´odigo 3.6.1 mostra essa implementa¸c˜ao em Java.

Em ooErlang esta implementa¸c˜ao tamb´em foi realizada, por´em com algumas diferen¸cas. Enquanto que em Java ´e possivel utilizar-se de atributos est´aticos, em ooErlang isto n˜ao ´

e poss´ıvel. A solu¸c˜ao seguida foi a de se utilizar processos registrados. Todo objeto em ooErlang ´e um processo. A instˆancia ´unica tamb´em o ´e. Dessa forma o m´etodo para retornar o ponto de acesso verifica se o atributo da instˆancia ´unica j´a foi registrado ou n˜ao, sendo criado e registrado em caso negativo e apenas retornado em caso positivo. O c´odigo 3.6.2 mostra esta implementa¸c˜ao em ooErlang.

Padrão Singleton 56

1 public class ChocolateBoiler { 2 private boolean empty; 3 private boolean boiled;

4 private static ChocolateBoiler uniqueInstance; 5 6 private ChocolateBoiler() { 7 empty = true; 8 boiled = false; 9 } 10

11 public static ChocolateBoiler getInstance() { 12 if (uniqueInstance == null) {

13 System.out.println("Creating unique instance of 14 Chocolate Boiler");

15 uniqueInstance = new ChocolateBoiler();

16 }

17 System.out.println("Returning instance of Chocolate Boiler"); 18 return uniqueInstance;

19 }

C´odigo 3.6.1: Classe ChocolateBoiler em Java

ooErlang, esta ´e a classe principal, e seu objetivo ´e o de testar a implementa¸c˜ao verificando a execu¸c˜ao do fonte, e se cria apenas uma ´unica instˆancia com um ponto de acesso global a ela. Ent˜ao ´e utilizado o m´etodo getInstance(), s˜ao realizadas algumas opera¸c˜oes na caldeira e em seguida um outro objeto tenta ter acesso `a instˆancia, verificando se receber´a a mesma instˆancia criada anteriormente. Os c´odigos em 3.6.3 e 3.6.4 referem-se a esta classe em Java e ooErlang, respectivamente.

Ao executar o m´etodo main() de ambas as implementa¸c˜oes, verifica-se que seus resulta- dos mostram inicialmente a instancia¸c˜ao da instˆancia ´unica relativa `a caldeira da f´abrica de chocolates, utiliza¸c˜ao de alguns m´etodos e, em seguida novamente a utiliza¸c˜ao do m´etodo getInstance(), verificando se, em ambos os casos, a mesma instˆancia criada anteriormente ´e utilizada. As figuras 3.14 e 3.15 mostram o resultado da execu¸c˜ao deste exemplo em Java e ooErlang.

Observa-se, na implementa¸c˜ao do exemplo referente ao padr˜ao Singleton em ooErlang, uma diferen¸ca em rela¸c˜ao `a implementa¸c˜ao em Java. Enquanto que em Java ´e poss´ıvel criar vari´aveis est´aticas, em ooErlang isto n˜ao ´e utiliz´avel, portanto ´e necess´ario utilizar outra ferramenta bastante conhecida em Erlang que, por consequˆencia, tamb´em est´a presente em ooErlang. Trata-se da utiliza¸c˜ao de processos registrados.

1 -class(chocolateBoiler).

2 -export([new/0, get_instance/0, fill/0, drain/0, boil/0]). 3 -export([is_empty/0, is_boiled/0]). 4 -constructor([new/0]). 5 6 attributes. 7 8 Empty; 9 Boiled; 10 UniqueInstance. 11 12 methods. 13 14 get_instance() -> 15 ListOfProcesses = erlang:registered(),

16 Return = lists:member(unique_instance, ListOfProcesses), 17 if

18 (Return == false) ->

19 io:format("Creating unique instance of 20 Chocolate Boiler ~n"), 21 self::UniqueInstance = chocolateBoiler::new(), 22 erlang:register(unique_instance, ObjectID); 23 true -> 24 io:format("") 25 end,

26 io:format("Returning instance of Chocolate Boiler ~n"), 27 Unique = {chocolateBoiler, whereis(unique_instance)}, 28 Unique::UniqueInstance.

C´odigo 3.6.2: Classe ChocolateBoiler em ooErlang

1 public class ChocolateController {

2 public static void main(String args[]) {

3 ChocolateBoiler boiler = ChocolateBoiler.getInstance(); 4 boiler.fill();

5 boiler.boil(); 6 boiler.drain(); 7

8 // will return the existing instance

9 ChocolateBoiler boiler2 = ChocolateBoiler.getInstance(); 10 }

11 }

C´odigo 3.6.3: Classe principal ChocolateController em Java

se de processos registrados na cria¸c˜ao da instˆancia relativa `a caldeira. Desta forma ´e poss´ıvel obter um ponto de acesso global ´unico a esta instˆancia. Na primeira instancia¸c˜ao, ´

e realizado o registro do referente processo. Nas outras tentativas de obter a instˆancia ´

Padrão Singleton 58 1 -class(chocolateController). 2 -export([main/0]). 3 4 class_methods. 5 6 main() -> 7 Boiler = chocolateBoiler::new(), 8 Boiler::get_instance(), 9 Boiler::fill(), 10 Boiler::boil(), 11 Boiler::drain(), 12 13 Boiler2 = chocolateBoiler::new(), 14 Boiler2::get_instance().

C´odigo 3.6.4: Classe principal ChocolateController em ooErlang

Figura 3.14: Execu¸c˜ao do exemplo para o padr˜ao Singleton em Java. necess´aria. Assim consegue-se utilizar o padr˜ao Singleton em ooErlang.

Figura 3.15: Execu¸c˜ao do exemplo para o padr˜ao Singleton em ooErlang.

exemplo, acesso controlado a uma ´unica instˆancia, facilidade de refinamento de opera¸c˜oes quando a classe ´unica for herdada por subclasses, permiss˜ao na utiliza¸c˜ao de um n´umero variado de instˆancias dependendo das caracter´ısticas pr´oprias do sistema.