I have asked quite a few questions about the Scala collection types and how they might actually be used. Consider how I might write some service API/implementation in Java:
public interface JavaProductAPI {
public Set<IProduct> getProducts(String isin);
}
And now the impl:
public class JavaProductAPIImpl implements JavaProductAPI {
private Map<String, Set<ProductImpl>> productsByIsin;
public Set<IProduct> getProducts() {
Set<ProductImpl> s = productsByIsin.get(isin);
return s == null
? Collections.<IProduct>emptySet()
: Collections.<IProduct>unmodifiableSet(s);
}
}
Lets say that there's a really good reason why I need to have access within the service implementation to the set of products as being of ProductImpl
s, not IProduct
s.
It seems that in Scala, there's no real way to achieve this whilst at the same time exlicitly returning an scala.collection.immutable.Set
from the API access method. Unless I don't mind returning a copy of the set.
I'm going to assume that returning an actual copy of the data is bad practice (feel free to argue this point!):
val productsByIsin: Map[String, scala.collection.Set[ProductImpl]] = ...
def getProducts(isin: String): scala.collection.immutable.Set[IProduct] = {
productsByIsin.get(isin) match {
case Some(s) => scala.collection.immutable.Set(s toSeq :_*)
case None => scala.collection.immutable.Set.empty
}
}
So that therefore my only real design choice is to have the API return a scala.collection.Set
and use a read-only view:
val productsByIsin: Map[String, scala.collection.mutable.Set[ProductImpl]] = ...
def getProducts(isin: String): scala.collection.Set[IProduct] = {
productsByIsin.get(isin) match {
case Some(s) => s readOnly
case None => scala.collection.Set.empty
}
}