티스토리 뷰
MVVC 패턴은 Model-View-ViewModel 패턴의 약자로, 소프트웨어 설계 방식 중 하나로 데이터와 UI의 분리를 통해 유지보수성과 재사용성을 향상시키기 위해 사용됩니다. QML에서 MVVC 패턴은 데이터 로직과 UI 로직을 ViewModel로 분리하여, UI와 로직을 명확하게 구분하고 데이터 바인딩을 통해 UI가 변경 사항에 반응하도록 합니다.
MVVC 패턴의 구성 요소
- Model (모델): 데이터와 비즈니스 로직을 담당합니다. 예를 들어 데이터베이스나 서버와의 연결, 데이터를 저장하고 관리하는 역할을 합니다.
- View (뷰): 사용자 인터페이스로, 데이터를 시각적으로 표시하고 사용자 입력을 받습니다. QML의 다양한 컴포넌트(Text, Button, ListView 등)가 여기에 해당합니다.
- ViewModel (뷰모델): 모델과 뷰를 연결하는 역할을 하며, 데이터와 UI 로직을 포함합니다. 바인딩을 사용하여 뷰와 모델 간의 상호작용을 중재합니다. ViewModel은 모델의 데이터를 가공하거나 상태를 관리하여 뷰에서 쉽게 사용할 수 있도록 합니다.
QML에서 MVVC의 구현
QML에서 MVVC 패턴을 구현하는 방법은 QML과 JavaScript 또는 C++과 QML을 조합하여 구현할 수 있습니다. ViewModel은 QML에서 JavaScript 코드나 C++ 객체로 구현할 수 있으며, 이 ViewModel을 통해 뷰와 모델을 연결합니다.
예시: QML과 JavaScript를 이용한 MVVC 구현
다음은 간단한 MVVC 패턴을 사용한 예제로, 사용자 데이터를 관리하는 애플리케이션을 구현해 보겠습니다.
1. Model (모델)
모델은 데이터의 저장소 역할을 합니다. 간단한 사용자 목록을 데이터로 가집니다.
ListModel {
id: userModel
ListElement { name: "Alice"; age: 25 }
ListElement { name: "Bob"; age: 30 }
}
- ListModel을 사용하여 데이터를 정의합니다. 각 사용자(ListElement)는 name과 age 속성을 가집니다.
2. ViewModel (뷰모델)
ViewModel은 JavaScript나 C++로 구현할 수 있습니다. 여기서는 QML의 JavaScript 파일을 사용하여 ViewModel 역할을 구현합니다.
userViewModel.js (JavaScript로 ViewModel 역할 수행)
function addUser(model, name, age) {
model.append({ name: name, age: age });
}
function removeUser(model, index) {
if (index >= 0 && index < model.count) {
model.remove(index);
}
}
- addUser 함수: 새로운 사용자를 모델에 추가합니다.
- removeUser 함수: 지정된 인덱스에 있는 사용자를 모델에서 제거합니다.
3. View (뷰)
뷰는 사용자와의 상호작용을 담당하고, 데이터를 시각적으로 표현합니다. 여기서 사용자 목록을 ListView로 표시하고, 버튼을 사용하여 사용자를 추가하거나 제거할 수 있습니다.
main.qml (사용자 인터페이스 - View)
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 400
height: 500
// 모델 정의
ListModel {
id: userModel
ListElement { name: "Alice"; age: 25 }
ListElement { name: "Bob"; age: 30 }
}
// 사용자 목록 표시
ListView {
id: userListView
width: parent.width
height: parent.height - 150
model: userModel
delegate: Rectangle {
width: parent.width
height: 50
border.color: "black"
color: index % 2 === 0 ? "lightblue" : "lightgreen"
Row {
spacing: 10
Text {
text: "Name: " + model.name + ", Age: " + model.age
}
}
}
}
// 사용자 추가 버튼
Button {
text: "Add User"
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: 10
onClicked: {
addUser(userModel, "NewUser", Math.floor(Math.random() * 50) + 20);
}
}
// 사용자 제거 버튼
Button {
text: "Remove Selected"
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 10
onClicked: {
if (userListView.currentIndex >= 0) {
removeUser(userModel, userListView.currentIndex);
}
}
}
// ViewModel 자바스크립트 파일 로드
Component.onCompleted: {
Qt.include("userViewModel.js");
}
}
설명
- Model 정의:
- userModel이라는 ListModel로 사용자의 데이터를 관리합니다.
- ViewModel 함수 사용:
- JavaScript 파일(userViewModel.js)에서 정의한 ViewModel 함수를 사용하여 사용자 추가 및 제거를 처리합니다.
- addUser()와 removeUser() 함수를 사용하여 userModel을 변경합니다.
- View:
- ListView를 사용하여 사용자 목록을 표시합니다.
- 버튼을 통해 사용자를 추가하거나 제거할 수 있으며, 버튼 클릭 시 ViewModel 함수를 호출합니다.
- Component.onCompleted를 통해 JavaScript 파일을 로드하여 ViewModel 함수에 접근합니다.
MVVC의 주요 장점
- 데이터와 UI의 분리:
- View와 Model 간의 직접적인 연결을 피하고 ViewModel을 통해 데이터와 UI를 분리합니다.
- 데이터와 UI 로직을 분리함으로써 유지보수성이 높아집니다.
- 바인딩을 통한 UI 자동 갱신:
- 모델에서 데이터가 변경되면, ViewModel을 통해 뷰에 자동으로 반영되므로 반응형 UI를 쉽게 구현할 수 있습니다.
- 테스트 용이성:
- ViewModel이 View와 독립적이므로, 뷰를 테스트하지 않고도 데이터 로직을 테스트할 수 있습니다.
- 이는 유닛 테스트 작성이 용이하게 해 줍니다.
C++을 사용한 MVVC 구현
복잡한 데이터 로직이 필요하거나 성능을 최적화해야 할 경우, ViewModel을 C++로 구현할 수도 있습니다. 이렇게 하면 모델의 복잡한 로직을 C++로 처리하고, QML과 바인딩하여 데이터 변경 사항을 UI에 반영할 수 있습니다.
예시: C++에서 ViewModel 클래스 생성
#include <QObject>
#include <QAbstractListModel>
class UserViewModel : public QAbstractListModel {
Q_OBJECT
public:
UserViewModel(QObject *parent = nullptr) : QAbstractListModel(parent) {
// 데이터 초기화
}
// 사용자 추가 및 제거 기능 구현
public slots:
void addUser(const QString &name, int age) {
// 사용자 추가 로직
}
void removeUser(int index) {
// 사용자 제거 로직
}
// 기타 QAbstractListModel 필수 함수들 구현...
};
결론
- MVVC (Model-View-ViewModel) 패턴은 QML에서 데이터와 UI 로직을 분리하고, 유지보수성과 확장성을 높이는 데 유용한 설계 패턴입니다.
- ViewModel은 모델과 뷰 사이에서 데이터 가공 및 상태 관리를 하며, QML에서는 JavaScript 코드나 C++ 객체로 구현될 수 있습니다.
- QML과 JavaScript, 또는 C++과 QML을 조합하여 MVVC를 구현하면, 유연하고 반응형 UI를 간단히 구축할 수 있습니다.
MVVC 패턴은 특히 큰 규모의 애플리케이션에서 코드의 재사용성을 높이고, 유지보수가 용이한 아키텍처를 만드는데 매우 효과적입니다.
개인적으로 학습하면서 정리한 내용입니다.
잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.
오늘도 감사합니다.(__)
'개발 > QT, QML' 카테고리의 다른 글
QML의 사용자 정의 컨트롤 (0) | 2024.11.22 |
---|---|
QML에서 delegate (1) | 2024.11.21 |
QML의 Repeater (0) | 2024.11.19 |
QML에서 시그널과 슬롯을 사용하기 위한 몇 가지 조건 (0) | 2024.11.18 |
빈 ListModel 생성 후 데이터 추가 (0) | 2024.11.17 |