Long Method? Move Accumulation to a Collecting Parameter

Posted on Monday, October 18, 2010

0


You would have definitely come across long bulky methods which accumulate information to a local variable and pass back that information. Here the local variable goes through a lot of changes throughout the logic of the method before it is finally returned back. Let us see how the combination of compose method, that we covered in the last post, and moving accumulation to a collecting parameter can help us in this case. Let us consider the following code sample

public List<Event> filterEvents(){
	List<Event> filteredEvents = new ArrayList<Event>();
	for (StateEvent stateEvent : allStateEvents) {
	        //if some logic is true then
		filteredEvents.add(stateEvent);
	}

	for (DistrictEvent districtEvent : allDistrictEvents) {
		for (Event event: filteredEvents){
			if (event.getChairman().equals(districtEvent.getChairman())){
				filteredEvents.add(districtEvent);
			}
		}
	}
	for (CityEvent cityEvent : allCityEvents) {
	        //if some logic is true then
		filteredEvents.add(cityEvent);
	}
	…
	…
	… continues …

	return filteredEvents;
}

As you would notice, this method is an accumulating method. Why? Because it is a method that accumulates information into a collecting parameter. The collecting parameter here happens to be filteredEvents. Ideally, you could decompose this method in 2 ways

Either we can use the compose method and have individual methods pass back the results as events. These events could then be combined into a final list which can be passed back.

OR

Instead of having each of the methods return a result, which you later combine into a final result, you can incrementally accumulate a result by passing a Collecting Parameter to each of the methods. The methods write their information to the Collecting Parameter, which accumulates all of the results.

For our case let us see how the method would change

public List<Event> filterEvents(){
	List<Event> filteredEvents = new ArrayList<Event>();
	filterPerStateEvents( filteredEvents);
	filterPerDistrictEvents( filteredEvents);
	filterPerCityEvents( filteredEvents);
	return filteredEvents;
}

As you can see the method becomes very small and clean as compared to the one that we started with. This method not only connects well with the reader by showing exactly what is happening but is also easy to extend and maintain.

And what do our private methods look like? You would have guessed by now, that they too are easy to read, clean and follow SRP.

private void  filterPerStateEvents (List<Event>  filteredEvents){
	for (StateEvent stateEvent : allStateEvents) {
		//if some logic is true then
		filteredEvents.add(stateEvent);
	}
}

private void  filterPerDistrictEvents (List<Event>  filteredEvents){
	for (DistrictEvent districtEvent : allDistrictEvents) {
		for (Event event: filteredEvents){
			if (event.getChairman().equals(districtEvent.getChairman())){
				filteredEvents.add(districtEvent);
			}
		}
	}
}

private void  filterPerCityEvents (List<Event>  filteredEvents){
	for (CityEvent cityEvent : allCityEvents) {
	//if some logic is true then
		filteredEvents.add(cityEvent);
	}
}

With this post we saw how easy it is to refactor code and reduce the size of long bulky methods by using a combination of compose method and moving accumulation to a collecting parameter. Keep tuned. Wishing you a clean code.

Advertisements
Posted in: Agile, Java