单例模式-日志类

46 阅读3分钟

让某个类只有一个对象

package level02

object class07 {
  /**
   *伴生类和伴生对象 实现一种特殊的编程的模式:单列模式
   *
   * 单列模式:让一个类只能有一个实例对象 一个类只能被 new 一次!
   *
   *  特点:可以相互访问对象的私有成员
   */

  // 1.把构造函数设置为private
    class Student private() {
  }

  // 2.伴生对象中 访问private
  object Student {
    private val instance = new Student() // 在伴生对象中可以访问private修饰的构造器

    def getInstance(): Student = {
      instance
    }
  }

  def main(args: Array[String]): Unit = {
    //val stu1 = new Student()
    //val stu2 = new Student()
    //println(stu1 = =stu2) // false

    val stu1 = Student.getInstance()
    val stu2 = Student.getInstance()

    println(stu1 == stu2) //true
  }

}
package level02

object class05 {
//  object 对象名 {
//    属性;
//    方法....
//  }
  // 单例对象
  // 只有一个 不能被new
  // 适用于存放工具方法 常量
  object Mytool {
    // 属性
    val PI = 3.14

    // 方法
    def Area(r:Double):Double = {
      PI * r * r
    }
  }

  def main(args: Array[String]): Unit = {
    // 对象.属性名
    // 对象.方法名

    println( Mytool.PI)  // 3.14
    println( Mytool.Area(10) ) // 314
  }

}

单例模式案例-日志类

省略new

package level02

import java.io.FileWriter

object class08 {
  /**
   *伴生类和伴生对象
   *在伴生对象中补充一个apply方法 这样创建对象的时候 就可以省略 new
   * 伴生类名(参数) ==== 伴生对象名.apply(参数)
   */

  // 日志类
    class Logger(var filename:String) {
      def log(message:String):Unit = {
        // 把日志信息写入文件中
        val writer = new FileWriter(filename, true)
        writer.write(s"$message \n")
//        println(s"log: $message")
        writer.close()
      }
  }

  object Logger {
    private var instance: Option[Logger] = None
    def apply(filename:String):Logger = {
      if(instance.isEmpty) {
        instance = Some(new Logger(filename))
      }
      instance.get
    }
  }

  def main(args: Array[String]): Unit = {
    // 省略 new
    val log1 = Logger("test.log")

    log1.log("2025-11-03 上午第四节课")
    log1.log("2025-11-05 学校运动会")
    log1.log("2025-11-07 周末!!!")
  }

}
package level02

object base04 {
  /*
   * apply
   * apply方法写在伴生对象中,可以在创建对象的时候,省略new关键字
   *
   * val 对象 = 伴生类()  <====>  伴生对象.apply()
   **/
  class Person() {

  }

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

  def main(args: Array[String]): Unit = {
    // 创建一个类的对象
    //    val p1 = new Person()
    val p1 = Person() // 自动调用apply方法
    val p2 = Person()

    println(p1)
    println(p2)
  }
}

将↑代码变为单例对象

实现单例模式:

  • 在伴生对象中 创建一个对象,在apply方法中返回它
package level02

object base05 {
  /*
   * 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 = new Person()
    val p1 = Person() // 自动调用apply方法
    val p2 = Person()

    println(p1)
    println(p2)
  }
}
package level02

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

  class Logger(filename:String) {
    def log(content:String):Unit={
      println(s"${content}")
    }
  }
  
  object Logger {
    //定义一个对象
    var instance:Option[Logger] = None
    def apply(filename:String):Logger={
      if (instance.isEmpty){
        instance = Some(new Logger(filename))
      }
      instance.get
    }
  }

  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 运动会")
  }
}

image.png 写入文件中/写入日志

writer

package level02

import java.io.FileWriter

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

  class Logger(filename:String) {
    def log(content:String):Unit={
      //把内容写入一个文件中
      val writer =new FileWriter((filename,true))
      writer.write(content)
      writer.close()
      //println(s"${content}")
    }
  }
  object Logger {
    //定义一个对象
    var instance:Option[Logger] = None
    def apply(filename:String):Logger={
      if (instance.isEmpty){
        instance = Some(new Logger(filename))
      }
      instance.get
    }
  }
  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 休息")
  }
}

image.png