MVP ํŒจํ„ด์—์„œ์˜ DataBinding

๐Ÿ’กMVP ํŒจํ„ด์—์„œ DataBinding์„ ํ™œ์šฉํ•œ ์–‘๋ฐฉํ–ฅ DataBinding ๋Œ€ํ•ด ์ •๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค!

 

MVP with DataBinding

  • MVP ํŒจํ„ด์€ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜๋กœ, UI ๋กœ์ง๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
  • DataBinding์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด UI์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ฝ”๋“œ๋Ÿ‰ ๊ฐ์†Œ์™€ ์ง๊ด€์ ์ธ UI ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

MVP์—์„œ DataBinding์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

์ฝ”๋“œ ๊ฐ„๊ฒฐํ™”

  • findViewById()๋ฅผ ํ†ตํ•œ UI ํƒ์ƒ‰์ด ์•„๋‹Œ DataBinding์„ ํ†ตํ•ด XML ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ๊ณผ ์ง์ ‘์ ์œผ๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด UI ์š”์†Œ์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ๋” ์ง๊ด€์ ์ด๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ

  • MVP ํŒจํ„ด์—์„œ View๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ UI๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.
  • DataBinding์„ ์‚ฌ์šฉํ•ด์„œ UI์š”์†Œ์™€ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด UI๊ฐ€ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋ฉ๋‹ˆ๋‹ค.

View์™€ Presenter ์˜์กด์„ฑ ๋ถ„๋ฆฌ

  • View์™€ Presenter๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ View์˜ ๋ณต์žก๋„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Presenter๊ฐ€ ์ง์ ‘ UI์— ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ , DataBinding์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

MVP ๊ตฌํ˜„

  • ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” User Model์„ MVP ํŒจํ„ด์—์„œ xml๊ณผ ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์ ์šฉํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.
data class User(val name: String, val age: Int)
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="user"
            type="com.example.app.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/nameTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}" />

        <TextView
            android:id="@+id/ageTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{Integer.toString(user.age)}" />
    </LinearLayout>
</layout>

DataBinding

  • Activity๋Š” Prsenter๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ DataBinding์„ ํ†ตํ•ด UI์™€ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
  • Presenter๋Š” Model์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ View์— ์ „๋‹ฌํ•˜๋Š” ๊ตฌ์กฐ๋กœ, View๋Š” DataBinding์„ ํ†ตํ•ด XML ๋ ˆ์ด์•„์›ƒ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ UI๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•ฉ๋‹ˆ๋‹ค.
class MainActivity : AppCompatActivity(), MainContract.View {

    private lateinit var binding: ActivityMainBinding
    private lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // DataBinding ์ดˆ๊ธฐํ™”
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        // Presenter ์ดˆ๊ธฐํ™”
        presenter = MainPresenter(this)

        // Presenter์—๊ฒŒ ๋ฐ์ดํ„ฐ ์š”์ฒญ
        presenter.loadUserData()
    }

    // Presenter๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ๋ฐ›์•„์„œ UI ์—…๋ฐ์ดํŠธ
    override fun displayUser(user: User) {
        binding.user = user // XML์— ์žˆ๋Š” user ๊ฐ์ฒด์™€ ๋ฐ”์ธ๋”ฉ
    }

    override fun showError(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}
  • ์–‘๋ฐฉํ–ฅ ์—…๋ฐ์ดํŠธ๋ฅผ ํ™œ์šฉํ•œ ์ž๋™ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ๊ฐ„๊ฒฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋กœ ์ธํ•ด UI ์ฝ”๋“œ์˜ ์–‘์„ ์ค„์ด๊ณ , ๋ฐ์ดํ„ฐ์™€ UI ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ๋” ์ง๊ด€์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DataBinding์—์„œ MVVM๊ณผ MVP

  • MVVM ํŒจํ„ด์—์„œ๋Š” ViewModel์„ ํ™œ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ผ์ด๋ธŒ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋กœ ์ข€ ๋” ์–‘๋ฐฉํ–ฅ์— ์ ํ•ฉํ•œ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • MVP ํŒจํ„ด์—์„œ๋„ LiveData๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
class MainActivity : AppCompatActivity(), MainContract.View {

    private lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        presenter = MainPresenter(DataRepository())

        // LiveData ๊ด€์ฐฐ
        presenter.userData.observe(this, Observer { user ->
            // ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ UI ์—…๋ฐ์ดํŠธ
            updateUI(user)
        })

        presenter.loadUserData()
    }

    override fun updateUI(user: User) {
        // UI ์—…๋ฐ์ดํŠธ ์ฝ”๋“œ
        textViewName.text = user.name
    }
}
  • ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€์ฐฐํ•ด์„œ View๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š”๋ฐ, interface๋ฅผ ์ƒ์†๋ฐ›์€ presenter์—์„œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, activity์—์„œ updateUi ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด ๋•Œ๋ฌธ์— Presenter๊ฐ€ UI์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ณ , ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • LiveData ์‚ฌ์šฉ์€ MVVM์— ๋” ์ž˜ ์–ด์šธ๋ฆฌ๋ฉฐ, MVP์—์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด Prsenter์˜ ์—ญํ• ์ด ๋ชจํ˜ธํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •๋ฆฌ

  • MVPํŒจํ„ด์—์„œ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ™œ์šฉํ•ด์„œ ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ๋ผ์ด๋ธŒ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์˜ ์ด์ ์„ ์‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” MVVM ํŒจํ„ด์ด ๋” ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ ํŠธ์˜ ๊ตฌ์กฐ์— ๋”ฐ๋ผ์„œ ์ ํ•ฉํ•œ ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์œ ๋™์ ์ธ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด ๊ฐ€๋Šฅํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.