ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UI 레이어란?
    Clean Architecture 2025. 8. 24. 22:00

    안녕하세요~ 올해 새로운 취미를 가지고 싶어서 소설책을 조금씩 읽고 있어요!! 뭘 읽을지 몰라 무작정 유명한 것만 골라서 파과, 스토너, 구의 증명, 홍학의 자리, 급류 이렇게 다섯 권 읽었어요. 기억에 남는 책은 구의 증명 > 파과 > 홍학의 자리 > 스토너 > 급류 였던 것 같아요. OTT 중 쿠팡플레이에서 '파과'가 얼마 전까지만 해도 유료였다가 무료로 풀렸더라고요. 소설이랑 영화랑 무슨 차이가 있을까 궁금해서 보고 있어요. 아직 초반까지만 봤는데 원작(소설)이 훨씬 나은 것...같아요^^ 하.하.하 (개인적인 생각입니다) 댓글로 괜찮은 소설 있으면 추천해주세요😊 오늘은 클린 아키텍처의 마지막 레이어, UI 레이어에 대해 알아보겠습니다!

    feat. 어플을 사용하는 유저가 왕이다 👑

     

    1. UI 레이어란?

    UI 레이어는 User Interface 레이어의 준말입니다. Presentation 레이어와 상호작용하는데, viewmodel을 통해 데이터를 받아와 화면 UI에 표시하거나 사용자의 액션을 viewModel로 전달하는 인터페이스 역할을 합니다. 

     

    2. XML vs Compose

    xml과 compose 둘 다 'UI를 구현한다'는 공통점이 있는데요. 기존 레거시 뷰로 xml 을 많이 사용했었지만 선언형 UI인 compose도 많은 장점이 있습니다. 상태를 mutablestate 로 지정하여 변경되었을 때 자동으로 recomposition을 해주는 점에서 상태 관리가 더욱 용이합니다. 프리뷰(Preview) 기능으로 따로 앱을 빌드하지 않고도 UI의 변경을 곧바로 확인할 수 있습니다. 또한 애니메이션 기능을 기존 xml에서는 복잡하게 구현해야 했는데 compose는 xml보다 비교적 쉽고 간단하게 구현할 수 있습니다. xml과 compose 는 호환성을 가지고 있기 때문에, 기존 xml 에다가 compose 뷰를 넣거나 compose 에서 xml 뷰를 넣는 혼합 UI를 구성할 수 있습니다. 이때 중요한 점은 기존 xml 코드에서 compose로 변환하는 과정을 거쳐도 Presentation 레이어의 뷰모델 코드가 변경되서는 안됩니다. 왜냐하면 안쪽인 Presentation 레이어는 바깥쪽 UI 레이어에 의존하지 않기 때문입니다. 

     

    3. xml 예제 코드

    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="viewModel"
                type="com.example.app.UserViewModel"/>
        </data>
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:text="@{viewModel.user.name}"/>
        </LinearLayout>
    </layout>

     

    데이터 바인딩을 사용하기 위해 <layout> 태그를 가장 바깥쪽에 감싸줍니다. 해당 태그는 데이터와 UI를 연결하는 역할을 합니다. <data> 태그는 xml 레이아웃에서 사용할 객체를 정의합니다. name 속성을 통해 viewmodel 객체에 접근할 수 있습니다. TextView의 text에서는 데이터 바인딩 표현식인 @{ } 을 통해 viewmodel 객체의 값에 접근합니다. 

    class UserActivity: AppCompatActivity() {
        private lateinit var binding: ActivityUserBinding
        private val viewModel: UserViewModel by viewModels()
        
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = DataBindingUtil.setContentView(this, R.layout.activity_user)
            binding.viewModel = viewModel
            binding.lifecycleOwner = this
            
            val userId = intent.getStringExtra("USER_ID")
            viewModel.loadUserProfile(userId)
        }
    }

     

    여기서는 DataBindingUtil 을 통해 데이터 바인딩을 사용해 binding 객체과 layout 파일을 연결해줍니다. binding.viewModel 에서는 아까 <data> 태그로 선언한 viewmodel 변수에 실제 viewmodel 을 주입합니다. binding.lifecycleOwner = this 는 livedata 를 xml에서 관찰하기 위해 반드시 지정해야 합니다. 해당 설정을 하지 않으면 text 에서의 @{viewModel.user.name} 값은 초기에 한 번만 값이 들어가고, 그 이후에 변경은 UI에 반영되지 않습니다. viewModel.loadUserProfile(userId) 에서는 UI 레이어에서 Presentation 레이어의 뷰모델을 호출하여 값을 전달하는 것을 확인할 수 있습니다.

     

    4. compose 예제 코드

    @Composable
    fun UserInfo(viewModel: UserViewModel) {
        val user by viewModel.user.collectAsStateWithLifecycle()
        if(user == null) {
            Text(text = "Loading")
        } else {
            Text(text = "user: ${user.name}")
        }
    }

     

    Presentation 레이어의 뷰모델로부터 user 데이터를 받아와 UI 레이어의 컴포저블로 노출하는 것을 확인할 수 있습니다. 여기서 viewModel의 user는 플로우(flow)를 state로 변환해주고 Lifecycle을 통해 화면이 보일 때만 안전하게 데이터를 수집(collect)합니다. Text 컴포저블로 값의 상태에 따라 UI를 다르게 표시하는걸 볼 수 있습니다.

     

    5. 정리

    UI 레이어는 Presentation 레이어의 뷰모델의 데이터를 화면에 표시하는 역할을 할 뿐 도메인 레이어의 비즈니스 로직을 알지 못합니다. 지금까지 배운 레이어를 플로우로 정리하면 사용자의 이벤트가 UI 레이어를 통해 Presentation 레이어의 뷰모델로 전파되고, 이후 도메인 레이어의 usecase 에 도달합니다. Data 레이어의 Repository를 거쳐 Remote, Local 레이어의 DataSource 를 통해 관련된 데이터를 가져와 다시 반대 방향으로 UI에 다시 액션으로 돌려주는 과정을 거칩니다.

     

    지금까지 클린 아키텍처의 Domain 레이어, Data 레이어, Remote 레이어, Local 레이어, Presentation 레이어, UI 레이어에 대해서 자세히 살펴보았습니다. 클린 아키텍처를 통해 복잡하고 고도화된 앱의 구조 설계에 실제 적용해보면 좋을 것 같습니다! 🙌

    'Clean Architecture' 카테고리의 다른 글

    Presentation 레이어란?  (8) 2025.08.17
    Local 레이어란?  (4) 2025.08.10
    Remote 레이어란?  (6) 2025.08.03
    Data 레이어란?  (2) 2025.07.27
    Domain 레이어란?  (2) 2025.07.20
Designed by Tistory.