Menu
Coddy logo textTech

싱글톤 테이블

Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 63번째.

때때로 프로그램 전체에서 설정 관리자, 로깅 시스템 또는 게임 설정과 같이 정확히 하나의 인스턴스만 필요한 경우가 있습니다. 여러 개의 복사본을 생성하면 어떤 것이 올바른 데이터를 가지고 있는지와 같은 문제가 발생할 수 있습니다. 싱글톤 패턴(Singleton pattern)은 오직 하나의 인스턴스만 존재하도록 보장합니다.

Lua에서 싱글톤(Singleton)을 구현하는 것은 모듈이 작동하는 방식 덕분에 놀라울 정도로 간단합니다. 모듈을 require하면, Lua는 그 결과를 캐시합니다. 이후 require를 호출하면 새로운 테이블이 아닌 캐시된 테이블을 반환합니다.

-- GameConfig.lua
local GameConfig = {
    volume = 80,
    difficulty = "normal"
}

function GameConfig:setVolume(v)
    self.volume = v
end

return GameConfig

이제 프로그램의 어느 곳에서나:

local config1 = require("GameConfig")
local config2 = require("GameConfig")

config1:setVolume(50)
print(config2.volume)  -- 50 (같은 테이블입니다!)

config1config2 모두 정확히 동일한 테이블을 참조합니다. 한 변수를 통해 변경된 사항은 다른 변수를 통해서도 확인할 수 있습니다. 이는 Lua의 require가 반환된 값을 package.loaded에 저장하고 이를 재사용하기 때문에 자동으로 발생합니다.

새로운 객체를 생성하는 Factory 패턴과 달리, Singleton은 애플리케이션 전체에서 공유 상태를 보장합니다. 이는 코드의 여러 부분에서 일관되게 액세스하고 수정해야 하는 전역 설정에 이상적입니다.

challenge icon

챌린지

쉬움

싱글톤(Singleton) 패턴을 사용하여 게임 설정 관리자를 만들어 봅시다! 프로그램의 어느 부분에서 호출하더라도 정확히 동일한 설정에 접근할 수 있도록 보장하는 설정 모듈을 만들게 됩니다.

코드는 다음 두 개의 파일로 구성됩니다:

  • GameSettings.lua: 게임 구성을 저장하는 싱글톤 모듈을 만듭니다. 설정 테이블에는 musicVolume (초기값 70), sfxVolume (초기값 100), 그리고 difficulty (초기값 "normal")가 포함되어야 합니다. 이 설정들을 수정하기 위해 :setMusicVolume(value), :setSfxVolume(value), :setDifficulty(level) 세 가지 메서드를 추가하세요. 모듈의 마지막에는 반드시 테이블을 반환해야 합니다!
  • main.lua: GameSettings 모듈을 서로 다른 두 변수에 require하여 싱글톤이 작동하는지 증명합니다. 첫 번째 변수를 사용하여 음악 볼륨과 난이도를 변경하세요. 그런 다음 두 번째 변수를 사용하여 세 가지 설정을 모두 출력합니다. 싱글톤이 올바르게 작동한다면 두 변수 모두 동일한 테이블을 참조하므로, 한 변수를 통해 변경한 내용이 다른 변수에서도 확인되어야 합니다.

두 개의 입력을 받게 됩니다:

  1. 새로운 음악 볼륨 (숫자)
  2. 새로운 난이도 레벨 ("easy" 또는 "hard"와 같은 문자열)

첫 번째 변수를 통해 설정을 수정한 후, 두 번째 변수를 사용하여 세 가지 설정을 음악 볼륨, SFX 볼륨, 난이도 순서대로 각각 한 줄씩 출력하세요.

예를 들어, 입력값이 50hard라면 출력은 다음과 같아야 합니다:

50
100
hard

입력값이 25easy라면 출력은 다음과 같아야 합니다:

25
100
easy

SFX 볼륨은 변경하지 않았으므로 기본값인 100으로 유지되지만, 음악 볼륨과 난이도는 첫 번째 변수를 통해 변경된 내용이 반영됩니다. 이는 두 변수가 모두 동일한 싱글톤 인스턴스를 가리키고 있음을 증명합니다!

치트 시트

싱글톤 패턴(Singleton pattern)은 프로그램 전체에서 객체의 인스턴스가 단 하나만 존재하도록 보장합니다. 이는 여러 인스턴스가 데이터 불일치를 유발할 수 있는 설정 관리자, 로깅 시스템 또는 게임 설정 등에 유용합니다.

Lua에서 싱글톤 패턴은 모듈 시스템을 통해 자연스럽게 구현됩니다. 모듈을 require하면 Lua는 그 결과를 package.loaded에 캐싱합니다. 이후 require를 호출하면 새로운 테이블이 아닌 동일한 캐시된 테이블을 반환합니다.

싱글톤 모듈 만들기:

-- GameConfig.lua
local GameConfig = {
    volume = 80,
    difficulty = "normal"
}

function GameConfig:setVolume(v)
    self.volume = v
end

return GameConfig

싱글톤 사용하기:

local config1 = require("GameConfig")
local config2 = require("GameConfig")

config1:setVolume(50)
print(config2.volume)  -- 50 (동일한 테이블!)

config1config2 모두 정확히 동일한 테이블을 참조합니다. 한 변수를 통해 변경된 사항은 다른 변수에서도 즉시 확인할 수 있으며, 이를 통해 애플리케이션 전체에서 공유된 상태를 보장합니다.

싱글톤 패턴은 팩토리 패턴(Factory pattern)과 다릅니다. 팩토리는 새로운 객체를 생성하는 반면, 싱글톤은 일관된 상태를 가진 단일 공유 인스턴스를 보장합니다.

직접 해보기

-- main.lua - 싱글톤 패턴 시연

-- 입력 읽기
local newMusicVolume = tonumber(io.read())
local newDifficulty = io.read()

-- TODO: GameSettings 모듈을 변수(예: settings1)로 불러오기

-- TODO: GameSettings 모듈을 다른 변수(예: settings2)로 다시 불러오기
-- (싱글톤이 올바르게 작동한다면, 두 변수는 동일한 테이블을 참조합니다!)

-- TODO: 첫 번째 변수를 사용하여 다음을 수행하세요:
--   - music volume을 newMusicVolume으로 설정
--   - difficulty를 newDifficulty로 설정

-- TODO: 두 번째 변수를 사용하여 설정을 출력하세요
-- 각 설정을 개별 줄에 출력: musicVolume, sfxVolume, difficulty
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨