ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SwiftUI가 선언형이라는게 무슨말일까?
    Apple🍎/SwiftUI 2024. 6. 11. 11:30

     

    명령형 프로그래밍과 선언형 프로그래밍

    명령형 프로그래밍 (Imperative Programming)

    명령형 프로그래밍은 컴퓨터 프로그램을 상태와 상태 변화를 통해 기술하는 방식입니다. 프로그래머는 프로그램이 수행할 작업들을 순서대로 명령어로 기술하며, 각 명령어는 프로그램의 상태를 변경합니다. 대부분의 전통적인 프로그래밍 언어(C, C++, Java, Python 등)는 명령형 패러다임을 따릅니다.

    특징

    1. 절차 지향적: 작업을 수행하는 구체적인 절차를 명시합니다.
    2. 상태 관리: 프로그램의 상태를 변경하는 명령어를 통해 작업을 수행합니다.
    3. 제어 구조: 반복문, 조건문, 함수 호출 등을 사용하여 프로그램의 흐름을 제어합니다.
    4. 직관적 이해: 프로그램의 흐름을 직접 기술하므로 이해하기 쉽습니다.

    예제: Python으로 리스트의 합 계산

    # 작업을 수행하는 구체적인 절차를 명시 
    numbers = [1, 2, 3, 4, 5]
    sum = 0 # 상태를 선언하고 
    
    for number in numbers: # 조건문, 반복문, 함수호출 등을 이용하여 
        sum += number # 상태를 변경하면서 작업을 수행 
    
    print(sum)  # 출력: 15

     

    선언형 프로그래밍

    선언형 프로그래밍은 무엇을 해야 하는지(결과)를 기술하고, 어떻게 수행할지는 시스템에 맡기는 방식입니다. 프로그래머는 원하는 결과를 선언하며, 세부적인 수행 절차는 기술하지 않습니다. 대표적인 선언형 언어로는 SQL, HTML, 그리고 SwiftUI 등이 있습니다.

    특징

    1. 결과 지향적: 원하는 결과를 선언하며, 수행 절차를 명시하지 않습니다.
    2. 상태 변화 없음: 상태 변화 없이 결과를 기술합니다.
    3. 고수준의 추상화: 수행 방법이 아닌 결과를 중심으로 코드를 작성합니다.
    4. 간결성: 코드가 간결하고 이해하기 쉽습니다.

    예제: SQL로 데이터베이스에서 특정 조건을 만족하는 레코드 조회

    // 어떻게 테이블에서 각 값들을 가져오는지에 대한 방법에 대한 기술은 없이 
    // 테이블로부터 가져와야할 값의 결과값들의 형태를 명시 
    SELECT name, age FROM users WHERE age > 30;

     

    명령형 프로그래밍과 선언형 프로그래밍의 비교

    명령형 프로그래밍은 ‘어떻게 해야하는지’ 방법을 명시하고 선언형 프로그래밍은 ‘어떻게 되어야하는지’ 결과를 명시한다.


    특징 명령형 프로그래밍 선언형 프로그래밍
    접근 방식 절차 지향적 결과 지향적
    상태 관리 명령어를 통해 상태를 직접 변경 상태 변화 없이 결과만 선언
    코드의 복잡성 비교적 복잡하며, 제어 구조가 많이 필요 간결하며, 고수준의 추상화로 인해 이해하기 쉬움
    사용 사례 시스템 프로그래밍, 게임 개발, 알고리즘 구현 등 데이터베이스 쿼리, UI 선언, 설정 파일 등
    학습 곡선 초기 학습이 비교적 쉬움 초기 학습이 어려울 수 있으나, 익숙해지면 간편함
    장점 프로그램의 흐름을 직접 제어할 수 있어 직관적, 다양한 제어 구조를 활용한 복잡한 로직을 구현 가능 코드가 간결하고 , 높은 수준의 추상화를 통해 이해가 쉬움, 상태 변화 없이 결과만 기술하므로 코드가 더욱 견고하고 예측가능함,
    단점 코드가 장황해져 유지보수가 어려울 가능성 , 상태 변화를 관리하는 데 있어 주의 필요 복잡한 로직을 표현하는데 있어 한계가 있을 가능성

     

    SwiftUI는 선언적 Framework이다.

    • SwiftUI가 선언적이라는 것은, 프로그래머가 무엇을 해야 할지를 일련의 명령으로 기술하는 것이 아니라, 최종 상태를 선언함으로써 인터페이스를 정의하는 것을 의미합니다.
    • 어떤 방식으로 인터페이스를 구성해야 하는지 절차를 구체적으로 명시하는 것이 아니라, 인터페이스가 최종적으로 어떤 모양을 띠어야 하는지에 대해 정의합니다.
    • 이에 반해, UIKit은 명령형 프로그래밍 접근 방식을 사용합니다.

     

    UIKit 과 SwiftUI 비교 : 버튼을 만들어 클릭할 때 레이블의 텍스트를 변경하는 코드

    UIKit에서 기능을 구현한 코드

    import UIKit
    
    class ViewController: UIViewController {
    
        var label: UILabel!
        var button: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // 레이블 생성
            label = UILabel()
            label.text = "Hello, World!"
            label.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(label)
    
            // 버튼 생성
            button = UIButton(type: .system)
            button.setTitle("Tap me", for: .normal)
            button.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(button)
    
            // 버튼에 액션 추가
            button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    
            // 오토 레이아웃 설정
            NSLayoutConstraint.activate([
                label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                button.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 20)
            ])
        }
    
        @objc func buttonTapped() {
            label.text = "Button tapped!"
        }
    }
    • 버튼을 눌렀을 때 버튼의 텍스틀 바꾸기 위해서 UIKit에서는
    • UILabel을 구성하는 방법을 구체적으로 명시한다.
      • UILabel 인스턴스를 만들고
      • 해당 인스턴스가 보여줄 텍스트를 할당하고
      • label의 위치를 조정하는 방법을 선택하고
      • ViewControllerview에 구성한 UILabel을 추가한다.
    • UIButton을 구성하는 방법을 구체적으로 명시한다.
      • UIButton 인스턴스를 만들고
      • 해당 버튼이 보여줄 텍스트를 할당하고
      • button의 위치를 조정하는 방법을 선택하고
      • ViewControllerview에 구성한 UIButton 을 추가한다.
      • @objc 메서드를 통해 동작을 명시하고
      • addTarget을 통해 앞서 만든 버튼이 해야할 동작을 연결해준다.

    -> UILabelUIButton을 구성하는 절차부터 버튼의 동작까지 하나하나 구체적으로 명시해 주었다.

     

    SwiftUI에서 동일한 기능을 구현한 코드

    import SwiftUI
    
    struct ContentView: View {
        @State private var labelText: String = "Hello, World!"
    
        var body: some View {
            VStack {
                Text(labelText)
                Button(action: {
                    labelText = "Button tapped!"
                }) {
                    Text("Tap me")
                }
            }
            .padding()
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    • Text와 Button을 어떠한 방법으로 구성해야지에 대한 방법을 명시하지 않았다.
    • 앞서 UIKit에서는 UILabel 인스턴스 자체가 text 의 상태값을 가지고 있었고 , text의 상태값을 변경하는 방법을 메서드로 명시하고 해당 메서드를 버튼에 연결함으로써 기능을 수행하였다면
    • SwiftUI에서는 Text나 Button을 이용해 각각의 컴포넌트가 화면에서 어떻게 나타나야하는지에 대한 결과만 명시하였다. 또한 각 컴포넌트는 상태값을 별도로 가지고 있지 않고 View 내부에서 관리하도록 함으로써 상태값의 변화가 생겼을 때 이를 Framework에서는 알아서 각각의 컴포넌트에 업데이트하도록 하였다.

    차이점 설명

    1. UI 구성 방식:
      • UIKit: 명령형 프로그래밍으로, UI 컴포넌트를 하나씩 만들고, 부모 뷰에 추가하며, 레이아웃 제약을 설정합니다. 또한 버튼 클릭 시 실행될 액션 메서드를 정의하고, 버튼에 해당 액션을 추가합니다.
      • SwiftUI: 선언형 프로그래밍으로, body 속성 안에 UI 컴포넌트를 선언하여 원하는 상태를 직접 기술합니다. 레이아웃은 VStack 등의 레이아웃 도구로 간편하게 구성할 수 있습니다.
    2. 상태 관리:
      • UIKit: 레이블의 텍스트 변경을 위해 직접 label.text 속성을 업데이트하는 명령을 추가합니다.
      • SwiftUI: 상태 변수(@State)를 사용하여 UI 상태를 관리합니다. 상태가 변경되면 SwiftUI가 자동으로 UI를 업데이트합니다.
    3. 코드의 간결함:
      • SwiftUI는 선언적으로 UI와 상태 관리를 한 번에 처리하기 때문에 코드가 더 간결하고 이해하기 쉽습니다.
      • UIKit에서는 UI 구성과 상태 관리를 분리해서 처리해야 하므로 코드가 더 길고 복잡해질 수 있습니다.

     

     

    댓글

Designed by Tistory.