Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Scala:带选项的构造函数方法_Oop_Scala_Orm - Fatal编程技术网

Oop Scala:带选项的构造函数方法

Oop Scala:带选项的构造函数方法,oop,scala,orm,Oop,Scala,Orm,由于不相关的原因而避免使用普通的ORM,我正在尝试编写一个类,该类既可以显示来自DB的数据,也可以向其中添加/更新数据(首先这是一个好主意吗?) 这意味着您可以: 知道记录的id和名称,创建表示该记录的对象 只知道记录的id,就可以从DB和 如果不提供id,则对象将处于未同步状态,并将在添加/更新后同步 问题是,第一个构造函数依赖于DB操作,因此选项[Car]作为返回类型更有意义。但据我所知,Scala不允许您执行以下操作: def this(_id:ID):Option[Car] = {

由于不相关的原因而避免使用普通的ORM,我正在尝试编写一个类,该类既可以显示来自DB的数据,也可以向其中添加/更新数据(首先这是一个好主意吗?)

这意味着您可以:

  • 知道记录的id和名称,创建表示该记录的对象
  • 只知道记录的id,就可以从DB和
  • 如果不提供id,则对象将处于未同步状态,并将在添加/更新后同步
  • 问题是,第一个构造函数依赖于DB操作,因此选项[Car]作为返回类型更有意义。但据我所知,Scala不允许您执行以下操作:

    def this(_id:ID):Option[Car] = { 
       try {
          val car = DB.fetchCar(_id)
          Some(this(_id,car.name))
       } catch {
          case e:Exception => None
       } 
    }
    

    这有意义吗?您将如何实现此功能?

    您可以从类的伴生对象执行此操作:

    class Car private (data: CarData) {
        ...
    }
    
    object Car {
    
        def apply(id: Int): Option[Car] = {
            DB.find(id) match {
                case Some(data) => Some(new Car(data))
                case _ => None
            }
        }
    
        def apply(data: CarData): Car = {
            new Car(data)
        }
    }
    
    这允许客户端代码

    val someId: Int = ...
    val maybeCar = Car(someId)              // Will be Option[Car]
    val someKnownData: CarData = ...
    val definitiveCar = Car(someKnownData)  // Will be Car
    

    德克有一个正确的想法,将伴生对象用作工厂。虽然可以对设计进行一些改进:

    case class Car private (id: Option[Id], name: String)
    
    object Car {
      def fetch(id: Id, name: String): Option[Car] = Some(Car(id, name))
    
      def fetch(name: String): Option[Car] = Some(Car(None, name))
    
      def fetch(id: Id): Option[Car] = try {
        Option(DB.fetchCar(id)) //will be `None` if the fetch operation returned null
      } catch {
        case _ => None
      }
    }
    
    用作:

    val car1 = Car.fetch(someId, "Herbie")
    
    val car2 = Car.fetch("Herbie")
    
    val car3 = Car.fetch(someId)
    
    val car2withId = car2.copy(id = someNewId)
    

    也很有意义,CarData是指将所有对象数据打包到一个case类中吗?听起来不错,但是对于这种行为,当前的Car类最好作为可重用的泛型类使用,对吧?
    CarData
    只是需要的任何数据/值/参数的占位符。没有与之相关的实际设计方案。。。很抱歉,如果它带来了任何混乱的话。关于“Option()”部分也是一个很好的提示。干杯
    val car1 = Car.fetch(someId, "Herbie")
    
    val car2 = Car.fetch("Herbie")
    
    val car3 = Car.fetch(someId)
    
    val car2withId = car2.copy(id = someNewId)