Arquitetura Trabalho

Bom dia.

Estou trabalhando em um novo emprego agora, e me deparei com a arquitetura já utilizada na empresa, no desenvolvimento de um pequeno portal para atender as necessidades da gerência. Neste Portal são agregado sistemas de controle de contratos e pessoal.
Essa arquitetura é composta pelos Beans de cada objeto:


public class Contrato{
	
	private int idContrato;
	
	private String nomeContrato;

	// get's e set's		
}

Pelos Java Form’s de cada Objeto:


public class ContratoForm extends ActionForm {


	private int idContrato;

	private String nomeContrato;

	
	public void reset(ActionMapping mapping, HttpServletRequest request) {
		nomeContrato = "";
	}

                // get's e set's

}

Dos action’s que tratam as ações de cada objeto:


public final class ContratoAction extends Action {

	public ActionForward editarContrato(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
       throws Exception {

                     return mapping.findForward("editar");
       }
}

De classes que chamamos de Manter que invocam os métodos declarados na Interface e ligam ao DAO (Me corrijam se estiver errado, por favor…):

public class ManterContrato {

	private IContratoDAO contratoDAO = FabricaContratoDAO.getInstancia()
			.getContratoDAO();

	public Contrato contrato(int idContrato) throws Exception {
		return contratoDAO.contrato(idContrato);
	}

	public void incluirContrato(Contrato contrato) throws Exception {
		contratoDAO.incluirContrato(contrato);
	}

                // outros métodos
}

Das Interfaces:

public interface IContratoDAO {
	public Contrato contrato(int idContrato) throws Exception;

	public void incluirContrato(Contrato contrato) throws Exception;

	// outros métodos
}

De Fábricas de Objetos:

public class FabricaContratoDAO {
	private static FabricaContratoDAO fabricaContratoDAO = new FabricaContratoDAO();

	private FabricaContratoDAO() {
		// Carrega informações de qual DAO deve ser carregado de um properties
		// ou XML
	}

	public IContratoDAO getContratoDAO() {
		// faz os testes e retorna a instancia a ser usada
		return ContratoDAO.getInstancia();
	}

	public static FabricaContratoDAO getInstancia() {
		return fabricaContratoDAO;
	}
}

Dos DAO’s, que possuem um método getInstancia que o liga à fabrica:

public class ContratoDAO implements IContratoDAO {

	private static final ContratoDAO  ContratoDAO = new ContratoDAO();

	//Declaração de query's

                private static final String STMT_CONTRATO = "SELECT * FROM contrato";
	// demais query's

		
	public Contrato contrato(int idContrato) throws Exception {
                 // conexão com o banco e retorno do objeto Contrato

	}
                  
                // outros métodos

	public static ContratoDAO getInstancia() {
		return ContratoDAO;
	}

}

Gostaria da opinião de vocês com relação a esta arquitetura, e sobre melhorias que possam ser implementadas.

Valeu galera.

 Não vi nada de errado nesta arquitetura, mas com certeza o sistema de vocês não é grande. A fábrica de dao poderia gerenciar um pool de instancias ao inves de apenas uma instância. Isto gera maior capacidade de atender grande concorrência. A regra de negócio está sendo colocada na Action? Se sim, isto costuma ser uma má escolha. Digamos que vocês queiram expor um webservice que faça a mesma regra de negocio que esta Action? Vocês vão ter que copiar e colar código. Se vocês tiverem uma camada de negocio vocês podem fazer isso:

…Action -----------------
…>---------- GeraContratoService ---------- ContratoDao
…Web Service----------

 Desta forma a Action e o Web Service só vão se preocupar em expor dados e não trabalhar com regra de negócio.

[quote=mauriciorocha665] Não vi nada de errado nesta arquitetura, mas com certeza o sistema de vocês não é grande. A fábrica de dao poderia gerenciar um pool de instancias ao inves de apenas uma instância. Isto gera maior capacidade de atender grande concorrência. A regra de negócio está sendo colocada na Action? Se sim, isto costuma ser uma má escolha. Digamos que vocês queiram expor um webservice que faça a mesma regra de negocio que esta Action? Vocês vão ter que copiar e colar código. Se vocês tiverem uma camada de negocio vocês podem fazer isso:

…Action -----------------
…>---------- GeraContratoService ---------- ContratoDao
…Web Service----------

 Desta forma a Action e o Web Service só vão se preocupar em expor dados e não trabalhar com regra de negócio.[/quote]

Olá Mauricio,

Obrigado pela resposta.
Deixa ver se eu entendi.

Sobre a fábrica:
A idéia seria fazer uma generalização para que todas fizessem o acesso desta Fabrica Genérica, seria isso?

Sobre a parte de negócio:
Se não me engano o negócio realmente está não só nas Action’s mas também nos DAO’s. A sua sugestão seria então a criação de classes Service só para as regras de negócio, e então os Actions, e WebServices (ainda não trabalhamos com eles, mas ninguém sabe o futuro né…) consumirem dessas Services, seria isso?!

Obrigado.

Sobre o negócio:

Se baseia assim, DAO é um components “burro”, ele só faz inserção, deleção, salect, etc no banco. A action também é “burra” pois só recebe dados e os exibe na tela. Ja um serviço de negócio faria a execução da regra de negocio.

Exemplo: No serviço de negocio de um banco chamado TransferenciaService podemos ter um metodo chamado transfere(Usuario u1, Usuario u2, double valor). e a implementação poderia ser algo tipo:

daoContaBancaria.retira(u1, valor);
daoContaBancaria.deposita(u2, valor);

Entao não importa quem chamou este serviço de transferencia (webservice, action ou até mesmo outra regra de negócio), e sim o fato que temos um componente reutilizável que está sempre pronto para fazer uma operação de transferencia independentemente de quem o chamou.

Sobre a fábrica:

Não é isso não, a idéia é você criar digamos 10 instancias do DAO e colocar em uma lista. Então quando 2 clientes acessarem ao mesmo tempo você manda a primeira instancia para um cliente e outra para outro cliente, isso melhora a performance quando se tem muitos acessos concorrentes (pesquise EJB session bean pool). Isso só é útil de você estiver com muitos acessos ao teu DAO, senão é irrelevante. Dê uma pensada em usar Spring ou EJB pois eles controlam esses pools automaticamente. Lembrando… EJB apenas se for uma aplicação REALMENTE grande.

[quote=mauriciorocha665]Sobre o negócio:

Se baseia assim, DAO é um components “burro”, ele só faz inserção, deleção, salect, etc no banco. A action também é “burra” pois só recebe dados e os exibe na tela. Ja um serviço de negócio faria a execução da regra de negocio.

Exemplo: No serviço de negocio de um banco chamado TransferenciaService podemos ter um metodo chamado transfere(Usuario u1, Usuario u2, double valor). e a implementação poderia ser algo tipo:

daoContaBancaria.retira(u1, valor);
daoContaBancaria.deposita(u2, valor);

Entao não importa quem chamou este serviço de transferencia (webservice, action ou até mesmo outra regra de negócio), e sim o fato que temos um componente reutilizável que está sempre pronto para fazer uma operação de transferencia independentemente de quem o chamou.

Sobre a fábrica:

Não é isso não, a idéia é você criar digamos 10 instancias do DAO e colocar em uma lista. Então quando 2 clientes acessarem ao mesmo tempo você manda a primeira instancia para um cliente e outra para outro cliente, isso melhora a performance quando se tem muitos acessos concorrentes (pesquise EJB session bean pool). Isso só é útil de você estiver com muitos acessos ao teu DAO, senão é irrelevante. Dê uma pensada em usar Spring ou EJB pois eles controlam esses pools automaticamente. Lembrando… EJB apenas se for uma aplicação REALMENTE grande.[/quote]

Ok.
Entendi agora o que você quis dizer sobre o negócio, em nosso sistema isso tudo é feito nas classes Manter, e não na Action e Dao como havia falado anteriormente.
Já sobre a fábrica, realmente o controle feito pelo Spring iria ajudar bastante, e algo a ser sugerido para um futuro próximo…rs…

Valeu pelos comentários!
Amigos, mas alguém gostaria de manifestar uma opinião? Todas são sempre bem vindas!

Abraço

Só outra coisa Mauricio,

Poderia demonstrar essa implementação de um array de instancias na fábrica?

Abraço

Não tenho nenhum exemplo. Isso não é algo muito trivial… É recomendavel você usar Spring e deixar que ele gerencie isto.

Caso queira implementar mesmo assim… o que já fiz é você colocar as instancias em uma estrutura de pilha e conforme vir as requests você passa uma delas como retorno (normalmente a do topo).

[quote=mauriciorocha665]Não tenho nenhum exemplo. Isso não é algo muito trivial… É recomendavel você usar Spring e deixar que ele gerencie isto.

Caso queira implementar mesmo assim… o que já fiz é você colocar as instancias em uma estrutura de pilha e conforme vir as requests você passa uma delas como retorno (normalmente a do topo).[/quote]

Valeu mauricio.

Se mais algum amigo quiser se manifestar agradeço!

:wink:

Abraço

A nomenclatura das interfaces não precisariam iniciar com um “I”, pois em tese, elas são o que de fato representa o modelo, e quem leva a culpa por isso sao suas NImpl, que aí sim é interessante adicionar o sufixo “impl” indicando que é uma implementação para tal…

apenas, uma dica.

[quote=peerless]A nomenclatura das interfaces não precisariam iniciar com um “I”, pois em tese, elas são o que de fato representa o modelo, e quem leva a culpa por isso sao suas NImpl, que aí sim é interessante adicionar o sufixo “impl” indicando que é uma implementação para tal…

apenas, uma dica.

[/quote]

E aí, blz!
Pois é… tô só seguindo o padrão já existente aqui no trampo… falows!
Mais alguém?! rs…

Abraço,

Bom, não entendi muito o pq de tantas classes para apenas uma entidade. Mas enfim, não vou entrar no mérito.

Separe um tempo para ler sobre DDD(Domain Driven Design), seja aqui no fórum ou o próprio livro.

Isso pode ampliar seus horizontes sobre o assunto.

Até.

Eh interessante tbm deixar seus IDs como Long, pois assim, se um dia eles passarem a barreira dos 32 bits, lascou! :smiley:

Blz, concordo que lascou… mas é um sistema médio, digamos, não é de grande porte, principalmente em termo de banco de dados. Até minha tabela chegar na barreira dos 32 bits, já vou ter aposentado…rs…

Vlws!

:wink:

Por causa disso que surgiu o bug do milênio! :lol:

Sinceramente não entendi a necessidade de um pool de DAOs. Isso realmente impacta na performance?
Um mesmo objeto não pode ser acessado concorrentemente por varios clientes? Pra que a necessidade de um pool de DAO então?

Por favor, isso me encucou.

[]'s

[quote=newj]Bom dia.

Estou trabalhando em um novo emprego agora, e me deparei com a arquitetura já utilizada na empresa, no desenvolvimento de um pequeno portal para atender as necessidades da gerência. Neste Portal são agregado sistemas de controle de contratos e pessoal.
Essa arquitetura é composta pelos Beans de cada objeto:


public class Contrato{
	
	private int idContrato;
	
	private String nomeContrato;

	// get's e set's		
}

Pelos Java Form’s de cada Objeto:


public class ContratoForm extends ActionForm {


	private int idContrato;

	private String nomeContrato;

	
	public void reset(ActionMapping mapping, HttpServletRequest request) {
		nomeContrato = "";
	}

                // get's e set's

}

Dos action’s que tratam as ações de cada objeto:


public final class ContratoAction extends Action {

	public ActionForward editarContrato(ActionMapping mapping,
                               ActionForm form,
                               HttpServletRequest request,
                               HttpServletResponse response)
       throws Exception {

                     return mapping.findForward("editar");
       }
}

De classes que chamamos de Manter que invocam os métodos declarados na Interface e ligam ao DAO (Me corrijam se estiver errado, por favor…):

public class ManterContrato {

	private IContratoDAO contratoDAO = FabricaContratoDAO.getInstancia()
			.getContratoDAO();

	public Contrato contrato(int idContrato) throws Exception {
		return contratoDAO.contrato(idContrato);
	}

	public void incluirContrato(Contrato contrato) throws Exception {
		contratoDAO.incluirContrato(contrato);
	}

                // outros métodos
}

Das Interfaces:

public interface IContratoDAO {
	public Contrato contrato(int idContrato) throws Exception;

	public void incluirContrato(Contrato contrato) throws Exception;

	// outros métodos
}

De Fábricas de Objetos:

public class FabricaContratoDAO {
	private static FabricaContratoDAO fabricaContratoDAO = new FabricaContratoDAO();

	private FabricaContratoDAO() {
		// Carrega informações de qual DAO deve ser carregado de um properties
		// ou XML
	}

	public IContratoDAO getContratoDAO() {
		// faz os testes e retorna a instancia a ser usada
		return ContratoDAO.getInstancia();
	}

	public static FabricaContratoDAO getInstancia() {
		return fabricaContratoDAO;
	}
}

Dos DAO’s, que possuem um método getInstancia que o liga à fabrica:

public class ContratoDAO implements IContratoDAO {

	private static final ContratoDAO  ContratoDAO = new ContratoDAO();

	//Declaração de query's

                private static final String STMT_CONTRATO = "SELECT * FROM contrato";
	// demais query's

		
	public Contrato contrato(int idContrato) throws Exception {
                 // conexão com o banco e retorno do objeto Contrato

	}
                  
                // outros métodos

	public static ContratoDAO getInstancia() {
		return ContratoDAO;
	}

}

Gostaria da opinião de vocês com relação a esta arquitetura, e sobre melhorias que possam ser implementadas.

Valeu galera.[/quote]

Na empresa na qual trabalho a gente usa algo bem semelhante. A diferença é que temos o Services como já foi falado aqui. Acho que a grande maioria trabalha desta forma, embora nem sempre eu ache uma boa solução… Depende muito do sistema.