Scala单例模式案例-日志类

30 阅读2分钟

apply的基本使用

0034C46C.jpg

00379B1B.png 能够让使用者在创建该类实例时省去显示的 new 关键字,并且可以通过重载提供多种构造方式。

(1)apply 写在伴生对象中,它返回类的实例

(2)实例化对象时,就可以不用写new

(3)val 对象 = 伴生类( ) <===> 伴生对象.apply( )

object f1104 {
/*apply
  apply方法写在伴生对象中 可以创建对象的时候 省略new关键字

  val 对象 = 伴生类() <===> 伴生对象.apply()
  */

  class Person() {

  }

  object Person {
    def apply():Person = {
      println("apply....")
      new Person
    }
  }

  def main(args: Array[String]): Unit = {
    //创建一个类的对象
    val p1 = Person()
    val p2 = Person()

    println(p1) //自动调用applyfangfa
    println(p2)
    println(p1==p2) //false
 }
  
  //运行结果:
apply....
apply....
luzhangna01.f1104$Person@27f674d
luzhangna01.f1104$Person@1d251891
false

apply实现单例模式

00379B1B.png 实现单例模式:在伴生对象中 创建一个对象 在apply方法中返回它。

object a1104 {
/*apply
  apply方法写在伴生对象中 可以创建对象的时候 省略new关键字
  实现单例模式
    在伴生对象中 创建一个对象 在apply方法中返回他
  */

  class Person() {
   println("主构造器被调用...")
  }

  object Person {
    val p = new Person()
    def apply():Person = {
      p
     }
  }

  def main(args: Array[String]): Unit = {
    //创建一个类的对象
    val p1 = Person()
    val p2 = Person()

    println(p1) //自动调用apply方法
    println(p2)
    println(p1==p2) //true
  }
  
  //运行结果:
主构造器被调用...
luzhangna01.a1104$Person@27f674d
luzhangna01.a1104$Person@27f674d
true  

案例-日志类

1. Option[Logger] 表示一种特殊的数据类型:可能是None,可能是Logger

2. instance.isEmpty 判断是否为空。

object i1104 {
/*  实现一个日志类:Logger
  1.把一些操作信息写入到文本文件中。
  2.实现单例模式。*/

  class Logger(filenname:String) {
    def log(content:String) :Unit = {
      println(s"${content}")
    }

  }

  object  Logger {
// 定义一个对象
    var instance:Option[Logger] = None
    def apply(fliename:String):Logger = {
      if(instance.isEmpty){
        instance = Some(new Logger(fliename))
      }
      instance.get // 获取到具体的对象 如果为None 也不会报错
    }

  }

  def main(args: Array[String]): Unit = {
    val logger1 = Logger("test.log")
    val logger2 = Logger("test.log")
  println(logger2==logger1)
    logger1.log("2005-11-4 09:06:03 上scala课")
    logger2.log("2005-11-5 09:06:03 运动会")
  }
  //运行结果:
true
2005-11-4 09:06:03 上scala课
2005-11-5 09:06:03 运动会

案例-改进日志类

具体实现文件的创建和写入功能。

接下来,我们去实现文件的创建和写入功能。这里需要用java.io.FileWriter类。我们通过这个类来创建一个writer对象,来将具体的日志内容写入指定的文件。

import java.io.{File, FileWriter}

object i1104 {
/*  实现一个日志类:Logger
  1.把一些操作信息写入到文本文件中。
  2.实现单例模式。*/

  class Logger(filename:String) {
    def log(content:String) :Unit = {
//把内容写入到一个文件中
      val writer = new FileWriter(filename,true)
      writer.write(content + "\n")
      writer.close()
//      println(s"${content}")
    }

  }

  object  Logger {
// 定义一个对象
    var instance:Option[Logger] = None
    def apply(fliename:String):Logger = {
      if(instance.isEmpty){
        instance = Some(new Logger(fliename))
      }
      instance.get // 获取到具体的对象 如果为None 也不会报错
    }

  }

  def main(args: Array[String]): Unit = {
    val logger1 = Logger("test.log")
//    val logger2 = Logger("test.log")
//  println(logger2==logger1)
    logger1.log("2005-11-4 09:06:03 上scala课")
    logger1.log("2005-11-5 09:06:03 运动会")
    logger1.log("2005-11-6 09:06:03 休息")
  }

运行结果:

Snipaste_2025-11-04_09-31-38.png