Pra variar estou com um pequeno problema pra ver se vcs podem me ajudar.
É o seguinte: Tenho uma classe que precisa ser instânciada um única vez no sistema. Bem, vcs vão me dizer: “Singleton”.
Mas não é tão aplicado (pelo menos na forma que eu conheço) na minha questão.
O problema é que eu tenho uma classe “A” e desta classe herdam classes “B”,“C”,“D”… O que eu quero controlar é uma instância para cada classe dessas.
Se eu controlar a instância em cada classe fica fácil, mas vou ter que criar o mesmo código simples, repetitivo e babaca em cada classe. Tem alguma outra forma mais “economica” de se fazer isso? Digo, porque são muitas classes - mais de 100. E ficar repetindo o mesmo código pra todas elas vai ser um saco!!!
Gostaria de uma solução limpa e da forma mais correta, aplicando-se patterns mais indicados.
class pai
{
static HashSet h = new HashSet();
protected pai()
{
if(h.contains(this.getClass()))
throw new Error("instanciando mais de 1 vez essa classe!");
h.add(this.getClass();
}
}
Se fosse C++, 1 template ja resolveria esse problema…
Talvez até dê… pegue o Together Control Center, carregue todas as classes num diagrama de classes, selecione as que interessam e dê um belo “Apply Pattern/Singleton” nelas
como o Urabatan falou, um factory. melhor ainda, um factory de Singletons na classe Pai. O clasico Multiton
class Pai {
// esse aqui as subclasses podem popular no static initializer
protected static Map hashDeSubClasses = new Hashtable();
// esse aqui vai ser populado pelo getInstance a seguir
protected static Map hashDeInstanciasDeSubClasses = new Hashtable();
protected Pai() {}
public static Pai getInstance(String tipo) { // poderia ser um int de uma enum
// tira do hash o tipo, algo como
Pai instance = (Pai) hashDeInstanciasDeSubClasse.get(tipo);
if (pai == null) {
// nao foi inicializado ainda uma isntancia desse tipo
Class class = hashDeSubClasses.get(tipo);
instance = (Pai) class.newInstance(); // supondo construtor default
hashDeInstanciasDeSubClasse.put(tipo, instance);
}
return instance;
}
Acoplamento um pouco grotesto, classes filhas precisam conhecer a implementacao da pai, mas… Tambem falta ai sincronizacao e as excecoes lancadas pelo newInstance(). Uma das filhas ficaria ± assim:
class Filha1 extends Pai {
// da um "toque" pro pai, de que eu existo!!!
static {
hashDeSubClasses.put("esteTipoDeSingleton", Filha1.class);
}
//.. overrides
}
Ah, Oziel, me poupe. O problema aqui não é saber ou não fazer um singleton, o problema aqui é gerenciar uma cacetada de singletons, coisa que com certeza nenhum curso da Sun ensina :x
Oziel, realmente aqui nao eh singleton nao. Eh um factory/multiton no melhor estilo DriverManager/Connection do java.sql, ja que a filha precisa se registrar a pai (ou a composta precisa se registrar na agregadora, tanto faz), para que a pai saiba q a filha existe.
Muito diferente do singleton. com singleton mesmo, voce nem sublcasse pode ter porque seu construtor deveria ser private. O louds tambem colocou o construtor protected ai nao a toa.
Não pude deixar de perceber que alguns amigos nossos no fórum, em vez de ajudar, como em muitos casos ajudaram, apenas encaminharam uma sugestão de curso. Por que não detalhar aqui no forum como fazer tal tarefa. Fica aqui a minha indiguinação, apesar de ser iniante, acredito que o proposito deste e qualquer fórum seja a ajuda mútua e não a promoção de alguém ou algo em especial.