2021-05-27(Thu)

Facts (์‚ฌ์‹ค, ๊ฐ๊ด€)

  • ๊ณผ๊ธฐ๋ถ€ ์žฅ๊ด€๋‹˜ ๋ฐฉ๋ฌธ์‹œ๊ฐ„์— ๋งž์ถฐ์„œ ์ŠคํŒŒ๋ฅดํƒ€42 ํšŒ์˜์— ์ฐธ์—ฌํ–ˆ๋‹ค.

  • ์‚ฌ์ด๋“œํ”„๋กœ์ ํŠธ ํŽ˜๋ธ” ํšŒ์˜๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

  • ์ฝ”๋“œ์ˆจ 4์ฃผ์ฐจ ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

  • ์ผ์ „์— ๋ฐ˜๋‚ฉํ–ˆ๋˜ ์ฑ…๋“ค์„ ๋‹ค์‹œ ๋นŒ๋ ค์™”๋‹ค.

  • ์ปจ๋””์…˜์ด ์ข‹์ง€ ์•Š์•„์„œ ์ €๋… ์‹œ๊ฐ„์€ ํœด์‹์„ ์ทจํ–ˆ๋‹ค.

Feelings (๋Š๋‚Œ, ์ฃผ๊ด€)

์žฅ๊ด€๋‹˜ ๋ฐฉ๋ฌธ ์ผ์ •์ด ๊ฐ‘์ž๊ธฐ ์˜ค์ „์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๋ฐ”๋žŒ์— 4์‹œ๊ฐ„ ๋ฐ–์— ๋ชป ์ž์„œ ์•„์นจ์— ํ”ผ๊ณคํ–ˆ๋‹ค.

ํŽ˜๋ธ” ํšŒ์˜๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ๊ธฐํš์ž๋‹˜์ด ๋„˜๊ฒจ์ค€ ํ”Œ๋กœ์šฐ๋ฅผ ๋ณด๊ณ  ์‹œํ€€์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ทธ๋ฆฐ ๋‹ค์Œ, API์™€ DB๋ฅผ ์„ค๊ณ„ํ•  ์˜ˆ์ •์ด๋‹ค. ์ปจ๋ฒค์…˜ ๊ด€๋ จํ•ด์„œ ํ‚ค์›Œ๋“œ๋ฅผ ๋˜์กŒ์—ˆ๋Š”๋ฐ, ๋‹ค๋ฅธ ํŒ€์›๋“ค์ด ์ƒ๊ฐ๋ณด๋‹ค ๋„ˆ๋ฌด ์ž˜ ์กฐ์‚ฌํ•ด์˜ค์…”์„œ ๋†€๋ž๋‹ค. ์šฐ๋ฆฐ commit์€ type์„ ๋ช…์‹œํ•˜์ง€ ์•Š๋Š”๋Œ€์‹  branch์— ์ž‘์—…์˜ ์„ฑ๊ฒฉ์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ์‹ ๊ฒฝ์“ฐ๊ธฐ๋กœ ํ–ˆ๊ณ , git-flow ๋Œ€์‹  github-flow๋ฅผ ์šฐ์„  ์‹œ๋„ํ•ด๋ณผ ์˜ˆ์ •์ด๋‹ค. java๋Š” ๊ตฌ๊ธ€ ์ปจ๋ฒค์…˜์œผ๋กœ, API ๋ฌธ์„œ๋Š” swagger๋กœ ์ž‘์„ฑํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. ์ƒˆ๋กญ๊ฒŒ ํ•ด๋ณด๋Š” ์‹œ๋„๊ฐ€ ๋งŽ์•„์„œ ์ฆ๊ฒ๋‹ค.

์˜ค๋ธŒ์ ํŠธ, ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” ์ฑ…์„ ๋‹ค ์ฝ์ง€ ๋ชปํ•˜๊ณ  ๋ฐ˜๋‚ฉํ–ˆ์—ˆ๋Š”๋ฐ, ๋ฏธ๋ จ์ด ๋‚จ์•„์„œ ๋‹ค์‹œ ๋นŒ๋ ค์™”๋‹ค. ์–ด์„œ ๋…ํŒŒํ•ด๋ด์•ผ์ง€!

์ปจ๋””์…˜ ๋ฌธ์ œ๋กœ ์ฝ”๋“œ์ˆจ 4์ฃผ์ฐจ ๊ณผ์ œ์— ๋ชฐ์ž…ํ•˜์ง€ ๋ชปํ•œ ๋Š๋‚Œ์ด๋‹ค. ์•„์‰ฝ๋‹ค. ๋‚ด์ผ์€ ๊ผญ ๋ชฐ์ž…ํ•ด๋ณด์ž.

Findings (๋ฐฐ์šด ์ )

invocation์— ๋Œ€ํ•ด์„œ

์ฝ”๋“œ์ˆจ 4์ฃผ์ฐจ ๊ฐ•์˜๋ฅผ ๋ณต์Šตํ•˜๋Š”๋ฐ, ์•„๋ž˜ ์˜ˆ์ œ์—์„œ ๋‚˜์˜จ invocation ๋‹จ์–ด๊ฐ€ ๋‚ฏ์„ค๊ฒŒ ๋Š๊ปด์กŒ๋‹ค.

given(taskRepository.save(only(Task.class)).will(invocation -> {
  return invocation.getArgument(0);
}))

์ด ๋‹จ์–ด๋Š” ๋‹ค๋ฅธ BDDMockito ์˜ˆ์ œ์—์„œ๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋‚˜์˜จ๋‹ค.

given(phoneBookRepository.contains(momContactName))
  .willReturn(true);
given(phoneBookRepository.getPhoneNumberByContactName(momContactName))
  .will((InvocationOnMock invocation) ->
    invocation.getArgument(0).equals(momContactName) 
      ? momPhoneNumber 
      : null);
phoneBookService.search(momContactName);
then(phoneBookRepository)
  .should()
  .getPhoneNumberByContactName(momContactName);

์ผ๋‹จ ๋„ค์ด๋ฒ„ ์‚ฌ์ „์—์„œ๋Š” ์˜ ์•Œ ์ˆ˜ ์—†๋Š” ๋œป์ด ๋‚˜์˜จ๋‹ค.

invocation

  • 1.(์‹ ์„ ํ–ฅํ•œ) ๊ธฐ๋„[๊ธฐ์›], (๊ถŒํ•œ์„ ์ง€๋‹Œ ์ด๋ฅผ ํ–ฅํ•œ) ํƒ„์›[ํ˜ธ์†Œ], (ํ˜ผยท์˜๊ฐ ๋“ฑ์„ ๋น„๋Š”) ์ฃผ๋ฌธ(ๅ‘ชๆ–‡)[๊ธฐ๋„]

  • 2.(๋ฒ•์  ๊ถŒํ•œ ๋“ฑ์˜) ๋ฐœ๋™[์‹ค์‹œ]

์กฐ๊ธˆ ๋” ์ฐพ์•„๋ณด๋‹ˆ Java API ๋ฌธ์„œ์— ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ช…์‹œ๋˜์–ด ์žˆ์—ˆ๋‹ค.

public interface Invocation

A client request invocation. An invocation is a request that has been prepared and is ready for execution. Invocations provide a generic (command) interface that enables a separation of concerns between the creator and the submitter. In particular, the submitter does not need to know how the invocation was prepared, but only how it should be executed (synchronously or asynchronously) and when.

๊ทธ๋ฆฌ๊ณ  ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์—๋„ ์•„๋ž˜ ๋‚ด์šฉ์ด ๋“ค์–ด์žˆ๋Š” ๊ธ€์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  • invocation is the event of issuing the call to the method; technically - placing the method onto the stack

  • execution is the whole process of running the method - from invocation till completion. And execution time is period during which the method body runs.

์ •๋ฆฌํ•˜๋ฉด

  • invocation์€ execution์˜ ์ „๋‹จ๊ณ„๋กœ์จ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค.

  • ์ œ๋„ค๋ฆญ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

  • creator์™€ submitter์˜ ๊ด€์‹ฌ์„ ๋ถ„๋ฆฌ์‹œํ‚ฌ ๋•Œ ์š”๊ธดํ•˜๊ฒŒ ์“ฐ์ธ๋‹ค. submitter๋Š” invocation์ด ์–ด๋–ป๊ฒŒ ์ค€๋น„๋˜๋Š”์ง€ ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ๋ƒฅ invocation์„ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋˜๋Š” ๊ฒƒ!

๊ทธ๋กœ์Šคํ•ดํ‚น ๋ถ„์„

๊ทธ๋กœ์Šค ํ•ดํ‚น์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์„ฑ์žฅ์„ ์ง‘์š”ํ•˜๊ฒŒ ํŒŒ๊ณ ๋“œ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

๊ทธ๋กœ์Šค ํ•ดํ‚น์„ ์ฒ˜์Œ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ํผ๋„(Funnel) ๊ตฌ์ถ•๋ถ€ํ„ฐ ํ•˜์ž.

ํผ๋„ ๊ตฌ์ถ•์€ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค.

  • ๋น„์ฆˆ๋‹ˆ์Šค ํ๋ฆ„ ๊ทธ๋ฆฌ๊ธฐ

  • ์ฒ˜์Œ์—๋Š” ๊ฐ€๋Šฅํ•œ ์ƒ์„ธํ•˜๊ฒŒ

  • ์‹œ์ž‘์€ ํฐ ์ˆซ์ž๋ถ€ํ„ฐ

  • ๋์€ Goal์„ ๊ธฐ๋ฐ˜์œผ๋กœ

ํผ๋„ ๋ถ„์„์€ AARRR์„ ๊ธฐ๋ณธ์œผ๋กœ ์ ์šฉํ•ด๋ณด์ž. Cycle์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์„œ ์ข‹๋‹ค.

  • Acquisition(์ธ์ž…/ํš๋“): ์‹œ์ž‘์€ ๊ด‘๊ณ ๋ถ€ํ„ฐ, ์ตœ๋Œ€ํ•œ ๋งŽ์€ ์‚ฌ๋žŒ์—๊ฒŒ ์„œ๋น„์Šค ๋…ธ์ถœ์‹œํ‚ค๊ธฐ

    • KPI: ๋…ธ์ถœ๋Ÿ‰, ํด๋ฆญ๋Ÿ‰, CTR, CVR, Conversion ๋“ฑ

  • Activation(ํ™œ์„ฑํ™”): ๋ณธ๊ฒฉ์ ์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ์ด์šฉ

    • KPI: DAU, WAU, MAU

  • Retention(์œ ์ง€, ์žฌ๋ฐฉ๋ฌธ): ์ง€์†์ ์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ์ด์šฉ

    • KPI: Retention Ratio, Life Time, ์žฌ๋ฐฉ๋ฌธ์œจ

  • Revenue(๋งค์ถœ,์ˆ˜์ต): ์œ ์ €๊ฐ€ ์ˆ˜์ต/๋งค์ถœ์„ ๊ฐ€์ ธ์˜ด

    • KPI: ๋งค์ถœ์•ก, eCPM, ์ด ๊ด‘๊ณ  ๋…ธ์ถœ๋Ÿ‰

  • Referrer(์ถ”์ฒœ): ์œ ์ €๊ฐ€ ๋‹ค๋ฅธ ์œ ์ €๋“ค์„ ๋ฐ๋ ค์˜ด

    • KPI: ์‹ ๊ทœ์ธ์ž…์ค‘ ์ถ”์ฒœ์„ ํ†ตํ•œ ์ธ์ž… ๋น„์œจ, ๊ฐ€์ž…์ž๋‹น ์ถ”์ฒœ ๋น„์œจ

์ฐธ๊ณ 

๊ทธ๋กœ์Šคํ•ดํ‚น ๊ธฐ์ดˆ

Affimation (์ž๊ธฐ ์„ ์–ธ)

  • ๋‚˜๋Š” ํ•™์— ๋ชฐ์ž…ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋‹ค.

Last updated