Refatoracao - Ajuda / Ideias

8 respostas
Rafael_Steil

Estou aceitando dicas / sugestoes em relacao a refatoracao de codigo. O problema basicamente o seguinte: atualmente, no JForum, o codigo que lida com a logica de listar / inserir / editar etc esta nas Actions, depedente de um request. O que eu quero eh separar o maximo de codigo que for possivel, afim de torna-lo facil de usar em outros ambientes, que nao precisam necessariamente ser HTTP.

A primeira coisa que me vem a cabeca eh colocar o codigo de logica em uma classe comum, e passar os dados que ela vai precisar via metodo / setter / construtor. Mas o meu medo eh que, como pode haver n parametros (10 eh um numero comum), a chamada ao metodo ficaria um tanto… hmm… fora do comum.

Exemplificando, eis o metodo atual que atualiza uma entrada do Favoritos:

public void updateSave() throws Exception
{
	int id = this.request.getIntParameter("bookmark_id");
	BookmarkModel bm = DataAccessDriver.getInstance().newBookmarkModel();
	Bookmark b = bm.selectById(id);
	
	if (!this.sanityCheck(b)) {
		return;
	}
	
	b.setTitle(this.request.getParameter("title"));
	b.setDescription(this.request.getParameter("description"));
	
	String visible = this.request.getParameter("visible");
	b.setPublicVisible(visible != null && !"".equals(visible) ? true : false);
	
	bm.update(b);
	this.setTemplateName(TemplateKeys.BOOKMARKS_UPDATE_SAVE);
}

Nesse simples codigo, ha 4 parametros que vem do request: bookmark_id, title, description e visible. Desacoplando usando a abordagem citada anteriormente, o novo codigo seria algo como

// BookmarkLogic.java
...
public int updateSave(int bookmarkId, String title, String description, boolean visible) 
{
	BookmarkModel bm = DataAccessDriver.getInstance().newBookmarkModel();
	Bookmark b = bm.selectById(bookmarkId);
	
	if (!this.sanityCheck(b)) {
		return SANITY_FAILED;
	}

	b.setTitle(title);
	b.setDescription(description);
	b.setPublicVisible(visible);

	bm.update(b);

	return UPDATE_OK;
}
// BookmarkAction.java - classe do codigo original
...
public void updateSave()
{
	BookmarkLogic logic = new BookmarkLogic();

	int status = logic.updateSave(this.request.getIntParameter("bookmark_id"), 
		this.request.getParameter("title"),
		this.request.getParameter("description"),
		this.request.getParameter("visible") != null);

	if (status == BookmarkLogic.SANITY_FAILED) {
		this.error("Bookmarks.notFound");
		return;
	}
}

Ficaria algo assim… O que acham? sugestoes sao mais do que bem vindas!

Rafael

8 Respostas

pcalcado

Oi,

Que tal um Introduce Parameter Object com um objeto próprio? Ou um Map mesmo…

Rafael_Steil

Hm… ao meu ver, somente justificaria usar esse se o numero de parametros a passar fosse muito grande, e nao relacionados. O http://www.refactoring.com/catalog/preserveWholeObject.html me pareceu mais interessante para determinados casos - como esse do autalizar o Favoritos.

O inserir / editar mensagem precisa de bastate coisa coisa - praticamente todos os dados contidos na classe Post, como id do forum, id do topico, o texto em si e as opcoes de formatacao. Se tiver alguns (poucos) a mais, seria ok passar eles como argumentos “simples”? … ou mesmo fazer “meio-a-meio”, passando o que se encaixar em algum objeto ja existe e o resto - se for em um numero variavel - usarno o conceito do Introduce Parameter…

Rafael

cv1

Map, Map, Map! :slight_smile:

Voce pode usar o mesmo truque que o WebWork usa pra copiar tudo do Request.getParameter() pra um Map, e partir dali. Outra coisa massa eh que usando o BeanUtils, voce pode copiar tudo de um Map pra um bean (entao a chave “user_id” vira user.setId(), e por ai vai) :mrgreen:

pcalcado

Eu até costumo usar maps nesse tipod e situação, mas a questão de não ter tipagem (e logo a juda do compilador) semrpe me deixa mal… antes dos Generics, claro 8)

Rafael_Steil

cv:
Map, Map, Map! :slight_smile:

Voce pode usar o mesmo truque que o WebWork usa pra copiar tudo do Request.getParameter() pra um Map, e partir dali. Outra coisa massa eh que usando o BeanUtils, voce pode copiar tudo de um Map pra um bean (entao a chave “user_id” vira user.setId(), e por ai vai) :mrgreen:

Como a resposta foi colada com a minha, fica a mesma pergunta feita apos a resposta do philip: usar algo assim mesmo quando boa parte dos parametros pode ser passada usando algum objeto ja existente? (duh, me parece meio logico isso, mas … :stuck_out_tongue: )

Rafael

ronaldtm

Pra algumas coisas, dá pra usar TOs (Transfer Objects), não?

Eu sei que muita gente acha que TOs são um anti-pattern, mas eu acho que eles são bem úteis nesses casos, onde você basicamente passa todos os dados de uma ‘entidade’ como parâmetro.

Claro que não dá pra bitolar e criar TOs pra todas as chamadas de métodos :), mas pra essas do tipo save() e update() eles caem como uma luva.

Rafael_Steil

Se alguem quiser ter uma ideia melhor do “problema”, eis uma classe interessante:

https://jforum.dev.java.net/source/browse/jforum/src/net/jforum/view/forum/UserAction.java?rev=1.35.2.2&only_with_tag=NewDAO&view=markup

o metodo insertSave() eh um que precisa duma refatoracao, mas todos de uma maneira geral necessitam…

Rafael

Paulo_Silveira

como o ronald falou, acho TO legal, soh que ai voce muda de push pra pull.

Criado 25 de março de 2005
Ultima resposta 25 de mar. de 2005
Respostas 8
Participantes 5