Singleton

Boa noite Galera…

Alguém poderia me mostrar como ficaria essa classe no Padrão de projetos SINGLETON? Li bastante na Net, mas ainda sim preciso de um empurrão para entender melhor!!

O código é o seguinte…

public class Util {
public boolean dataValida(String d) {
// código para validar a data.
}
public boolean cpfValido() {
// código para validar a data.
}
public boolean cnpjValido() {
// código para validar a data.
}
public String desenvolvidoPor() {
return "Kelvis" // este método deve retornar o nome do responsável.
}
}

Agradeço desde já galera!!

[code]
public class Util {
//Variável única da classe útil
private static Util instance = new Util();

//Método de acesso
public static Util getInstance() {
return instance;
}

//Construtor privado
private Util {}

//Resto da classe
public boolean dataValida(String d) {
// código para validar a data.
}
public boolean cpfValido() {
// código para validar a data.
}
public boolean cnpjValido() {
// código para validar a data.
}
public String desenvolvidoPor() {
return “Kelvis” // este método deve retornar o nome do responsável.
}
} [/code]

[quote=ViniGodoy][code]
public class Util {
//Variável única da classe útil
private static Util instance = null;

//Método de acesso
public Util getInstance() {
return instance;
}

//Construtor privado
private Util {}

//Resto da classe
public boolean dataValida(String d) {
// código para validar a data.
}
public boolean cpfValido() {
// código para validar a data.
}
public boolean cnpjValido() {
// código para validar a data.
}
public String desenvolvidoPor() {
return “Kelvis” // este método deve retornar o nome do responsável.
}
} [/code]
[/quote]
Me desculpe te corrigir, mas é apenas um acréscimo…

[code]
public class Util {
//Variável única da classe útil
private static Util instance = new Util();

//Método de acesso
//Nesse caso o synchronized serve para ambientes onde existe concorrência e o static é para que você possa conseguir a instancia sem o uso do “new”
public static synchronized Util getInstance() {
if (instance == null)
instance = new Util();
return instance;
}

//Construtor privado
private Util {}

//Resto da classe
public boolean dataValida(String d) {
// código para validar a data.
}
public boolean cpfValido() {
// código para validar a data.
}
public boolean cnpjValido() {
// código para validar a data.
}
public String desenvolvidoPor() {
return “Kelvis” // este método deve retornar o nome do responsável.
}
} [/code]

Espero ter ajudado (Vini: mais uma vez desculpe não quis ofende-lo).

Galera… Muito obrigado… Agora entendi perfeitamente como funciona esse Pattern!!

Qualquer coisa posto novamente ai…

Abraços!!

Ok, então é melhor explicar o seu acréscimo, e porque não deixei o método sincronizado.

Você tem duas opções ao fazer um singleton:

a) Inicializar diretamente a variável instance, como eu fiz ali. Nesse caso, a inicialização é garantida pela VM e não há necessidade do método getInstance() ser syncronized, já que duas threads nunca irão solicitar a construção da instância ao mesmo tempo. Por outro lado, sem lazy loading a sua classe singleton será criada assim que a classe for carregada pela VM, não quando for usada pela primeira vez (entretanto, normalmente a VM só carrega a classe quando for usada pela primeira vez).

b) Usar lazy loading. Só uma correção no código do colega (copy&paste tem disso, heheh), o atributo instance deverá ser inicializado com null (lauden, usei meus “superpoderes” de moderador e já corrigi ali em cima). No caso do lazy loading, é o método getInstance() que chama o new, desde que a instância ainda não tenha sido criada. Por outro lado, agora é necessário garantir thread safety, já que duas threads podem chamar esse método ao mesmo tempo e, numa condição de concorrência, duas instâncias poderiam ser criadas, quebrando o padrão e gerando um erro realmente estranho. Por isso, no caso de lazy loading, use o método getInstance() sincronizado.

Eu geralmente prefiro a primeira forma. O código fica mais simples, a sincronização é garantida, e pouquíssimas vezes ela acaba inicializando o singleton antes do primeiro uso. A segunda, deixe reservado para classes que realmente ocupam muita memória, ou que serão pré-inicializadas pela VM de alguma forma.

Veja também as desvantagens do padrão singleton, e entenda-as antes de usa-lo:
a) O padrão não funciona com multiplos class-loaders. Isso é especialmente problemático em aplicações web, já que os servidores de aplicação efetivamente usam múltiplos classloaders;
b) O singleton nunca é destruído. Uma vez criado, ele ocupa memória para sempre. Muito cuidado se o seu singleton permitir a adição de listeners, ou contiver listas de outros objetos. Tudo que o singleton referenciar também não será destruído. É muito comum que singletons (e variáveis estáticas no geral) estiquem seus tentáculos e gerem memory leaks difíceis de corrigir.
c) Geralmente existem outros padrões melhores: caches, registry, fábricas, etc. Afinal, o singleton deveria ser usado quando você quer uma única instância na aplicação toda, não quando você quer deixar uma classe globalmente acessível, ou referencia-la de maneira prática. Esses dois últimos efeitos são só efeitos colaterais, não devem ser a motivação.

[quote=ViniGodoy][code]

//Método de acesso
public Util getInstance() {
return instance;
}
} [/code]
[/quote]

public static Util getInstance() {

[quote=pmlm][quote=ViniGodoy][code]

//Método de acesso
public Util getInstance() {
return instance;
}
} [/code]
[/quote]

public static Util getInstance() {[/quote]

Bem observado, vou corrigir os posts.

[quote=ViniGodoy][quote=pmlm][quote=ViniGodoy][code]

//Método de acesso
public Util getInstance() {
return instance;
}
} [/code]
[/quote]

public static Util getInstance() {[/quote]

Bem observado, vou corrigir os posts.[/quote]

Não achei que causaria irritação, e sim faltou o static e o synchronized como eu disse é para ambientes onde o mesmo objeto será acessado por mais de uma thread.

Da minha parte, não causou nenhuma irritação. :wink:

Galera… Pintou uma outra questão aqui…

E se eu quiser criar três instâncias diferentes pra minha classe Util que é um Singleton? se não posso dar new no treco como é que fica?

Bom teoricamente nao haveria necessidade de vc ter 3 instancias dessa classe, só se ele fosse um bean…
Mas caso contrario cria um metodo que retorna uma instancia da classe…
Mas sinceramente nao vejo o pq disso

Se você precisa de 3 instâncias, então não é singleton. De qualquer forma, você poderia incluir um parâmetro no método getInstance, que receberia um número e retornaria a instância adequada.

A idéia do padrão singleton é manter uma instância única, por isso a proibição do new. Se liberar o new, pode ser que criem não só 3, mas diversas instâncias da sua classe.

Só pra entenderem o porque disso, é que estou no último semestre da Facul e tenho a matéria de Desenvolvimento baseado em componentes saca, daí o professor disse que tem como e quer porque quer que agente descubra uma forma… já me liguei que não tem utilidade, mas já que o camarada quer… rs

Tem uma forma sim, usando outro pattern que não o Singleton…rsss.