ETC/Auto Hotkey

고급 스크립팅: 함수, 객체, 클래스를 활용한 코드 구조화와 재사용성 향상

shimdh 2025. 2. 5. 10:11
728x90

1. 함수: 코드의 재사용성과 가독성 향상

함수는 특정 작업을 수행하는 코드 블록으로, 필요할 때마다 호출하여 사용할 수 있습니다. 함수를 사용하면 중복 코드를 줄이고, 코드의 가독성을 높이며, 프로그램 구조를 명확하게 만들 수 있습니다.

1.1 함수의 기본 문법과 예제

함수는 FunctionName(Parameters) 형식으로 정의됩니다. 아래는 간단한 예제입니다:

MyFunction(param1, param2) {
    result := param1 + param2
    return result
}

result := MyFunction(5, 10)
MsgBox % "The sum is: " . result   ; 메시지 박스에 결과 출력

위 예제에서 MyFunction은 두 개의 매개변수를 받아 합계를 반환하는 함수입니다. 이렇게 함수를 사용하면 동일한 코드를 반복해서 작성하지 않아도 됩니다.

1.2 지역 변수와 전역 변수

함수 내에서 선언된 변수는 기본적으로 지역 변수로, 함수 외부에서는 접근할 수 없습니다. 이를 통해 변수 충돌을 방지할 수 있습니다.

GlobalVar := "I am global"

MyFunction() {
    LocalVar := "I am local"
    MsgBox % LocalVar   ; 정상적으로 작동 (지역변수)
}

MsgBox % GlobalVar     ; 정상적으로 작동 (전역변수)
; MsgBox % LocalVar     ; 오류 발생 (지역변수에 접근 불가)

1.3 매개변수 기본값 설정

함수의 매개변수에 기본값을 설정할 수 있습니다. 이는 매개변수가 제공되지 않았을 때 유용합니다.

Greet(name = "Guest") {
    MsgBox % "Hello, " . name . "! Welcome!"
}

Greet("Alice")   ; Hello, Alice! Welcome!
Greet()          ; Hello, Guest! Welcome!

위 예제에서 Greet 함수는 이름을 매개변수로 받지만, 이름이 제공되지 않으면 기본값인 "Guest"를 사용합니다.

1.4 여러 값 반환하기

함수는 단일 값을 반환하지만, 배열이나 객체를 사용하여 여러 값을 반환할 수도 있습니다.

GetCoordinates() {
    return [100, 200]   ; 배열 형태로 두 개의 좌표값 반환 
}

coords := GetCoordinates()
MsgBox % "X: " . coords[1] . ", Y: " . coords[2]

위 예제에서는 좌표값을 배열 형태로 반환하고 있으며, 각각 X와 Y좌표를 표시합니다.


2. 객체: 데이터와 기능의 구조화

객체는 속성과 메서드를 포함하는 데이터 구조로, 코드를 더 조직적이고 효율적으로 만들 수 있습니다. 객체를 사용하면 복잡한 데이터를 쉽게 관리할 수 있습니다.

2.1 객체 생성과 메서드 추가

myCar := Object()
myCar.color := "Red"
myCar.model := "Toyota"

myCar.Drive := Func("DriveFunction")

DriveFunction() {
    MsgBox % "The car is driving."
}

myCar.Drive()   ; 메시지 박스에 "The car is driving." 출력

위 예제에서 myCar 객체는 색상과 모델 속성을 가지며, Drive 메서드를 통해 주행 기능을 수행합니다.

2.2 객체의 활용 사례

객체는 대량의 데이터를 다룰 때 매우 유용합니다. 예를 들어, 사용자 정보를 관리하는 객체를 만들어보겠습니다.

user := Object()
user.name := "Alice"
user.age := 30
user.ShowInfo := Func("ShowUserInfo")

ShowUserInfo() {
    MsgBox % "Name: " . this.name . ", Age: " . this.age
}

user.ShowInfo()   ; 메시지 박스에 "Name: Alice, Age: 30" 출력

위 예제에서 user 객체는 이름과 나이 속성을 가지며, ShowInfo 메서드를 통해 사용자 정보를 표시합니다.


3. 클래스: 객체 지향 프로그래밍의 핵심

클래스는 객체를 생성하기 위한 템플릿으로, 관련된 데이터와 기능을 그룹화하여 코드의 재사용성과 조직화를 향상시킵니다.

3.1 클래스 정의와 인스턴스 생성

class Car {
    ; 속성
    Color := ""
    Model := ""

    ; 생성자
    __New(color, model) {
        this.Color := color
        this.Model := model
    }

    ; 메서드
    Drive() {
        MsgBox % "The " this.Color " " this.Model " is driving."
    }

    Stop() {
        MsgBox % "The " this.Color " " this.Model " has stopped."
    }
}

myCar := new Car("Red", "Toyota")
myCar.Drive()   ; 메시지 박스에 "The Red Toyota is driving." 출력
myCar.Stop()    ; 메시지 박스에 "The Red Toyota has stopped." 출력

위 예제에서 Car 클래스는 색상과 모델 속성을 가지며, 주행과 정지 기능을 제공합니다. 클래스를 사용하면 동일한 구조의 객체를 쉽게 생성할 수 있습니다.

3.2 상속을 통한 기능 확장

클래스는 상속을 통해 기존 클래스의 기능을 확장할 수 있습니다. 예를 들어, 전기차 클래스를 만들어보겠습니다.

class ElectricCar extends Car {
    BatteryLevel := 100

    Charge() {
        MsgBox % "Charging the battery to full!"
        this.BatteryLevel := 100
    }
}

myElectricCar := new ElectricCar("Blue", "Tesla")
myElectricCar.Drive()   ; 메시지 박스에 "The Blue Tesla is driving." 출력
myElectricCar.Charge()  ; 메시지 박스에 "Charging the battery to full!" 출력

ElectricCar 클래스는 Car 클래스를 상속받아 배터리 충전 기능을 추가했습니다.

3.3 캡슐화: 데이터 보호와 안정성 향상

캡슐화는 객체 내부의 데이터와 메서드를 외부에서 직접 접근하지 못하도록 보호하는 개념입니다. 이를 통해 데이터의 안정성을 높일 수 있습니다.

class SecureAccount {
private:
   Balance := 0

public:
   Deposit(amount) {
       if (amount > 0) {
           this.Balance += amount
           MsgBox % amount " deposited."
       } else {
           MsgBox % "Invalid deposit amount."
       }
   }

   GetBalance() {
       return this.Balance
   }
}

account := new SecureAccount()
account.Deposit(100)   ; 메시지 박스에 "100 deposited." 출력
MsgBox % "Current Balance: " . account.GetBalance()   ; 메시지 박스에 "Current Balance: 100" 출력

위 예제에서 SecureAccount 클래스는 잔액을 private으로 설정하여 외부에서 직접 수정할 수 없도록 보호합니다. 대신 입금 및 잔액 조회 메서드를 통해 안전하게 작업할 수 있습니다.


4. 고급 활용: 함수, 객체, 클래스의 통합

함수, 객체, 클래스를 함께 사용하면 더 강력한 스크립트를 작성할 수 있습니다. 예를 들어, 사용자 관리 시스템을 만들어보겠습니다.

class User {
    name := ""
    age := 0

    __New(name, age) {
        this.name := name
        this.age := age
    }

    ShowInfo() {
        MsgBox % "Name: " . this.name . ", Age: " . this.age
    }
}

users := []

AddUser(name, age) {
    user := new User(name, age)
    users.Push(user)
}

ShowAllUsers() {
    for index, user in users {
        user.ShowInfo()
    }
}

AddUser("Alice", 30)
AddUser("Bob", 25)
ShowAllUsers()   ; 각 사용자의 정보를 메시지 박스로 출력

위 예제에서는 User 클래스를 정의하고, AddUser 함수를 통해 사용자를 추가하며, ShowAllUsers 함수를 통해 모든 사용자의 정보를 표시합니다.


5. 심화 예제: 게임 캐릭터 관리 시스템

함수, 객체, 클래스를 활용하여 간단한 게임 캐릭터 관리 시스템을 만들어보겠습니다. 이 시스템은 캐릭터의 생성, 정보 표시, 경험치 추가 등의 기능을 제공합니다.

5.1 캐릭터 클래스 정의

class Character {
    name := ""
    level := 1
    experience := 0

    __New(name) {
        this.name := name
    }

    ShowInfo() {
        MsgBox % "Name: " . this.name . ", Level: " . this.level . ", Experience: " . this.experience
    }

    AddExperience(amount) {
        this.experience += amount
        if (this.experience >= 100) {
            this.level += 1
            this.experience := 0
            MsgBox % this.name . " has leveled up to level " . this.level . "!"
        }
    }
}

characters := []

CreateCharacter(name) {
    character := new Character(name)
    characters.Push(character)
    MsgBox % "Character " . name . " created!"
}

ShowAllCharacters() {
    for index, character in characters {
        character.ShowInfo()
    }
}

AddExperienceToCharacter(name, amount) {
    for index, character in characters {
        if (character.name == name) {
            character.AddExperience(amount)
            return
        }
    }
    MsgBox % "Character " . name . " not found!"
}

CreateCharacter("Alice")
CreateCharacter("Bob")

AddExperienceToCharacter("Alice", 50)
AddExperienceToCharacter("Bob", 120)

ShowAllCharacters()   ; 각 캐릭터의 정보를 메시지 박스로 출력

위 예제에서는 Character 클래스를 정의하고, CreateCharacter 함수를 통해 캐릭터를 생성하며, AddExperienceToCharacter 함수를 통해 캐릭터의 경험치를 추가합니다. 또한, ShowAllCharacters 함수를 통해 모든 캐릭터의 정보를 표시합니다.


6. 디자인 패턴: 싱글톤 패턴

싱글톤 패턴은 클래스의 인스턴스가 하나만 생성되도록 보장하는 디자인 패턴입니다. 이는 전역 상태를 관리하거나 리소스를 공유할 때 유용합니다.

6.1 싱글톤 패턴 예제

class Singleton {
    static instance := ""

    __New() {
        if (this.instance == "") {
            this.instance := this
        } else {
            return this.instance
        }
    }

    ShowMessage() {
        MsgBox % "This is a singleton instance."
    }
}

singleton1 := new Singleton()
singleton2 := new Singleton()

singleton1.ShowMessage()   ; 메시지 박스에 "This is a singleton instance." 출력
singleton2.ShowMessage()   ; 동일한 메시지 박스 출력

MsgBox % (singleton1 == singleton2) ? "Same instance" : "Different instances"   ; "Same instance" 출력

위 예제에서는 Singleton 클래스를 정의하고, __New 메서드를 통해 인스턴스가 하나만 생성되도록 보장합니다. 이를 통해 singleton1singleton2는 동일한 인스턴스를 참조합니다.


결론

함수, 객체, 클래스는 AutoHotkey 스크립팅에서 코드의 재사용성과 가독성을 높이는 핵심 도구입니다. 함수를 사용하면 반복적인 작업을 효율적으로 처리할 수 있고, 객체와 클래스를 사용하면 데이터와 기능을 구조화하여 복잡한 프로그램을 쉽게 관리할 수 있습니다. 이러한 개념들을 적절히 활용하면 스크립트의 품질과 유지보수성이 크게 향상될 것입니다.

728x90