[MVVM] ViewModel์—์„œ View ์ฐธ์กฐ

์‘์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ๋•Œ MVVM ํŒจํ„ด์„ ์ ์šฉํ•˜๋ฉด ๋ทฐ์™€ ๋ทฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ทฐ๋ชจ๋ธ ๊ฐ„ ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ๋ทฐ๋ชจ๋ธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ํ‘œ์‹œํ•˜๊ณ  ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ MVVM์—์„œ ๋ช…๋ น์–ด๋ฅผ ๋ทฐ๋ชจ๋ธ์—์„œ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ทฐ์˜ ๋™์ž‘์ด ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ™”๋ฉด์ƒ์—์„œ ํ…์— ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ ์ปจํ…์ŠคํŠธ์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•ด์•ผ ํ•˜๊ณ  ์ด ์ด๋ฆ„์„ ํŒ์—… ์œˆ๋„์šฐ๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ ๋ฐ›์•„์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.

  1. [๋ทฐ] ํ… ์ถ”๊ฐ€ ๋ฒ„ํŠผ ํด๋ฆญ
  2. [๋ทฐ๋ชจ๋ธ] ์ปจํ…์ŠคํŠธ ์ถ”๊ฐ€
  3. [๋ทฐ] ์ปจํ…์ŠคํŠธ ์ด๋ฆ„ ํŒ์—… ์ž…๋ ฅ
  4. [๋ทฐ๋ชจ๋ธ] ์ž…๋ ฅ๋ฐ›์€ ์ด๋ฆ„์œผ๋กœ ์ปจํ…์ŠคํŠธ ์ถ”๊ฐ€
  5. [๋ทฐ] ์ปจํ…์ŠคํŠธ ๋ฐ”์ธ๋”ฉ์— ์˜ํ•ด ํƒญ ํ‘œ์‹œ, ๋‚ด์šฉ ํ‘œ์‹œโ€ฆ

๋‹ค๋ฅธ ๊ณผ์ •์€ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ๊ฐ€๋Šฅํ•œ๋ฐ '2-1โ€™์˜ ๊ฒฝ์šฐ ๋ทฐ๋ชจ๋ธ์—์„œ ๋ทฐ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ทฐ๋ชจ๋ธ์—์„œ ๋ทฐ๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฉด MVVM ํŒจํ„ด์— ์œ„๋ฐ˜๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ SOLID ์›์น™ ์˜์กด๊ด€๊ฒŒ ์—ญ์ „ ์›์น™์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” IoC์—์„œ๋„ ๋™์ผํ•œ ์›๋ฆฌ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ๋ทฐ๋ชจ๋ธ์€ ๋ทฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ  ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ฐธ์กฐํ•ด์„œ ๋ทฐ๋Š” ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๋ทฐ๋ชจ๋ธ์€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ง์ ‘์ ์ธ ๋ทฐ๋ชจ๋ธ๊ณผ ๋ทฐ๊ฐ„ ์ฐธ์กฐ ๊ด€๊ณ„๊ฐ€ ์—†๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ด€๊ณ„ ๋ช…์„ธ

๊ฐ„๋‹จํ•œ ๋‘๊ฐœ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

public interface IViewAction
{
}

public interface IHaveViewAction<TViewAction>
    where TViewAction : IViewAction
{
    TViewAction? ViewAction { get; set; }
}

IViewAction์€ ๋ทฐ ์•ก์…˜์„ ์˜๋ฏธํ•˜๋ฉฐ IHaveViewAction์˜ ์ œ๋„ค๋ฆญ ์ธ์ž๊ฐ€ ๋ทฐ ์•ก์…˜์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
IHaveViewAction<TViewAction>์€ ๋ทฐ๊ฐ€ ๋ทฐ ์•ก์…˜์„ ์†Œ์œ ํ•จ์„ ์˜๋ฏธํ•˜๋ฉฐ ๋‹ค์Œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

| ๋ทฐ๋ชจ๋ธ

public partial class RepositoryViewModel : ObservableRecipient, IViewModel, IHaveViewAction<IRepositoryViewAction>
{
    public IRepositoryViewAction? ViewAction { get; set; }
...

IViewModel๋„ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๋ทฐ๋ชจ๋ธ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋นˆ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

๋ทฐ๋Š” ๋‹ค์Œ์˜ ๋ชจ์Šต์ด ๋ฉ๋‹ˆ๋‹ค.

| ๋ทฐ

public sealed partial class RepositoryPage : ViewModelPage, IView<RepositoryViewModel>, IRepositoryViewAction
{
    public RepositoryPage()
    {
        InitializeComponent();

        ViewModel.ViewAction = this;
    }
...

์ด์ œ RepositoryPage๋Š” IRepositoryViewAction ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ทฐ๋ชจ๋ธ์—์„œ MVVM ํŒจํ„ด์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ๋ทฐ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

8๊ฐœ์˜ ์ข‹์•„์š”

ํ˜น์‹œ ๊ด€๋ จ ์ž์„ธํ•œ ์˜ˆ์‹œ ์ฝ”๋“œ๊ฐ€ ์žˆ์„๊นŒ์š”?
๊ธ€์„ ์ฝ์—ˆ์„ ๋•Œ๋Š” ์ดํ•ด๊ฐ€ ๊ฐ€๋Š”๋ฐ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ ์–ด๋–ค ๋ถ€๋ถ„์— ์ ์šฉ์ด ๊ฐ€๋Šฅํ•œ์ง€ ๊ฐ์ด ์ž˜ ์•ˆ์˜ต๋‹ˆ๋‹ค.

๋˜ InvokeCommandAction ํ•˜๊ณ  ๋‹ค๋ฅธ๊ฒƒ์ด ์žˆ์„๊นŒ์š”?

2๊ฐœ์˜ ์ข‹์•„์š”

๋ทฐ๋ชจ๋ธ์—์„œ ๋ทฐ๋กœ์˜ ํ๋ฆ„์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ๋‹ฌ์„ฑํ•˜๋Š”๋ฐ์š”, ํ•˜์ง€๋งŒ ๊ฐ€๋ น ์ฐฝ์„ ๋„์›Œ์•ผ ํ•œ๋‹ค๋“ ์ง€, ๋˜๋Š” ๋ทฐ๋ชจ๋ธ์˜ ํ๋ฆ„์— ์˜ํ•ด (๊ฐ€๋ น ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ ) ํŒŒ์ผ ์ €์žฅ์„ ์œ„ํ•œ ํŒŒ์ผ์ €์žฅ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ๋„์šด๋‹ค๋“ ์ง€ ํ•  ๋•Œ์ž…๋‹ˆ๋‹ค.

๊ด€๋ จํ•ด์„œ ์ƒ˜ํ”Œ ์ƒ์„ฑํ•ด์„œ ๊ณต์œ  ํ•ด๋ณผ๊ป˜์š”

4๊ฐœ์˜ ์ข‹์•„์š”