본문 바로가기
안드로이드

[Kotlin] 싱글턴 패턴

by 디지털노마더 2021. 1. 21.

개발을 하다보면, 수많은 클래스의 객체를 생성하는 일들이 많다.

하지만, 대부분 알고보면 똑같이 사용하는 객체를 무분별하게 반복적으로 생성하는 경우를 볼 수 있다.

 

계속해서 객체를 생성하게 되면, 불필요한 메모리를 낭비하게 된다.

왜냐하면 신규 객체 생성 시, CPU에서 일정한 메모리를 할당하게 되기 때문이다.

 

하나의 객체를 생성하여 여기저기서 반복해서 사용할 수 있는 패턴이 바로 "싱글턴 패턴(Singleton Pattern)"이다.

 

* Singleton 

  : 클래스의 인스턴스는 오직 하나임을 보장하며, 이 인스턴스에 접근할 수 있는 방법을 제공한다.

 

 

 

아래 코드는 MySQL 연결을 싱글턴 패턴으로 구현한 예제이다.

 

1. MySQLOpenHelperSingleton (Singleton 패턴으로 생성)

package com.dahami.kotlinexample01

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class MySQLOpenHelperSingleton private constructor(context: Context) : SQLiteOpenHelper(context, "MyDB", null, 1){

    val TAG: String = "로그"

    // 싱글턴 패턴
    // kotlin에는 전역 변수(static)가 없다.
    // companion object : 클래스 인스턴스 없이 특정 클래스 내부에 접근하고자 할 때 사용
    companion object {
        // 자기 자신 변수 선언
        @Volatile private var instance: MySQLOpenHelperSingleton? = null

        // 자기 자신 가져오기
        fun getInstance(context: Context) : MySQLOpenHelperSingleton =
            instance ?: synchronized(this) {
                instance ?: MySQLOpenHelperSingleton(context).also {
                    instance = it
                }
            }
    }

    override fun onCreate(db: SQLiteDatabase?) {
        TODO("Not yet implemented")
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        TODO("Not yet implemented")
    }
}

 

2. MainActivity.kt (싱글턴 패턴 객체 생성 및 주소값 동일한지 확인)

package com.dahami.kotlinexample01

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) /* -- 기존 방식 -- */

        val TAG = "로그"

        val mySQLOpenHelper_1 = MySQLOpenHelperSingleton.getInstance(this)
        val mySQLOpenHelper_2 = MySQLOpenHelperSingleton.getInstance(this)


        Log.d(TAG, "MainActivity - mySQLHelper_1 : ${mySQLOpenHelper_1}")
        Log.d(TAG, "MainActivity - mySQLHelper_2 : ${mySQLOpenHelper_2}")
    }
}

 

<결과>

 동일한 주소값을 참조하고 있는 것을 볼 수 있다.

 

댓글