The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

312748 (5) [Avatar] Offline
#1
In the book, we are given an example of a smart constructor like the following:

final case class CheckingAccount private(no: String, name: String, dateOfOpen: Option[Date], dateOfClose: Option[Date], balance: Balance) extends Account

object Account {
  def checkingAccount(no: String, name: String, openDate: Option[Date], closeDate: Option[Date], balance: Balance): Try[Account] = {
    closeDateCheck(openDate, closeDate).map { d =>
    CheckingAccount(no, name, Some(d._1), d._2, balance)
  }
}


Here the case class is final in order to prevent anyone from extending it and thus constructing their own unsafe instances of CheckingAccount. We also make the constructor private in order to prevent instantiation with the new keyword. What this fails to address, however, is that you can still create an unsafe instance using the apply() method of the companion object. How do we address this issue? Originally I was thinking of overriding the apply method to make it private but this results in a compiler error because now the apply method is defined twice (once by the you and once by the compiler for the cass class).

The example in the online repo for Chapter 3 (https://github.com/debasishg/frdomain/blob/master/src/main/scala/frdomain/ch3/smartconstructor/Account.scala) defines the 'copy' and 'apply' methods "to ensure that the user cannot use" them but I really don't see how that is because those methods are still available in the companion object.

Is there a better way of achieving a safer smartconstructor?