Open sooohi opened 5 months ago
MVVM 패턴 Model + View + View Model
동작
특징
단점
ios 개발이 mvvm으로 넘어가는 이유
Data Binding, Command
MVC는 Model, View, Controller로 구성되어있다.
간단히 말하면 사람들 눈에 직접보이는 뷰위 모델이 있고 컨트롤러가 두 뷰의 데이터신호를 관리한다.
Model은 소프트웨어나 애플리케이션에서 정보 및 데이터 부분을 의미한다. 이는 Controller에게 받은 데이터를 조작(가공)하는 역할을 수행한다고 볼 수 있다
Controller(컨트롤러) Controller는 Model과 View 사이에서 데이터 흐름을 제어한다. 사용자가 접근한 URL에 따라 요청을 파악하고 URL에 적절한 Method를 호출하여 Service에서 비즈니스 로직을 처리한다. 이 후 결과를 Model에 저장하여 View에게 전달하는 역할을 수행한다
-그럼MVVM이란 무엇일까? MVC에서 C가 ViewModel로 바뀐것이다. 뷰 모델은 뷰가 데이터 바인딩되는 속성또는 명령을 구현하며 뷰의 상태변경을 알리는 역할을 한다.
-MVVM
View: 화면에 표시되는 구조, 레이아웃 및 모양을 정의
Model: 데이터를 가져오거나 저장하는 역할
ViewModel: 중재자 역할을 하면서 뷰가 데이터 바인딩될 수 있는 속성 및 명령을 구현
-MVVM 동작과정
1.사용자의 Action들은 View를 통해 들어옵니다. 2.View에 Action이 들어오면 ViewModel에 Action을 전달합니다. 3.ViewModel은 Model에게 데이터를 요청합니다. 4.Model은 ViewModel에게 요청받은 데이터를 응답합니다. 5.ViewModel은 응답 받은 데이터를 가공하여 저장합니다. 6.View는 Data Binding을 이용해 UI를 갱신시킵니다.
-MVVM 특징
View : ViewModel = 1 : n
관계로 되어있고 데이터 바인딩을 이용하면 의존성을 줄일 수 있는 장점이 있다.
-써야하는이유?
의존성이 적다(뷰와 뷰모델 사이를 데이터 바인딩하기 때문)
코드재사용가능(중복되는 부분을 모듈화해서 여러 뷰에 가져다 쓸수 있음)
Model: 데이터 구조 그 자체 ViewModel: 비즈니스 로직 모음집 View: UI 모음집
마치 디자이너와 개발자가 나뉘어 있는 것 처럼
View는 UI만 집중하여 상호작용 이벤트를 처리하고, 이를 ViewModel에 전달하여 해당 동작에 대한 비즈니스 로직을 실행 ViewModel은 데이터 가져오기, 변환, 가공, 상태관리 등의 작업을 수행하고 이러한 로직을 통해 View에 표시할 데이터를 적절히 가공하여 제공한다.
예시 1)
Model 모델
사용할 데이터를 정의
View 뷰
UI만 집중하여 로직, 함수가 필요한 경우 ViewModel의 함수를 호출하여 사용한다.
ViewModel 뷰모델
View에서 사용할 함수가 정의 되어있다.
예시 2)
모델
뷰
뷰모델
트랙어스 파일에서 View와 ViewModel을 나누어 놓았습니다. 각자 View에서 필요한 로직을 ViewModel에 정의하여 사용하면 좋을 것 같습니다..!
MVVM 패턴 Model + View + View Model
- 구조
- Model : 데이터를 다루는 부분. 화면을 표현하는데 필요한 데이터를 관리하며, 사용자가 입력한 데이터를 저장하거나 서버로 받은 데이터를 저장
- View : 사용자에게 보여지는 UI 부분. 사용자가 화면에서 보는 것들에 대한 구조 배치와 같이 외관에 해당
- View Model : View를 표현하기 위해 만들어진 View를 위한 Model. View에서 발생하는 이벤트를 감지하고, 해당 이벤트에 맞는 비즈니스 로직을 수행.
- 동작
- 사용자의 Action들은 View를 통해 들어�
- View에 Action이 들어오면, Command 패턴으로 View Model에 Action을 전달
- View Model은 Model에게 데이터를 요청
- Model은 View Model에게 요청 받은 데이터를 응답
- View Model은 응답 받은 데이터를 가공하여 저장
- View는 View Model과 Data Binding하여 UI를 갱신
- 특징
- Command 패턴과 Data Binding 두 가지 패턴을 사용하여 구현
- View와 View Model 사이 의존성을 없앰
- View Model과 View는 1:n 관계
- 장점
- View와 Moel 사이 의존성이 없어 독립성을 유지할 수 있음
- 독립성 유지하기 때문에 효율적인 유닛 테스트가 가능
- View와 ViewModel이 1:n 관계이기 때문에 중복되는 로직을 모듈화 하여 개발할 수 있음(코드 재사용이 가능)
- 단점
- View Model 설계가 복잡
- 데이터 바인딩으로 인한 메모리 소모가 있음
- 복잡해질수록 ViewModel이 비대해짐
- ios 개발이 mvvm으로 넘어가는 이유
- SwiftUI에서는 View가 Viewmodel을 소유하고, Viewmodel이 Model을 소유하여 구조적인 개선이 이루어짐
- ViewController가 View, Model의 역할까지 담당하는 UIKit 단점을 극복
- 모듈화로 인한 테스트가 편리해짐
- Data Binding, Command
- Data Binding : Model고 UI 요소 간의 싱크를 맞추는 패턴. View와 로직이 분리되어 잇어도 한 쪽이 바뀌면 다른 쪽도 업데이트가 이루어져 데이터의 일관성을 유지할 수 있음
- Command : 여러가지 요소에 대한 처리를 하나의 액션으로 처리할 수 있게 하는 기법
헷갈리는게 하나 있습니다 ViewModel과 View의 관계가
View : ViewModel = 1 : n ViewModel : View = 1 : n
둘 중 어떤 것 인가욤?
viewModel이 n이 맞지않을까요? 왜냐면 viewModel은 view를 알지못한다는게 특정 view에 대한 종속성이 없다는거라 일방적으로 viewModel을 끌어다쓰는 view가 1 viewModel이 n이지 않을까여(뇌피셜)
viewModel이 n이 맞지않을까요? 왜냐면 viewModel은 view를 알지못한다는게 특정 view에 대한 종속성이 없다는거라 일방적으로 viewModel을 끌어다쓰는 view가 1 viewModel이 n이지 않을까여(뇌피셜)
오..
아닌것도 같습니다... 쳐보니깐 1:1이라는 말도 ㅋㅋ 머리아프네요
MVVM 패턴은 다음과 같은 구성 요소
MVVM 패턴은 데이터 바인딩을 통해 View와 ViewModel을 연결하고, ViewModel과 Model을 연결하는 방식으로 동작
SwiftUI 선언형 UI 구조에서 data flow가 양방향으로 이루어진 mvvm 패턴과 단방향으로 이루어진 다른 아키텍처의 사용에 대해서 어떻게 생각하시나요?
SwiftUI에서 View는 자체적으로 Data Binding이 가능한 PropertyWrapper를 지원함.
SwiftUI에서는 뷰에서 데이터 바인딩을 통한 기능을 ViewModel에서 해주고 있지만
사실 View에서 @State 변수로 선언된 값은 모델값의 변경으로 인스턴스 값이 변경된다.
import SwiftUI
struct ContentView: View {
@State var person = Person()
var body: some View {
Text(person.name)
...
}
}
따라서 이미 SwiftUI에서는 View + ViewModel의 기능을 수행하고 있음.
생각보다 MVVM 패턴에 대해서 사람들의 인식이 바뀐 거 같아요. MVC, MVP 패턴에서 MVVM으로 당연하게 써오던 것들의 문제점과 단점들을 보완을 하는 TCA 같은 부분도 같이 공부하면 좋을 거 같습니다.
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app https://green1229.tistory.com/267
ViewModel과 View의 관계는 View가1 ViewModel이n라고 이해했습니다 주체를 누구로 보냐에 따라 달라지지만 보통 View를 주체로 보고 다수의 ViewModel에서 View로 코드를 재사용 하기 때문에 View가 여러ViewModel을 가져온다고 생각하면 될거같습니다. 다만 재사용성이 없는 코드에서는 1:1도 가능할거 같네요.
이런 경우도 있네요 ViewModel을 재사용하고, View형식이 같다면 View를 재사용하는 경우도 있기 때문에 M:N의 관계도 성립돼는군요 ㄷㄷ..
MVVM 패턴에 대한 기본적인 내용과 평소에 SwiftUI 에서 MVVM패턴을 이용하면서도 정확히 알지 못하거나 헷갈렸던 점들을 다시한번 정리해봤습니다.
디자인 패턴이란 개발을 할떄 조금더 효율적으로 또는 좋은 구조로 개발을 하기 위한 방법론? 약속? 같은 의미이다. 그 중에서도 MVVM 이라는 패턴에 대하여 이론적으로 한번 알아보고 토의하는 목적으로 작성
MVVM 의 종속성 관계는 다음과 같다.
반면에 ViewModel은 View를 소유하지 않고 Model 또한 View를 알지 못한다. 기존의 Cocoa MVC 에서는 ViewController가 view와 Model 모두를 소유하는 구조인 MVC 패턴과는 다른 구조를 가진다.
데이터 흐름은 다음과 같다. 예를들어 사용자가 인스타같은 소셜앱에서 좋아요를 누르는 기능을 생각해보자 좋아요를 누름(View) -> ViewModel(서버에 좋아요 처리 요청) -> ViewModel의 데이터가 변경됨 -> View에서 변경된 데이터 감지(좋아요 증가)
데이터 바인딩 이라는 말이 데이터를 무언가 동기화 시킨다는 의미로 알고있지만 정확히 알지 못해서 정리. 데이터 바인딩이란 UI상의 데이터와 실제 메모리의 데이터를 일치시키는 기법을 말한다. 만약 버튼을 누르면 카운팅된 숫자를 보여주는 앱이 있다고 가정해보자 버튼을 눌러서 실제 메모리상의 데이터는 1이 증가된 값이 저장되었지만 화면상의 UI에 변화가 없다면 데이터 바인딩이 필요한 상황이라고 말할 수 있다.
그렇다면 단방향, 양방향 데이터 바인딩의 차이는 무엇일까? 단방향 데이터 바인딩이란 한쪽에서 변경이 일어날 때만 데이터가 업데이트 되는 방식이다. HTML(View) 와 JS(Model)이 있다고 가정할때 단방향의 경우 JS(Model)에서 데이터를 변경하여 HTML(View)가 변경된다 HTML->JS 불가능
반면 양방향 데이터 바인딩의 경우 HTML -> JS가 가능하게 된다 양방향 데이터 바인딩은 프레임워크에서 감지하고 있다가 데이터가 변경되는 시점에 View를 리렌더 해준다.
ViewModel 클래스에 @Published, @ObservableObject 와 같은 프로퍼티 래퍼들은 Combine 프레임워크에 구현이 되어있다. Combine이란 시간에 흐름에 따라 발생하는 이벤트를 처리하기 위한 프레임워크이며 이미 Apple의 여러 프레임워크가 Combine기반으로 구현되어 있다. 또한 System Level에 구현이 되어있기 때문에 사용할 수 있는 기능이 많다고 한다. 우선 SwiftUI 와 Combine의 상성이 좋으며 우리가 사용하는 @Published, ObservableObject 등등은 Combine 이라는 프레임워크에 선언이 되어있으며 SwiftUI 에서도 Combine을 import 한다.
MVVM 패턴은 Model, View, ViewModel 세 가지 요소로 구성된 패턴
장점
단점
struct User {
var username: String
var email: String
}
import SwiftUI
import Combine
class UserViewModel: ObservableObject {
@Published var user: User
init(user: User) {
self.user = user
}
func updateUser(username: String, email: String) {
user.username = username
user.email = email
}
}
import SwiftUI
import Combine
struct UserView: View {
@ObservedObject var viewModel: UserViewModel
var body: some View {
VStack {
TextField("Username", text: $viewModel.user.username)
.padding()
TextField("Email", text: $viewModel.user.email)
.padding()
Button("Update") {
viewModel.updateUser(username: "viewModel.user.username", email: "viewModel.user.email")
}
.padding()
}
}
}
struct ContentView: View {
let user = User(username: "JohnDoe", email: "john@example.com")
let viewModel: UserViewModel
init() {
viewModel = UserViewModel(user: user)
}
var body: some View {
UserView(viewModel: viewModel)
}
}
MVVM 패턴 Model + View + View Model
- 구조
- Model : 데이터를 다루는 부분. 화면을 표현하는데 필요한 데이터를 관리하며, 사용자가 입력한 데이터를 저장하거나 서버로 받은 데이터를 저장
- View : 사용자에게 보여지는 UI 부분. 사용자가 화면에서 보는 것들에 대한 구조 배치와 같이 외관에 해당
- View Model : View를 표현하기 위해 만들어진 View를 위한 Model. View에서 발생하는 이벤트를 감지하고, 해당 이벤트에 맞는 비즈니스 로직을 수행.
- 동작
- 사용자의 Action들은 View를 통해 들어�
- View에 Action이 들어오면, Command 패턴으로 View Model에 Action을 전달
- View Model은 Model에게 데이터를 요청
- Model은 View Model에게 요청 받은 데이터를 응답
- View Model은 응답 받은 데이터를 가공하여 저장
- View는 View Model과 Data Binding하여 UI를 갱신
- 특징
- Command 패턴과 Data Binding 두 가지 패턴을 사용하여 구현
- View와 View Model 사이 의존성을 없앰
- View Model과 View는 1:n 관계
- 장점
- View와 Moel 사이 의존성이 없어 독립성을 유지할 수 있음
- 독립성 유지하기 때문에 효율적인 유닛 테스트가 가능
- View와 ViewModel이 1:n 관계이기 때문에 중복되는 로직을 모듈화 하여 개발할 수 있음(코드 재사용이 가능)
- 단점
- View Model 설계가 복잡
- 데이터 바인딩으로 인한 메모리 소모가 있음
- 복잡해질수록 ViewModel이 비대해짐
- ios 개발이 mvvm으로 넘어가는 이유
- SwiftUI에서는 View가 Viewmodel을 소유하고, Viewmodel이 Model을 소유하여 구조적인 개선이 이루어짐
- ViewController가 View, Model의 역할까지 담당하는 UIKit 단점을 극복
- 모듈화로 인한 테스트가 편리해짐
- Data Binding, Command
- Data Binding : Model고 UI 요소 간의 싱크를 맞추는 패턴. View와 로직이 분리되어 잇어도 한 쪽이 바뀌면 다른 쪽도 업데이트가 이루어져 데이터의 일관성을 유지할 수 있음
- Command : 여러가지 요소에 대한 처리를 하나의 액션으로 처리할 수 있게 하는 기법
Command 패턴이 뭔가용 알려주세요 해주세요 @sooohi
MVVM 패턴 Model + View + View Model
- 구조
- Model : 데이터를 다루는 부분. 화면을 표현하는데 필요한 데이터를 관리하며, 사용자가 입력한 데이터를 저장하거나 서버로 받은 데이터를 저장
- View : 사용자에게 보여지는 UI 부분. 사용자가 화면에서 보는 것들에 대한 구조 배치와 같이 외관에 해당
- View Model : View를 표현하기 위해 만들어진 View를 위한 Model. View에서 발생하는 이벤트를 감지하고, 해당 이벤트에 맞는 비즈니스 로직을 수행.
- 동작
- 사용자의 Action들은 View를 통해 들어�
- View에 Action이 들어오면, Command 패턴으로 View Model에 Action을 전달
- View Model은 Model에게 데이터를 요청
- Model은 View Model에게 요청 받은 데이터를 응답
- View Model은 응답 받은 데이터를 가공하여 저장
- View는 View Model과 Data Binding하여 UI를 갱신
- 특징
- Command 패턴과 Data Binding 두 가지 패턴을 사용하여 구현
- View와 View Model 사이 의존성을 없앰
- View Model과 View는 1:n 관계
- 장점
- View와 Moel 사이 의존성이 없어 독립성을 유지할 수 있음
- 독립성 유지하기 때문에 효율적인 유닛 테스트가 가능
- View와 ViewModel이 1:n 관계이기 때문에 중복되는 로직을 모듈화 하여 개발할 수 있음(코드 재사용이 가능)
- 단점
- View Model 설계가 복잡
- 데이터 바인딩으로 인한 메모리 소모가 있음
- 복잡해질수록 ViewModel이 비대해짐
- ios 개발이 mvvm으로 넘어가는 이유
- SwiftUI에서는 View가 Viewmodel을 소유하고, Viewmodel이 Model을 소유하여 구조적인 개선이 이루어짐
- ViewController가 View, Model의 역할까지 담당하는 UIKit 단점을 극복
- 모듈화로 인한 테스트가 편리해짐
- Data Binding, Command
- Data Binding : Model고 UI 요소 간의 싱크를 맞추는 패턴. View와 로직이 분리되어 잇어도 한 쪽이 바뀌면 다른 쪽도 업데이트가 이루어져 데이터의 일관성을 유지할 수 있음
- Command : 여러가지 요소에 대한 처리를 하나의 액션으로 처리할 수 있게 하는 기법
Command 패턴이 뭔가용 알려주세요 해주세요 @sooohi
Command는 UI에서 발생하는 작업을 캡슐화하고, 나중에 실행할 수 있도록 하는 객체입니다. MVVM패턴에서 Command는 주로 ViewModel에 의해 구현되며 아래 세 가지 주요 부분으로 구성됩니다.
요청하신 예시는 아래 코드로 드리겠습니다!
Command 클래스 또는 인터페이스 : 이벤트를 처리하는데 사용되는 명령을 나타냄.
public interface ICommand
{
void Execute();
}
Command 구현체 : Command 클래스 또는 인터페이스의 실제 구현
public class SaveCommand : ICommand
{
private ViewModel viewModel;
public SaveCommand(ViewModel vm)
{
viewModel = vm;
}
public void Execute()
{
viewModel.SaveData();
}
}
Command 트리거 하는 객체 : 버튼이나 다른 사용자 이벤트가 해당 Command를 실행
public class SaveButton
{
private ICommand saveCommand;
public SaveButton(ICommand command)
{
saveCommand = command;
}
public void Click()
{
// 사용자가 버튼을 클릭하면 연결된 Command의 Execute 메서드를 호출합니다.
saveCommand.Execute();
}
}
// ViewModel을 생성합니다.
ViewModel myViewModel = new ViewModel();
// SaveCommand를 생성하고 ViewModel을 주입합니다.
SaveCommand saveCommand = new SaveCommand(myViewModel);
// SaveButton을 생성하고 SaveCommand를 연결합니다.
SaveButton saveButton = new SaveButton(saveCommand);
// 사용자가 버튼을 클릭하면 연결된 SaveCommand의 Execute 메서드가 호출됩니다.
saveButton.Click();
부족한 부분이나 틀린 부분 언제든지 말해주세욤...! @Seokki-Kwon
MVVM 패턴 공부 한 내용 업로드
기한 : 1월 18일 13시까지