DJ180
DJ180

Reputation: 19854

Refactoring to higher order function in Scala

I am new to Scala and wondering if I can somehow refactor this code using Scala's support for function literals, higher order functions etc

Because there is no relationship between a Competition and a Team, I don't see how this is possible. I guess I could add a trait to Competition and Team that would include the name property and it would then be possible.

Any other alternatives?

class CompetitionDao extends BaseDao[Competition]{

  def retrieveAllCompetitionNames(): java.util.List[String] = {
    val competitions: java.util.List[_ <: Competition] = getDao().queryForAll()
    val competitionNames: java.util.List[String] = new ArrayList();
    for (competition <- competitions) competitionNames.add(competition.name)
    competitionNames
  } 

}

class TeamDao extends BaseDao[Team]{

  def retrieveAllTeamNames(): java.util.List[String] = {
    val teams: java.util.List[_ <: Team] = getDao().queryForAll()
    val teamNames: java.util.List[String] = new ArrayList();
    for (team <- teams) teamNames.add(team.name)
    teamNames
  }  
}

Upvotes: 0

Views: 212

Answers (2)

EECOLOR
EECOLOR

Reputation: 11244

You could introduce a trait and use map like Enrique suggested:

import scala.collection.JavaConversions._

trait NameRetrieval[T <: { def name: String }] { self: BaseDao[T] =>
  def retrieveAllNames = getDao.queryForAll.map(_.name)
}

You can then use it like this:

object TeamDao extends BaseDao[Team] with NameRetrieval[Team]

Edit

The [T <: { def name:String }] means that the NameRetrieval trait can be used for any type that has a an element called name of type String. To find out more about that notation search for 'Scala structural types'.

With the self: BaseDao[T] I say that this trait can only be used in combination with a BaseDao that has the same type for T. This allows me to freely use the getDao method because I know for sure it's available. A similar pattern is used in the Cake Pattern, so you can check that out for more information.

Upvotes: 4

korefn
korefn

Reputation: 955

You could try something like:

object DAO{
  def getNames: String => List[String] = { from =>
    from match {
      case "competition" => Competition.getDao().queryForAll().map(_.name)
      case "team" => Team.getDao().queryForAll().map(_.name)
    }
  }

  ...
}

calling this would be as easy as

val temNames : List[String] = DAO.getNames("team")

Upvotes: 0

Related Questions