1. 선언형 UI란?
한 정의에 따르면, 프로그램이 어떤 방법으로 해야 하는지를 나타내기보다 무엇과 같은지를 설명하는 경우에 "선언형"이라고 한다. 예를 들어, 웹 페이지는 선언형인데 웹페이지는 제목, 글꼴, 본문, 그림과 같이 "무엇"이 나타나야하는지를 묘사하는 것이지 "어떤 방법으로" 컴퓨터 화면에 페이지를 나타내야 하는지를 묘사하는 것이 아니기 때문이다. 이것은 전통적인 포트란과 C, 자바와 같은 명령형 프로그래밍 언어와는 다른 접근방식인데, 명령형 프로그래밍 언어는 프로그래머가 실행될 알고리즘을 명시해주어야 하는 것이다. 간단히 말하여, 명령형 프로그램은 알고리즘을 명시하고 목표는 명시하지 않는 데 반해 선언형 프로그램은 목표를 명시하고 알고리즘을 명시하지 않는 것이다.
여기서 중요한 내용을 간단하게 요약하자면 선언형 UI는 "어떻게(HOW)" UI를 구성하는지가 아니라 "무엇(WHAT)"을 UI에 구성하는지 나타내는 방식이다.
명령형 UI VS 선언형 UI
Flutter 공식 문서에 명령형 UI와 선언형 UI의 차이를 설명해주는 내용이 있어 이 내용을 가지고 비교를 해보겠다.
// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
명령형 UI는 우리가 흔히 아는 방식이다. UI를 구성할 때 어떻게 화면을 구성할 지 묘사를 하는 방법이다.
b가 어떻게 만들어지는지에 대한 과정이 명시되어 있다.
// Declarative style
return ViewB(
color: red,
child: const ViewC(),
);
반면에 선언형 UI는 UI를 구성할 때 무엇을 구성할 지 묘사를 해야한다.
ViewB가 무엇인지 설명하는 목표에만 치중하고 있다.
더 쉽게 두 방법을 비교하는 예시로, 다른 사람에게 본인의 위치를 알려주고 찾아오게 한다고 가정하자.
명령형 방식 - OO역의 북쪽 출구로 나와 왼쪽으로 5분 가면 ㅁㅁ학교가 나오는데 거기서 XX방면으로 10분동안 직진하면 됩니다.
선언형 방식 - 주소는 OO시 ㅁㅁ구 XX로 입니다.
선언형 UI에서의 한가지 공식
선언형 UI에서 가장 중요한 것은 위젯 또는 함수(F)의 인자로 상태(STATE)를 넘겨주면 그의 맞는 뷰(VIEW)를 생성해주는 것이다.
2. 선언형 UI의 종류
선언형 UI가 실제로 해당 공식을 지키는지 간단한 코드와 함께 살펴볼 것이다.
React Native
페이스북에서 개발한 오픈소스 프레임워크이며 리액트를 기반으로 한다. JavaScript언어를 사용한다.
const styles = StyleSheet.create({
bigBlue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigBlue}>just bigBlue</Text>
<Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>
<Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text>
</View>
);
}
}
웹에서의 CSS동작과 일치한다. 아래의 View나 Text 컴포넌트를 통해 UI를 선언하고 style을 통해 상태를 넘겨주며 뷰를 생성한다.
Flutter
구글에서 개발한 크로스플랫폼 프레임워크이며 Dart언어를 사용한다.
class AddCartButton extends StatelessWidget{
@override
build() {
return Center(
child: Button(
child: Text('Add to Cart'),
)
);
}
}
Button과 Text가 위젯을 뜻한다. Button의 위젯의 상태로 Text 위젯을 전달하고 뷰를 생성하는 것을 볼 수 있다.
Jetpack Compose
안드로이드에서 선언형 UI를 위해 제작된 프레임워크이며 Kotlin으로 작성할 수 있다.
@Composable
fun OnboardingScreen(onContinueClicked: () -> Unit) {
Surface {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Welcome to the Basics CodeLab!")
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = onContinueClicked
) {
Text("Continue")
}
}
}
}
Column과 Button 컴포넌트의 상태로 modifier등을 전달하고 뷰를 생성하게 된다.
SwiftUI
iOS에서 선언형 UI를 위해 제작된 프레임워크이며 Swift로 작성할 수 있다.
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.body)
.fontWeight(.medium)
.foregroundColor(.green)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Text("California")
.font(.subheadline)
}
}
}
}
Text와 같은 컴포넌트의 상태로 font등을 전달하게 되고 뷰를 생성한다.
3. 선언형 UI의 장단점
모바일 플랫폼도 선언형 UI가 대세로 자리잡고 있다.
리액트 네이티브와 플러터는 선언형 UI를 사용하고 있고, 안드로이드와 iOS에서도 선언형 UI 방식의 프레임워크인 Compose와 SwiftUI를 각각 공개했다.
그럼 왜 선언형 UI가 대세인지 장단점에 대해 알아보자.
장점
- 직관적이다. 하나의 포인트에서 화면 구성, 이벤트 내용, 애니메이션 등 UI의 모든 것을 알 수 있다.
- 재사용성이 좋다. 기본 호출만으로 UI를 재사용할 수 있다. UI를 수정할 때 하나의 영역만 확인 후 수정하면 되니 작업 효율성도 올라가게 된다.
- 단방향 흐름으로 인한 SideEffect 제거할 수 있다. 단방향 흐름의 성향이 강한 선언형 UI의 특징에 따라 호출된 영역과 호출한 영역의 구분이 확실하게 독립적이다. 따라서 SIdeEffect 차단에 도움이 된다.
단점
- 방대한 코드가 단점. 한 곳에서 UI의 모든 것을 정의하기 때문에 코드가 방대해진다.
- 재사용성의 어두운면이 존재한다. 개발자의 활용 부족으로 마구잡이로 개발하면 중복 코드가 많아져 유지보수가 힘들어진다.
- 선언형은 결국 명령형의 추상화이다. 가독성은 좋지만 과정이 없기에 불호하는 사람이 있기 마련이다.
마치며
안드로이드가 비교적 선언형 UI의 도입이 늦었다.
하지만 선언형 UI가 대세인 만큼 Compose 사용자가 늘어나고 있기 때문에 나도 아마 다음주부터는 Compose 관련 포스팅을 시작하지 않을까 싶다.
Compose 시작하기에 앞서 선언형 UI를 짚고가는 느낌이랄까..
참고
'안드로이드 개발 이야기' 카테고리의 다른 글
토스 앱 분석기 (UX 심리학, 모션 등등 토스같은 앱 개발을 위한 추천 안드로이드 라이브러리) (0) | 2023.06.25 |
---|---|
개발자 관점에서 바라본 좋은 UI / UX 디자인이란? (0) | 2023.03.18 |
반응형 UI 만들기 (0) | 2023.01.22 |
안드로이드 개발 트렌드 (0) | 2023.01.09 |