Can I define a class without a public constructor and place the factory method for this class object in another class in Scala?

For example (maybe a little clumsy from real life, but just for illustration):

β€œUser” is the case class containing the username and identifier. An identifier can never be set manually, and an instance of a user class without a set of identifiers does not make sense.

The UserBase class supports the user base and has a getUser (name: String): User method that returns a sequential instance of the user.

No one except the UserBase object can know (well, someone can, but really should not rely on this knowledge) the user ID, so creating a user instance manually does not make sense (and can lead to errors in the future if someone hardcodes accidentally forgets this). In addition, an unwanted instance of an orphaned user that is not tracked by UserBase is also undesirable.

So the task is to make calling UserBase.getUser the only way to get the user instance.

Could this be implemented in Scala?

+3
source share
3 answers

. :

object O {
  class C private[O] (val x: Int) { }
  object D { def apply(i:Int) = new C(i) }
  def getC(i:Int) = new C(i)
}

scala> O.D(5)
res0: O.C = O$C@5fa6fb3e

scala> new O.C(5)
<console>:10: error: constructor C cannot be accessed in object $iw
       new O.C(5)

scala> O.getC(5)
res1: O.C = O$C@127208e4
+2

case , - apply() . "" case. apply(), error: method apply is defined twice

factory, case. (toString, apply, unapply ..), .

+1

, "" , , , , , factory .

factory - ( , case, )

class User private(val id: Int, val name: String) {
  ...
}

object User {
  private def nextId() : Int = ...
  def apply(name: String) = new User(nextId(), name)
}

//now create one:
val u = User("Ivan")

, User ( ), id. , () User , .

, UserBase factory. factory , , , .

+1

Source: https://habr.com/ru/post/1770985/


All Articles