UseCase

๊ฐœ๋…

  • ์ฃผ๋กœ ์ƒ์„ฑ์ž์™€ ์‹คํ–‰ ํ•จ์ˆ˜ 1๊ฐœ๋งŒ ๊ฐ€์ง„ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

  • ๋ฐ›์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ๋ถ€์ž‘์šฉ(side effect)๋ฅผ ๊ฐ€ํ•˜์ง€ ์•Š๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

  • ์ •์  ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์ง€๋งŒ DI์™€์˜ ๊ถํ•ฉ์ด ์ข‹๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฅ˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

์–ธ์ œ UseCase๋ฅผ ์‚ฌ์šฉํ•˜๋‚˜์š”?

  • ํ†ต์‹  ์ฒ˜๋ฆฌ

  • ๊ณตํ†ต ์ฒ˜๋ฆฌ๋กœ ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ฒ˜๋ฆฌ

  • Lifecycle๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋น„๋Œ€ํ™”๋˜์–ด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ

ํŠนํžˆ ํ†ต์‹ ์ฒ˜๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ , ์ฒ˜๋ฆฌ ๋‚ด์šฉ๋„ ๋น„๋Œ€ํ•ด์ง€๊ธฐ ์‰ฝ๊ธฐ ๋•Œ๋ฌธ์— UseCase๋กœ ๋ถ„๋ฅ˜ํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿด ๋•Œ UseCase๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜์„ธ์š”.

์˜ˆ๋ฅผ ๋“ค์–ด ์บ๋ฆญํ„ฐ ์ •๋ณด ํš๋“ ํ†ต์‹ ์€ ์ธ๊ฒŒ์ž„ ์ „ํ™˜ ์‹œ, ํŽธ์„ฑ ํ™”๋ฉด, ๊ฐ•ํ™” ํ™”๋ฉด ๋“ฑ ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์ฒ˜๋ฆฌ๋ฅผ ์—ฌ๋Ÿฌ๊ณณ์—์„œ ํ•˜๊ฒŒ๋˜๋ฏ€๋กœ UseCase๋กœ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

Lifecycle ๋Œ€์‹  ์ „๋ถ€๋‹ค UseCase๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ์•ˆ๋˜๋‚˜์š”?

ํ†ต์‹  ์ด์™ธ์—๋„ ๋ชจ๋“  ์ฒ˜๋ฆฌ๋ฅผ UseCaseํ™” ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ์ผํšŒ์„ฑ UseCase๊ฐ€ ๊ณ„์† ๋Š˜์–ด๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ๊ฐœ๋ฐœ ํšจ์œจ๋„ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๊ณตํ†ต์ ์ธ ์ฒ˜๋ฆฌ์—์„œ 2~3ํšŒ ์ด์ƒ ์ค‘๋ณต ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด ํ™•์ธ๋˜๋ฉด ๊ทธ ๋•Œ ๋งˆ๋‹ค UseCaseํ™” ํ•˜์—ฌ ์ •๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ์‹์„ ์ถ”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

์•„๋ž˜๋Š” ํ†ต์‹ ์˜ UseCase ์ƒ˜ํ”Œ์ž…๋‹ˆ๋‹ค. ํ†ต์‹ ์„ ํ•˜๊ณ  ๊ฒฐ๊ณผ๋Š” ๋ฐ›๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ํ†ต์‹  ์ค‘ UI ํ‘œ์‹œ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋“ฑ๋„ ํฌํ•จํ•ด์„œ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž(Lifecycle ๋“ฑ)๋Š” DoConnect๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊นŒ์ง€ ํฌํ•จํ•œ ํ†ต์‹  ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class TestUseCase
{
    private readonly IHttpClient _httpClient; // ํ†ต์‹  ์‹คํ–‰ ํด๋ž˜์Šค
    private readonly NetworkErrorUseCase _networkErrorUseCase; // ํ†ต์‹  ์˜ค๋ฅ˜์— ๋”ฐ๋ฅธ ํ™”๋ฉด ์ „ํ™˜ ๋“ฑ์˜ ์˜ค๋ฅ˜ ๋Œ€์ฑ…
    private readonly NetworkLoadingController _loadingController; // ํ†ต์‹  ์ค‘ ํ‘œ์‹œ

    [Inject]
    public HomePageUseCase(IHttpClient httpClient, NetworkErrorUseCase networkErrorUseCase, NetworkLoadingController loadingController)
    {
        _httpClient = httpClient;
        _networkErrorUseCase = networkErrorUseCase;
        _loadingController = loadingController;
    }

    // DoConnect๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‹คํ–‰ํ•˜๊ธฐ
    public async UniTask<TestPageLifecycle.NetworkParameter> DoConnect(CancellationToken cancellationToken) => await DoConnectInternal(cancellationToken, 0);

    // DoConnect ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ
    // ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์ด์ „๊นŒ์ง€์˜ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ๋ฐ›์•„ ์žฌ๊ท€ ์ฒ˜๋ฆฌํ•œ๋‹ค.
    private async UniTask<TestPageLifecycle.NetworkParameter> DoConnectInternal(CancellationToken cancellationToken, int retryCount)
    {
        // ํ†ต์‹  ์ค‘... ์˜ UI๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ํ†ต์‹ ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
        _loadingController.Activate();
        var connection = await _httpClient.Call<TestConnectResponse>(new TestConnectRequest(), cancellationToken);
        _loadingController.InActivate();

        // ์‹คํŒจ ์‹œ ์ฒ˜๋ฆฌ
        if (!connection.result.IsSuccess())
        {
            // ์˜ˆ๋ฅผ ๋“ค์–ด, ์œ ์ง€๋ณด์ˆ˜ ์ค‘์—๋Š” ์œ ์ง€๋ณด์ˆ˜ ํ‘œ์‹œ๋ฅผ ํ•˜๊ณ  ์ œ๋ชฉ์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.
            if (connection.response?.status.IsInMaintenanceMode ?? false)
            {
                await _networkErrorUseCase.ShowMaintenanceToTitle(connection.response?.status.error);
                return null;
            }
            
            // ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์žฌ์‹œ๋„ ์—ฌ๋ถ€๋ฅผ ์„ ํƒํ•˜๊ฒŒ ํ•œ๋‹ค.
            // ์žฌ์‹œ๋„์—๋Š” ์ตœ๋Œ€ ํšŸ์ˆ˜๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ๊ฐ•์ œ๋กœ ํƒ€์ดํ‹€์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
            var isRetry = await _networkErrorUseCase.ShowErrorWithRetry(retryCount);
            if (isRetry)
            {
                retryCount++;
                return await DoConnectInternal(cancellationToken, retryCount);
            }
            return null;
        }

        // ํ†ต์‹ ์— ์„ฑ๊ณตํ•˜๋ฉด ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
        return new TestPageLifecycle.NetworkParameter()
        {
            TestConnectResponse = result.response
        };
    }
}

Last updated