HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

What improvements can I make to avoid these If statments?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
canthesewhatmakeavoidimprovementsstatments

Problem

I have Model Object Car.

public class Car
{
  private String colour;
  private String make;
  private String yearOfMake;
}


Then a managed bean

public Class CarSearchManagedBean
{
  private Car car;

  @EJB
  private CarFacade carFacade;

  public String search()
  {
     this.car =carFacade.find(car);
     .....
  }
}


Then I have a JSF facelet with input fields connected to car object by backing bean and a search button linked to search method .There is no Ajax and use can provide values for any property and since there is no auto cleaning can possibly provide values more than one property but search only uses one.

Then before I show CarFacade I will show CarDao becasue I think makes more sense here.

public class CarDaoImpl implements CarDao
{
  public Car findByColour(Car car){
  //Calls a webservice method
  }
  public Car findByMake(Car car){
  //Calls a webservice method
  }
  public Car findByYearOfMake(Car car){
  //Calls a webservice method
  }

}


Now if the CarFacade I have this ugly if statment that I do not know how to avoid.

public class CarFacade

{
   @EJB
   CarDao carDao;

   public Car find(final Car car)
   {
      Car aCar ;
      //How can improve the design to avoid this If statment
      if (car.getColour()!=null)
      {
       aCar = carDao.findByColour(car)
      }
      else if (car.getMake()!=null)
      {
        aCar = carDao.findByMake(car);
      }
      else
      {
        aCar =carDao.findByYearOfMake(car);
      }
      return aCar;
   }
}

Solution

You'll want to look up the Strategy Pattern.

In your specific case, you're probably going to want to do something along these lines (note - I've never worked with ManagedBeans, so I don't know what spanners that throws).

Leave your Car class as normal. Or, well, you may want to provide specific types for assignments, if possible (So make Colour an actual class, even if it only contains an actual String - just so people can't assign a Make value to it...).

Your CarDAO should be multiple instances. Something like:

public class CarColorFinderDAOImpl implements CarDAO {

    public Car find(String colorToFind) {
        // search by color here
    }
}


Then your CarFacade actually transforms to something like this:

public class CarFacade {

    private Map finderDAO = new HashMap();

    public Car find(Sring searchValue, String searchColumn) {

       return finderDAO.get(searchColumn).find(searchValue);
    }

    public void registerFinder(String searchColumn, CarDAO finder) {
        finderDAO.put(searchColumn, finder);
    }
}


Which you then call (mostly) as normal from your managed bean.

Please not that there are further abstractions available (such as encapsulating searchValue and searchColumn in some sort of FinderContract object). But this is a quick basic one to get you started.

Code Snippets

public class CarColorFinderDAOImpl implements CarDAO {

    public Car find(String colorToFind) {
        // search by color here
    }
}
public class CarFacade {

    private Map<String, CarDAO> finderDAO = new HashMap<String, CarDAO>();

    public Car find(Sring searchValue, String searchColumn) {

       return finderDAO.get(searchColumn).find(searchValue);
    }

    public void registerFinder(String searchColumn, CarDAO finder) {
        finderDAO.put(searchColumn, finder);
    }
}

Context

StackExchange Code Review Q#4896, answer score: 4

Revisions (0)

No revisions yet.