아요 개발 일기

[급할수록 돌아가자] 개념 정리 노트 본문

iOS/급할수록 돌아가자🤔

[급할수록 돌아가자] 개념 정리 노트

소진이 2024. 9. 7. 20:54

안녕하세요!

오랜만입니다 ㅎㅎ..

이번에는 새로운 기술이 아닌 기초 개념들에대해서 가지고 왔어요.

기초 개념에대해 제가 부족하다는 것을 느끼고 문서도 보고 GPT에도 물어보면서

제 나름대로 정리해보았습니다.

 

급할수록 돌아가자 카테고리는

제가 부족함을 느낄때마다 특정 부분의 개념들을 정리해서 올릴 것 같습니다.

개념에대해 글로적어내는 과정에서 독자?분들이 보시기에 다소 엉뚱한 질문들이 있을 수 있습니다.

부족함을 인정하고 스스로 해답을 찾으며 더 단단히 개념을 이해하려고 합니다.

 

때문에 개념들이 정말 기초적인 부분일 수 있습니다ㅎㅎ

 

이 글들이 저와 같은 고민을 하여 다시 처음으로 되돌아가는분들이 있거나,

iOS 개발자 혹은 it 개발자로써 첫 걸음을 내딛는 분들에게 도움이 되었으면 좋겠습니다.

 

서론이 많이 길었네요ㅎㅎ

아 그리고

친구에게 편하게 설명하는 느낌으로 작성할꺼라

반말체를 사용하도록 하겠습니다..ㅎㅎ

 

불편하신 분들에게는 죄송합니다 ㅜ.ㅜ

 

이제 시작해보겠습니다!

 


 

Object(객체)가 뭐야?

 

swift가 객체 지향 프로그래밍(OOP)라고하는데,

객체는 뭘까?

 

객체란,

클래스(class)나 구조체(struct)를 기반으로 생성된 인스턴스입니다.

 

인스턴스요??...

 

객체와 인스턴스를 함께 코드로 이해해보자!!!

class Car {
    var color: String
    var speed: Int
    
    init(color: String, speed: Int) {
        self.color = color
        self.speed = speed
    }
    
    func drive() {
        print("The \(color) car is driving at \(speed) km/h.")
    }
}

// Car 클래스의 인스턴스 생성
let myCar = Car(color: "Green", speed: 100)
myCar.drive()

 

짠~~

인스턴스를 만드는 간단한 코드를 만들어보았어

주석 달아둔 부분을 보면

Car 클래스를 이용해서 myCar라는 인스턴스를 만들었지?

그렇다하면 여기서 객체는 무엇일까?!!!!

 

myCar라는 인스턴스겠징 ㅎㅎ

 

 

그래!

이제 객체랑 인스턴스는 알겠어..

그렇다면

 

클래스(Class)나 구조체(Struct)도 object(객체)라고 할 수 있어?

클래스(Class)와 구조체(Struct)는 객체를 만들기위한 "틀" 혹은 "설계도"라고 할 수 있고

이것들이 객체를 정의하고 생성하는데 사용되었잖아? (위 코드 블록 참고)

그럼 이것들도 객체라고도 부를 수 있지않을까?...

 

결론을 말하자면 객체라고 할 수 없어!!

객체는 클래스나 구조체를 기반으로 생성된 인스턴스를 의미해.

틀이나 설계도 역할을 하는거지 인스턴스는 생성이 안 되었으니까!!!

단독으로 객체라고 할 수 없는거지!

 


 

클래스(Class)와 구조체(Struct)에대해 알고싶어!

단순히 정의해볼게!

 

클래스(Class): 속성(Properties)와 메서드(Method)를 가질 수 있으며, 참조 타입(reference type)을 가지고 있다.

구조체(Struct): 속성(Properties)과 메서드(Method)를 가질 수 있으며, 값 차입(value type)을 가지고 있다.

 

라고 정의할 수 있는데,

만약 더 자세하게 알고 싶다면 내가 전에 따로 정리해 놓은 포스팅을 참고해줘!!

 

https://develop-ssooo.tistory.com/149

 

[Swift] Class - 클래스

Class 프로퍼티(클래스 안의 변수)와 메소드(클래스 안의 함수)를 가질 수 있는 컨테이너 타입을 정의하기위한 용도 일반적으로 단일 상속이 가능하지만, 프로토콜을 사용하면 다중 상속도 가능

develop-ssooo.tistory.com

https://develop-ssooo.tistory.com/150

 

[Swift] Struct - 구조체

Struct C 언어 구조체 용도와 비슷하지만, 추가로 멤버 변수(프로퍼티), 함수(메소드) 정의 가능 상속이 불가능 확장(extention) 등 기능 사용 가능 값 타입 (= Value Type) Swift의 대부분의 큰 뼈대는 모두

develop-ssooo.tistory.com

 

 

그런데 속성과 메서드를 잘 모르겠어🤷‍♀️🥺

그래! 같이 자세히 알아보쟈아

 


 

속성(Properties)

 

속성이란,

클래스나 구조체 내부에 정의된 변수로 객체의 상태나 특성을 나타내

클래스 인스턴스가 생성될 때 할당되고 그 인스턴스가 존재하는 동안 함께 존재하지

 

잠깐.. 헷갈리는데

속성(Properties)은 변수인건가?

우선 그럼 변수의 의미를 알아볼까?

 

변수란,

데이터를 저장하는 메모리 공간, 프로그램내에서 데이터를 조작하고 저장하기위한 기본 단위

함구나 메서드 내부에서 사용될 수 있으며 특정 연산이나 데이터를 임시로 저장하고 처리하는데 사용

 

그러니까 정리해보자면

 

변수는 클래스/구조체나 함수/메서드 내부에 정의된 것

속성은 클래스나 구조체에 정의된 것

 

이라 할 수 있어!

 

어?? 그러면

속성은 변수일 수도 있는거 아니야?

맞아!!

 

그렇다면 변수는 속성일 수 있을까??

이건 아니야!

함수 내부에 있는 변수는 지역 변수라서 속성이 아니거든ㅎㅎ

 


 

메서드(Method)

메서드란,

클래스, 구조체 또는 열거형 내부에 정의된 함수로

객체의 속성에 접근하거나, 객체가 특정 동작을 정의

 

메서드는 아래와 같이 두가지로 구분될 수 있어

 

1. 인스턴스 메서드(Instance Method)

 

- 특정 객체(인스턴스)에 속하는 메소드

-해당 객체의 속성에 접근하거나 그 속성을 변경할 수 있음

 

 

2. 타입 메서드(type Method)

 

- 클래스나 구조체 자체에 속하는 메서드

- 특정 인스턴스가 아니라 클래스나 구조체 전체에대해 동작 함

- swift에서는 "static" 키워드를 사용하여 메서드를 정의할 수 있음

클래스에서는 "class" 키워드를 이용해 타입 메서드를 재정의(override)할 수 있음

 

 

 

어? 근데.. 만약에

A클래스에서 인스턴스를 생성했어,

A클래스 내부에 B라는 함수가 존재한다 했을때

B라는 함수는 인스턴스 메서드이면서 타입 메서드 일 수 있는거야?

 

결론은! No!!

글보다는 코드로 보는게 더 이해가 쉬우니!!

같이 코드를 보쟈!!!

class A {
	var instanceProperty = 10
    
    func instanceMethod() {
    	...
    }
    
    static func typeMethod() {
   		...
    }
}

let instanceOfA = A() // 인스턴스 생성
instanceOfA.instanceMethod() // 인스턴스 메서드 호출
A.typeMethod() // 타입 메서드 호출

 

어때 코드를 보니까 이해가지!!?

 

즉!

인스턴스 메서드는 인스턴스가 있어야만 호출이 가능하고

타입 메서드는 인스턴스가 없어도 호출이 가능해!!!

 

그러니까 인스턴스 메서드이면서 타입 메서드가 있을리가 없지;;ㅎㅎㅎ...

 

 

인스턴스 메서드(InstanceMethod)랑 타입 메서드(Type Method)는

각각 어떤 상황에서 사용하는게 좋을까?

 

 

인스턴스 메서드(InstanceMethod)

 

- 객체의 상태를 변경하거나 읽어야할때

- 인스턴스의 고유의 동작정의할때

- 객체간의 상호작용이 필요할때

 

class Car {
	var color: String
    var speed: Int
    
    init(color: String, speed: Int) {
    	self.color = color
        self.speed = speed
    }
    
    // 인스턴스 메서드
    func accelerate() {
    	speed += 10
    }
    
    // 인스턴스 메서드
    func brake() {
    	if speed >= 10 {
        	speed -= 10
        } else {
        	speed = 0
        }
    }
}

let myCar = Car(color: "Red", speed: 50)
myCar.accelerate()
myCar.brake()

 

 

타입 메서드(Type Method)

 

- 인스턴스와 무관한 동작을 정의할때

- 유틸리티 함수나 헬퍼 메서드를 만들때

- 팩토리 메서드를 구현할때(특정 조건에따라 인스턴스를 생성)

 

class MathUtility {
	static func add(_ a: Int, _ b: Int) -> Int {
    	return a + b
    }
    static func multiply(_ a: Int, _ b: Int) -> Int {
    	return a * b
    }
}

let sum = MathUtility.add(5,7) // 12
let product = MathUtility.multiply(4, 6) // 24

 

즉, 타입 메서드는

주로 계산이나 데이터 처리등 인스턴스 상태에 의존하지 않는 기능을 구현해!!

 

 

📱 스마트폰이라는 예시를 이용해서 쉽게 이해해볼까? 📱

 

인스턴스 메서드(Instance Method)

: 스마트폰 객체(클래스)는 call(), sendMessage() 같은 기능을 가질 수 있어

각 스마트폰 인스턴스는 각각 고유한 상태(배터리 상태, 연락처 등)를 가지며,

인스턴스 메서드는 이 상태를 기반으로 동작 해

 

타입 메서드(Type Method)

: 스마트폰 제조사 클래스가 maufactureName(), releaseYear()와 같은 정보를 제공할 수 있어

그러니까 특정 스마트폰 인스턴스와 무관하게 제조사 전체에 관련된 일을 처리 해

 

간단하게 정리하면!

 

각각의 휴대폰 배터리, 연락처 정보, 메세지 정보

-> 인스턴스 메소드

 

휴대폰의 이름, 출시년도

-> 타입메서드

 

어때! 이해가지!!!


 

타입 메서드는

유틸리티 함수, 헬퍼 함수, 팩토리 메서드를 구현할때 사용하라고 되어있는데

그게 모야....

 

유틸리티 함수(Utility Function)

특정 클래스나 객체와 독립적으로, 일반적인 작업을 수행하는 함수

이 함수들은 주로 여러 곳에서 반복적으로 사용되는 간단한 작업들을 처리하는데 사용됨

 

struct MathUtilities {
    static func add(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
    
    static func max(_ a: Int, _ b: Int) -> Int {
        return a > b ? a : b
    }
}

// 유틸리티 함수 사용
let sum = MathUtilities.add(10, 20)  // 30
let maxValue = MathUtilities.max(10, 20)  // 20

 

 

주로 수학 연산(예: 최대값, 최소값 계산), 문자열 처리, 형 변환 등에 사용되!

 

주의할 점 및 단점

  • 과도한 전역 상태: 유틸리티 함수가 전역 상태(글로벌 변수)를 사용하게 되면, 프로그램의 다른 부분에서 예상치 못한 동작을 초래할 수 있음. 유틸리티 함수는 상태가 없는(stateless) 것이 이상적입니다.
  • 남용 위험: 너무 많은 유틸리티 함수가 코드의 다른 부분에 퍼져 있을 경우, 코드의 유지보수성이 떨어질 수 있습니다. 중요한 로직이 유틸리티 함수로 분산되면, 로직을 파악하는 데 시간이 더 걸릴 수 있습니다.
  • 응집도 낮음: 유틸리티 함수가 너무 범용적으로 설계되면, 함수가 다양한 작업을 수행하게 되어 응집도가 떨어질 수 있습니다. 응집도란 관련 있는 기능들이 하나의 모듈(또는 함수)에 잘 모여 있는지를 나타내는 지표입니다.

 


 

헬퍼 메서드(Helper Method)

주로 복잡한 작업을 지원하기 위해 내부적으로 사용되는 보조적인 메서드

헬퍼 메서드는 주로 다른 메서드에의해 호출되며, 특정 작업의 일부분을 처리하는데 도움을 줌

class StringFormatter {
    
    // 공개된 메서드
    func formatName(firstName: String, lastName: String) -> String {
        return "\(capitalize(firstName)) \(capitalize(lastName))"
    }
    
    // 헬퍼 메서드
    private func capitalize(_ string: String) -> String {
        return string.prefix(1).uppercased() + string.dropFirst().lowercased()
    }
}

// 헬퍼 메서드를 통해 포맷팅된 이름 생성
let formatter = StringFormatter()
let formattedName = formatter.formatName(firstName: "kim", lastName: "SOJIN")
// "Sojin Kim" 출력

 

주로 데이터를 검증하는 메서드, 복잡한 로직의 일부를 처리하는 메서드에 사용됨

 

주의할 점 및 단점:

  • 과도한 캡슐화: 헬퍼 메서드를 너무 많이 사용하여 내부 로직을 지나치게 캡슐화하면, 코드가 과도하게 분리되어 메인 로직의 흐름을 파악하기 어려울 수 있습니다.
  • 의존성 증가: 헬퍼 메서드가 서로를 많이 참조하게 되면, 한 메서드를 수정할 때 다른 메서드들도 영향을 받을 수 있습니다.
  • 테스트 어려움: 헬퍼 메서드는 종종 private으로 선언되므로, 단위 테스트에서 직접적으로 테스트하기 어렵습니다. 따라서 헬퍼 메서드가 복잡해지면, 관련 메서드 전체를 테스트해야 할 수 있습니다.

 


 

팩토리 메서드(Factory Method)

객체를 생성하는 로직을 캡슐화한 메서드

객체 과정이 복잡하거나, 다양한 하위 클래스의 인스턴스를 생성해야하는 경우에 사용

객체 생성자(init)대신 사용될 수 있음

 

class Button {
    var title: String
    
    init(title: String) {
        self.title = title
    }
    
    func click() {
        print("\(title) button clicked")
    }
}

class ButtonFactory {
    
    static func createButton(for type: String) -> Button? {
        switch type {
        case "OK":
            return Button(title: "OK")
        case "Cancel":
            return Button(title: "Cancel")
        default:
            return nil
        }
    }
}

// 팩토리 메서드를 통해 버튼 생성
if let okButton = ButtonFactory.createButton(for: "OK") {
    okButton.click()  // "OK button clicked" 출력
}

 

주로 조건에따라 다른 객체를 반환하는 메서드, 객체 생성이 복잡한 경우 팩토리 메서드를 통해 간단히 객체 생성하는 곳에 사용되!

 

주의할 점 및 단점:

  • 복잡성 증가: 팩토리 메서드를 너무 많이 사용하거나, 불필요하게 사용하면 코드의 복잡성이 증가할 수 있습니다. 작은 프로젝트에서는 오히려 불필요한 복잡성을 초래할 수 있습니다.
  • 확장 시 위험: 팩토리 메서드에 조건문(예: switch 문)을 사용하여 다양한 객체를 생성하는 경우, 새로운 조건이 추가될 때마다 팩토리 메서드를 수정해야 할 수 있습니다. 이로 인해 코드가 점점 더 복잡해질 수 있습니다.
  • 추상화 과다: 너무 많은 추상화 레이어를 추가하면, 코드의 가독성과 이해도가 떨어질 수 있습니다. 간단한 객체 생성이 필요한 경우, 팩토리 메서드를 사용하는 것이 과도할 수 있습니다.

 

휴.. 꼬리에 꼬리를 무니까 너무 많아졌네요,,

급할수록 돌아가자 하면서 이전에 문법 정리했던 것들도 내용이 좀 빈약한 것 같애서 틈틈히 추가 좀 하려구요!!

할게 아주 많네요,,,

 

혹시 글을 보시고 이해 안 가는 부분이나 틀린 부분이 있다면 댓글 적어주세요!!

아주아주 환영입니다 ㅎㅎㅎ

길고 부족한 글 읽어주셔서 감사합니당 🙇🏻‍♀️