Dúvida sobre Factory

Nos exemplos que observei sobre este pattern, cada classe possui sua própria factory. No caso de classes que implementam uma interface (ex. DAO), é errado criar um factory genérico onde eu tenha uma estrutura de decisão (switch) para saber qual tipo de objeto eu devo produzir?
Até que ponto isto fere o pattern?

O que voce viu era uma Abstract Factory… no fundo eh tudo a mesma cosia… a diferenca basicamente eh que a factory normal eh usada para criar os objetos “diretamente” ( a propria factory cria )…

Na Abstract Factory, voce tem uma classe centralizadora, e varias classeszinhas, que implementam a factory principal, que criam os objetos do tipo correto.
Ou seja, ao inves de voce encher de if-else para decidir qual instancia criar, voce usa uma abstract factory, que delegara a responsabilidade de criacao dos objetos para as classes filhas/especializadas.

Rafael

Voce quer poder fazer algo assim:

class Factory {
  Object newInstance(Class cl);
}

Ai o usuario faria

  Object obj = factory.newInstance(Usuario.class);

Não vejo problema, só toma cuidado para o switch não ficar fora de controle…

No meu caso ao invés de vários if (ou switch) eu preferi usar reflection pra instanciar o DAO, funciona bem aqui usando Abstract Factory Factory (sim, eh uma factory pras possiveis factories e então pros DAOs :wink: )

Fica mais flexivel, é só ir adicionando DAOs e usando …

[]s

No GUJ2 eu implementei um esquema bem legalzinho de DAO Factory. Da uma olhada la :slight_smile:

cv,

dei uma olhada no dao do guj2, mais especificamente em guj/guj2/src/java/br/com/guj/dao. Vc fez da forma como o louds postou… mas qual a responsabilidade da classe DaoFactoryAware?

DaoFactoryAware é apenas uma interface de marcação pro Webwork habilitar o componente DaoFactory em uma action, no seu caso, ignore-o :wink:

Minhas classes factory implementam javax.naming.ObjectFactory por estar utilizando JNDI. Neste caso existe uma forma de utilizar essa idéia de uma factory genérica que implementa ObjectFactory?

olha a assinatura do método de ObjectFactory aí:

public Object getObjectInstance( Object obj, Name name, Context ctx, Hashtable env) throws Exception;

Hummmm , sim, claro que é possível, mas é necessário?

No meu caso precisei de uma Abstract Factory porque pros mesmos objetos eu teria 2 factories diferentes … uma gerando objetos DAO que utilizavam Hibernate (banco de dados mesmo) e outra gerando objetos DAO que utilizavam uma outra API pra acessar os dados.

Entonces nas classes que utilizam fica assim:

ObjectFactory fac = ObjectFactory.getFactory(Const.Hibernate);
UserDAO userDao = fac.getDAO(UserDAO.class);
User user = userDao.findByPk('xxxxx');

Veja que a factory criada eh uma implementação de ObjectFactory que realmente sabe quais DAOs criar (UserDAO é uma interface também), e claro existe um DAO implementado pra cada tipo de acesso aos dados.

Ajudou? Atrapalhou? diz ae …

[]s

Ajudou sim smota.
A necessidade é a questão de edição do meu server.xml. Se tivesse uma única factory produzindo os meus objetos não teria a necessidade de ficar editando o server.xml e acrescentando um novo <Resource> para cada DAOFactory.
Mas percebí que no caso de JNDI é inviável, pois preciso especificar o tipo de objeto que minha factory produz. Tudo bem, posso especificar a interface que as classes DAO produzidas implementam, mas neste caso só teria acesso aos métodos comuns da interface. Métodos específicos de cada DAO não estariam disponíveis para a instância do objeto.

Hummm não é bem assim.

A sua Factory genérica retorna um tipo genérico de DAO (a interface) , mas quem vai usar o DAO sabe qual a implementação que vai usar (pode até ser uma interface pra poder ter várias implementações reais diferentes) então pode fazer um cast e ter acesso aos métodos específicos. Não pode ser assim?

UserDao userDAO = &#40;UserDao&#41; genericFactory.getDAO&#40;UserDao.class&#41;

Na verdade a interface DAO só precisa especificar os métodos necessários na construção do DAO, o resto fica por conta de cada DAO.

Seguinte… está tendo algum mal entendido. Se eu não estiver entendendo, vc me explica pq não existe maneira de implementar isso que vc sugeriu na expecificação de recursos do container (tomcat).

Como eu já disse no outro post, pela especificação a factory deve implementar javax.naming.spi.ObjectFactory.
O método utilizado para fabricar o objeto é

public Object getObjectInstance&#40;
		Object obj,
		Name name,
		Context ctx,
		Hashtable env&#41;
		throws Exception;

segue as configurações no server.xml e deployment descriptor:
server.xml

    &lt;Resource name=&quot;dao/UserDAOFactory&quot; auth=&quot;Container&quot;
    	type=&quot;UserDAO&quot;&gt;
    &lt;/Resource&gt;
    &lt;ResourceParams name=&quot;dao/UserDAOFactory&quot;&gt;
    	&lt;parameter&gt;
    		&lt;name&gt;factory&lt;/name&gt;
    		&lt;value&gt;UserDAOFactory&lt;/value&gt;
    	&lt;/parameter&gt;
    &lt;/ResourceParams&gt;

web.xml

	&lt;resource-env-ref&gt;
	&lt;resource-env-ref-name&gt;dao/UserDAOFactory&lt;/resource-env-ref-name&gt;
 		&lt;resource-env-ref-type&gt;UserDAO&lt;/resource-env-ref-type&gt;
	&lt;/resource-env-ref&gt;

ufa!!! é isso…