Tuesday, June 1, 2010

Refractoring if-else to rules

This is one snippet to convert if else into rules mostly floating in non-concerned class .For example I have designed an online movie booking system .And now I am going to add cancellation functionality -


Class CancellationService {

public void cancelTicket(Ticket ticket ){
if(isCancellationAllowed()){
ticket.setStatus("Cancelled");

}
private boolean isCancellationAllowed(Ticket ticket){
if(new Date()return false;
}
if(ticket.bookingType()=="WINDOW_BOOKING"){
return false;
}

if(ticket.BookingType()=="PHONE_BOOKING"){
return false;
}


if(ticket.BookingType() = "SPECIAL_OFFER"){
return false;
}
return true;
}

As you might have already noticed slowly application need you to add more rules .This would mix cancellation class with rules .And if you do it this way ..rules are not easy to review for domain experts.


Another better way is to --

public interface cancellationValidator {
public boolean cancellationAllowed(Ticket);
}

public class windowTicketCancellationExc implemets cancellationValidator{
public boolean cancellationAllowed(Ticket ticket){
if(ticket.cancellationType() == "WINDOW_TICKET"){
return false;
}
return true;
}

public class TicketStatusCancellationExc implemets cancellationValidator {
public boolean cancellationAllowed(Ticket ticket){
if(!ticket.status .equals("BOOKED")){
return false;
}
return true;
}


now make a TicketCancellation RulesGenerator
//a static factory for now
public class TicketCancellationRuleGenerator {
public static List getCancellationValidators() {
List validators = new ArrayList();
validators.add (new windowTicketCancellationExc() );
validators.add(new TicketStatusCancellationExc());
}
}

//now write a master cancellationValidator --

public class MasterCancellationValid