A life committed to learning.

Category: SCRUM

Continue Reading

How to improve productivity when developing JEE based web applications

The title of this post was stolen from Stackoverflow, from this discussion:

http://stackoverflow.com/questions/645746/how-to-improve-productivity-when-developing-jee-based-web-applications

I really like and agree with this point:

Being “the enterprise stack”, it is often used to create boring, ugly, “good enough” applications and, in general, enterprises tend not to attract great developers who love programming, and think and care about what they do. The quality of software in the enterprise world is not great.

There are exceptions, of course, but mainly from what I’ve seen from the past 10 years, this is, sadly, true. Why?

Continue Reading

Programmer testing

Recently I’ve researched a little about programmer testing, which resulted in a slide set that I’m now sharing with you. These slides are the basis for a training, which included a lot of exercises, as I like to do.

It includes some information about:

  • Agile testing
  • Test driven development
  • Unit testing with JUnit
  • Test doubles and Mockito
  • Code coverage

If you have any feedback or question, please let me know by leaving a comment or send me an email.

Continue Reading

Fluent interfaces while trying to make sense of Prototype Pattern

Sometimes I don’t have great opportunities to apply some nice concepts, but I have some time to learn them.

While trying to make some sense of the Prototype Pattern, I was doing some experiments and I needed, of course, the tests to prove my experiments.

It was when coding the tests, trying to define the client interface (not user interface :)), that to my mind came this article from Martin Fowler: Fluent Interface.

Well, what it matters are these two points:

  • Making your tests first helps you, a lot, to define not only the behavior, but also importantly, the client API.
  • Using Fluent Interface with a Builder, it’s a great way to send our message to the objects implementing the API.

Example of using a fluent interface:

package eu.jpereira.trainings.designpatterns.creational.prototype;

import static org.junit.Assert.*;

import java.util.List;
import java.util.Properties;

import org.junit.Test;

import eu.jpereira.trainings.designpatterns.creational.prototype.exception.CannotHaveZeroPartsException;
import eu.jpereira.trainings.designpatterns.creational.prototype.exception.CouldNotCloneLastObjectException;
import eu.jpereira.trainings.designpatterns.creational.prototype.exception.NeedToPackLastVehicleException;
import eu.jpereira.trainings.designpatterns.creational.prototype.exception.VehicleDoesNotHavePartsException;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.Shell;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.Tire;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.Vehicle;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.VehiclePartEnumeration;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.VehiclePartPropertiesEnumeration;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.Window;
/**
 * @author jpereira
 *
 */

public class ClientTest {

	
	/**
	 * Integration Test
	 * @throws CouldNotCloneLastObjectException
	 * @throws CannotHaveZeroPartsException
	 * @throws NeedToPackLastVehicleException
	 * @throws VehicleDoesNotHavePartsException
	 */
	@Test
	public void testCreateBUS() throws CouldNotCloneLastObjectException, CannotHaveZeroPartsException, NeedToPackLastVehicleException, VehicleDoesNotHavePartsException {
		Client client = new Client();
		
		//create a bus car
		//Create props for tire
		Properties tiresProps = new Properties();
		tiresProps.put(VehiclePartPropertiesEnumeration.SIZE,10);

		//Create props for shell
		Properties shellProps = new Properties();
		shellProps.put(VehiclePartPropertiesEnumeration.COLOR,"blue");

		
		Properties windowProps = new Properties();
		windowProps.put(VehiclePartPropertiesEnumeration.WIDTH,20);
		windowProps.put(VehiclePartPropertiesEnumeration.WIDTH,20);

		//client.createVehicle().with(new Tires()).times(4).
		Vehicle vehicle = client.vehicleBuilder().createVehicle().with(new Tire(tiresProps)).times(3).with(new Window(windowProps)).times(8).with(new Shell(shellProps)).times(1).packIt();
		
		//Get all windows
		List<VehiclePart> parts = vehicle.getParts(VehiclePartEnumeration.WINDOW);
		assertEquals(8, parts.size());
		 
	}
}

A hypothetical Builder implementation with a fluent interface:

package eu.jpereira.trainings.designpatterns.creational.prototype;

import java.util.ArrayList;
import java.util.List;

import eu.jpereira.trainings.designpatterns.creational.prototype.exception.CouldNotCloneLastObjectException;
import eu.jpereira.trainings.designpatterns.creational.prototype.exception.CannotHaveZeroPartsException;
import eu.jpereira.trainings.designpatterns.creational.prototype.exception.NeedToPackLastVehicleException;
import eu.jpereira.trainings.designpatterns.creational.prototype.model.Vehicle;

/**
 * @author jpereira
 *
 */
public class SimpleVehicleBuilder implements VehicleBuilder {

	private List<VehiclePart> vehicleParts;
	
	public SimpleVehicleBuilder() {
		this.vehicleParts = createNewPartsBag();
	}
	
	@Override
	public VehicleBuilder createVehicle() throws NeedToPackLastVehicleException{
		//Just check this is allways the first call on the builder
		if (vehicleParts.size()!= 0) {
			throw new NeedToPackLastVehicleException();
		}
		return this;
	}

	
	@Override
	public VehicleBuilder with(VehiclePart part) {
		this.vehicleParts.add(part);
		return this;
	}

	
	@Override
	public VehicleBuilder times(int times) throws CouldNotCloneLastObjectException, CannotHaveZeroPartsException {
		if (times==0) {
			throw new CannotHaveZeroPartsException();
		}
		//get the last one and clone it xtimes 
		if ( this.vehicleParts.size()>0) {
			
			VehiclePart lastObject = this.vehicleParts.get(this.vehicleParts.size()-1);
			//add it xtimes
			for (int i=0; i< times-1; i++) {
				//new object
				try {
					this.vehicleParts.add((VehiclePart)lastObject.clone());
				} catch (CloneNotSupportedException e) {
					//Could not clone it. Wrap exception
					throw new CouldNotCloneLastObjectException(e);
				}
			}
		}
		return this;
		
	}

	
	@Override
	public Vehicle packIt() {
		Vehicle vehicle = new Vehicle(); 
		vehicle.setParts(this.vehicleParts);
		//clear this reference for the chicle parts.
		this.vehicleParts = createNewPartsBag();
		return vehicle;
		
		
	}
	
	//Can be overriden by subclasses
	protected List<VehiclePart> createNewPartsBag() {
		return new ArrayList<VehiclePart>();
	}

}

That’s it

Continue Reading

You do not understand, yet, why do you need tests!

Why do I need tests in my software project? Keep bugs away? Yes! Keep quality high? Maybe. Can you define quality?

I see that people often justify the demand for a high test coverage with their desire to have quality in software projects, however they’re only seeing a part of the quality, the bugs visible to the customer. Quality, that word alone, can be very subjective, meaning different things to different people. Of course, having a bug free software means a high quality software, but if I have a bug free software and cannot add new features or improve existing ones, is this software a high quality software?

Now that we’re all doing “agile development” (right? at least you may think you’re doing, because you have daily meetings, review, sprints, etc), everyone should bear in mind one of the critical purposes of tests.

Big up-front designs do not work anymore, never worked for that matter (you soon loose integrity between the code and the design in the papers). We’re no able to make decisions based on the unknown (though some people may think they can), so we leave every decision to the last possible moment, until we have all, or most, information needed to make a reasonable decision.

One fundamental aspect of agile development is that you evolve your system as you go, you do it in iterations and every iteration is focusing only on what is needed to deliver the features you committed for that iteration. Your system will evolve, iteration after iteration.

With this evolution of your system, you will also evolve your architecture and design. You will not add database support on the first iteration if you don’t need a database, right? It’s waste. Right? So, from iteration to iteration your architecture and design will evolve, based on the features you have to develop and those you have developed. This is what evolutionary architecture and deign looks like, according to Martin Fowler.

But, how do you evolve your design and architecture? One of the key practices to do that is refactoring. Refactoring, again using Fowler’s knowledge, is “the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the changes of introducing bugs.”

Refactoring is one of the key practice of any project using any kind of agile development methodology, backed by testing and continuous integration. There is no way you can refactor your code if you do not have a safety net, i.e., if you don’t have something that keep you away from breaking existing functionality. This is a key point of tests, to allow you to evolve your system design and architecture.. Of course these test must be automated, needless to say that.

Continue Reading

Ahh, a responsabilidade…

Na semana passada estive presente numa formação onde se tocaram em temas bastante interessantes. Um dos temas abordados e que me chamou a atenção foi o “Modelo de Responsabilidade“.

O “Modelo de Responsabilidade” tenta descrever como nós, humanos,  geralmente nos comportamos face aos problemas que encontramos diariamente. Acho que este modelo descreve algo que nasce conosco, as atitudes e sentimentos que foram cultivados durante milhões de anos de evolução.

Continue Reading

Porque é que eu gosto das metodologias ágeis para desenvolvimento de Software?

Nesta história a equipa estava a trabalhar no lançamento de um produto para o mercado. O projecto já dura à um ano e é gerido com técnicas “tradicionais”* de desenvolvimento de software. Uma das iniciativas (ou sub-projecto, ou projecto no contexto de um programa) inclui um site,  um blog e um perfil no Facebook, no Twitter e no Youtube, onde se irá anunciar o grande lançamento do produto para o mercado.

Um mês antes do grande lançamento a equipa responsável pela comunicação pergunta ao desenvolvimento: “Quando é que o produto vai estar pronto? Precisamos de uma data para comunicar ao público o grande lançamento”.

A equipa de desenvolvimento respondeu qualquer coisa como: “Já está 85% feito.”

Com uma contas, o gestor de projecto prevê que dentro de um mês o produto estará pronto para o mercado. E foi com esse pressuposto que a equipa de comunicação anunciou a data do lançamento “imprevisível” do grande lançamento no site, no blog, no Facebook, no Twitter e no Youtube.

Mas será que aconteceu o pior?

No dia de lançamento (segundo as expectativas da equipa de comunicação), a equipa de desenvolvimento diz que não é possível lançar o produto hoje.

Infelizmente para a equipa, a data de lançamento calhou a uma Sexta-Feira, quando já todos andavam atacados com o stress pre-release. Depois do problema escalado, a direcção da empresa pede gentilmente que se esforcem ao máximo durante o fim de semana para lançar o produto na próxima Segunda-Feira. Até lhes ofereceu recompensas financeiras.

O produto é lançado na Segunda-Feira, mas apesar do incentivo financeiro,  a equipa perdeu muita motivação com este acontecimento. O overtime e sensação de “falha” é sempre um desmotivador e não há dinheiro que “mexa” nessa psicologia.

Agora, porque é que eu gosto das metodologias ágeis para desenvolvimento de software? Não vou aqui falar de tudo, é claro, mas apenas de um ponto que acho importante no contexto desta história tão comum.

Disciplina nas entregas (e tudo que o processo traz de borla)

  • A trabalhar com iterações que produzem Software “utilizável”  e com um conjunto de funcionalidades conhecidas, a equipa ganharia disciplina nas datas de entrega (Com uma gestão apropriada da equipa).
  • Se as iterações tivessem duração de 3 semanas e a equipa confiasse que necessitava de uma iteração para atingir um conjunto de funcionalidades, que somadas às produzidas nas iterações anteriores igualavam as funcionalidades mínimas para lançar o produto, então a equipa de comunicação poderia estar confiante ao anunciar a data do grande lançamento

Será este ponto importante para repensar algumas metodologias de desenvolvimento de Software? Ou assumimos a postura da  negação: “Ahh, podia ser pior se tivéssemos marcado um evento com a comunicação social e grandes investidores.”?  🙂

* Refiro-me aqui às técnicas que apenas são reconhecidas como boas práticas dentro da empresa um por um grupo restrito de empresas. 🙂

Continue Reading

O poder do “E” e do “Mas”

Acho que existe um poder psicológico no “E” e no “Mas”. O “E” tem um poder positivo, de criatividade e colaboração enquanto o “Mas”  tem um poder negativo e cria barreiras para a criatividade e colaboração.

Para o demonstrar, considerem as seguinte conversas:

Programador – “Vou conseguir terminar o módulo A a tempo”

Gestor de Projecto – “Sim, muito bem. Mas conseguirás fazer também a documentação a tempo?”

Pensem que isto vos está a acontecer e tentem perceber o roadblock que foi colocado apenas no vosso caminho?

Agora no mesmo cenário mas como uma atitude mais positiva:

Programador – “Vou conseguir terminar o módulo A a tempo”

Gestor de Projecto – “Sim, muito bem e agora temos de nos focar também em entregar a documentação a tempo? Do que precisamos?”

Pensem agora nesta última conversa. Qual delas será a mais construtiva, colaborativa, positiva e inteligente?

Continue Reading

O que faz uma boa equipa?

Num artigo do Financial Post de Setembro, pode ler-se o seguinte:

“An effective team has to be able to respond quickly[…] And for that, we need a forum for robust dialogue.

A formally constituted team comes from the desire to work collaboratively […] There is a shared commitment to goals that has the support of individual team members, and in turn supports them.

An effective team […] contrasts with a more common hierarchical approach to business goals, “the command-and-control approach.”

The effective team are […] The Magnificent Seven rather than The Good, The Bad and The Ugly.

To have and effective teams […]Businesses need to shift from individual bonuses to team-based bonuses, to flatten out their reporting structure.

What may not be a Team? […] A committee is a weak variant of a team […] A team […] is the opposite of a committee in that it has a unifying purpose and values to which all members ascribe, despite their position within the organization.

How to build a team? […] Peer mentoring is a team learning system that lets people teach each other […] Workshops have their place in leadership development, but most corporations don’t have a significant way to transfer that knowledge into skills.”

Peer Mentorig […] challenges people to take ownership of their careers. As long as no direct reporting is involved, it works magically.

How a effective team looks like?[…] include enough people, and a good cross-section of skills. We call it collective intelligence. The worst thing to do is try to figure out things by yourself.

Ainda no mesmo artigo são sugeridas oito características de uma boa equipa:

EIGHT TEAM MUST-HAVES

  1. Must have a meaningful purpose that all members care about.
  2. Can’t be too large. Some experts suggest capping at 20. Field cautions against there being too little work for all members.
  3. Needs a diverse set of skills appropriate to the goals.
  4. Needs to be physically together. Even having some team members on different floors can hurt the team.
  5. Succeeds or fails together. No stars or scapegoats.
  6. Shares leadership. Of course there is one leader, but he or she should be willing to step aside when another team member’s skills are required.
  7. Has strong shared norms and expectations of behaviour. These are soft skills that often need to be taught.
  8. Needs time. “You lose advantages if you hurry,” Prof. Field says. “Slow it down for the process to work.”

Artigo original:

http://www.financialpost.com/story.html?id=2258320

Continue Reading
Continue Reading