๐Ÿš€ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐํ™”์™€ ๊ด€๋ฆฌ ์ „๋žต ๐Ÿ› ๏ธ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐํ™”์™€ ๊ด€๋ฆฌ ์ „๋žต ๐Ÿ› ๏ธ

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์ฝ”๋”ฉ ๋งˆ๋ฒ•์‚ฌ ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ ์ •๋ง ํฅ๋ฏธ์ง„์ง„ํ•œ ์ฃผ์ œ๋กœ ์—ฌ๋Ÿฌ๋ถ„๊ณผ ํ•จ๊ป˜ ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์กฐํ™”ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ํŒŒํ—ค์ณ ๋ณผ ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ๊ฑฐ๋Œ€ํ•œ ๋ ˆ๊ณ  ์„ฑ์„ ์Œ“๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๋„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ตฌ์กฐํ™”ํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ๋งŒ ์šฐ๋ฆฌ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ฌด๋„ˆ์ง€์ง€ ์•Š๊ณ  ๋๊นŒ์ง€ ์™„์„ฑ๋  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ๐Ÿ˜‰

์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ ์žฌ๋Šฅ๋„ท(https://www.jaenung.net)์ด๋ผ๋Š” ์‚ฌ์ดํŠธ๋ฅผ ๋“ค์–ด๋ณด์…จ๋‚˜์š”? ์ด๊ณณ์€ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ๋ฐ์š”, ํ”„๋กœ๊ทธ๋ž˜๋ฐ skills๋„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์˜ค๋Š˜ ๋ฐฐ์šธ ๋‚ด์šฉ์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„๋„ ์žฌ๋Šฅ๋„ท์—์„œ C++ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐํ™” ์ „๋ฌธ๊ฐ€๋กœ ํ™œ์•ฝํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐ŸŒŸ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ์šฐ๋ฆฌ์˜ ์—ฌ์ •์€ ๊ธธ๊ณ ๋„ ํ—˜๋‚œํ•  ํ…Œ์ง€๋งŒ, ๋๊นŒ์ง€ ํ•จ๊ป˜ ๊ฐ€๋ฉด ๋ฐ˜๋“œ์‹œ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ์˜ ๋‹ฌ์ธ์ด ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ์ถœ๋ฐœ~! ๐Ÿš—๐Ÿ’จ

1. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ์˜ ๊ธฐ์ดˆ: ํด๋” ๊ตฌ์กฐ์™€ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜ ๐Ÿ—‚๏ธ

๋จผ์ €, ์šฐ๋ฆฌ์˜ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ํƒ„ํƒ„ํ•œ ๊ธฐ์ดˆ๋ฅผ ๋‹ค์ ธ๋ณผ๊นŒ์š”? ๋งˆ์น˜ ์ง‘์„ ์ง€์„ ๋•Œ ๊ธฐ์ดˆ๊ณต์‚ฌ๊ฐ€ ์ค‘์š”ํ•˜๋“ฏ, ํ”„๋กœ์ ํŠธ์˜ ํด๋” ๊ตฌ์กฐ์™€ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์€ ์ „์ฒด ํ”„๋กœ์ ํŠธ์˜ ์•ˆ์ •์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์„ ์ขŒ์šฐํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

1.1 ํด๋” ๊ตฌ์กฐ ์„ค๊ณ„ํ•˜๊ธฐ ๐Ÿ“

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์˜ ํด๋” ๊ตฌ์กฐ๋Š” ๋งˆ์น˜ ๋„์‹œ์˜ ๊ตฌํš์„ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐ ๊ตฌ์—ญ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์œผ๋ฉด, ๊ทธ ์•ˆ์—์„œ ๋ฌด์—‡์„ ์ฐพ์•„์•ผ ํ• ์ง€ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์ฃ . ์—ฌ๊ธฐ ์ถ”์ฒœํ•˜๋Š” ๊ธฐ๋ณธ ํด๋” ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณผ๊นŒ์š”?

project_root/
โ”‚
โ”œโ”€โ”€ src/                # ์†Œ์Šค ์ฝ”๋“œ
โ”‚   โ”œโ”€โ”€ core/           # ํ•ต์‹ฌ ๊ธฐ๋Šฅ
โ”‚   โ”œโ”€โ”€ modules/        # ๋…๋ฆฝ์ ์ธ ๋ชจ๋“ˆ๋“ค
โ”‚   โ””โ”€โ”€ utils/          # ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค
โ”‚
โ”œโ”€โ”€ include/            # ํ—ค๋” ํŒŒ์ผ
โ”‚   โ”œโ”€โ”€ public/         # ์™ธ๋ถ€์— ๊ณต๊ฐœ๋  ํ—ค๋”
โ”‚   โ””โ”€โ”€ private/        # ๋‚ด๋ถ€์šฉ ํ—ค๋”
โ”‚
โ”œโ”€โ”€ tests/              # ํ…Œ์ŠคํŠธ ์ฝ”๋“œ
โ”‚   โ”œโ”€โ”€ unit/           # ๋‹จ์œ„ ํ…Œ์ŠคํŠธ
โ”‚   โ””โ”€โ”€ integration/    # ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ
โ”‚
โ”œโ”€โ”€ docs/               # ๋ฌธ์„œ
โ”‚
โ”œโ”€โ”€ libs/               # ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
โ”‚
โ”œโ”€โ”€ build/              # ๋นŒ๋“œ ์ถœ๋ ฅ (git ignore)
โ”‚
โ””โ”€โ”€ scripts/            # ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ, ์œ ํ‹ธ๋ฆฌํ‹ฐ ์Šคํฌ๋ฆฝํŠธ
    

์ด๋Ÿฐ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋ฉด, ํ”„๋กœ์ ํŠธ์˜ ๊ฐ ๋ถ€๋ถ„์ด ์–ด๋””์— ์œ„์น˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•ด์ง‘๋‹ˆ๋‹ค. src ํด๋”๋Š” ์‹ค์ œ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ, include ํด๋”๋Š” ํ—ค๋” ํŒŒ์ผ์„ ๋‹ด๋‹นํ•˜์ฃ . tests ํด๋”์—์„œ๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , docs์—์„œ๋Š” ํ”„๋กœ์ ํŠธ ๋ฌธ์„œ๋ฅผ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.

์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์˜๋ขฐ๋ฐ›์•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณผ๊นŒ์š”? ์ด๋Ÿฐ ์ฒด๊ณ„์ ์ธ ํด๋” ๊ตฌ์กฐ๋ฅผ ์ œ์•ˆํ•œ๋‹ค๋ฉด, ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ „๋ฌธ์„ฑ์— ๊ฐํƒ„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Ž

1.2 ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜: ์ผ๊ด€์„ฑ์˜ ํž˜ ๐Ÿท๏ธ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ์— ์ด๋ฆ„์„ ๋ถ™์—ฌ์ค„ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์€ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋งˆ๋ฒ•์˜ ์—ด์‡ ์™€ ๊ฐ™์•„์š”. C++์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์„ ์‚ดํŽด๋ณผ๊นŒ์š”?

  • ํŒŒ์ผ๋ช…: ์†Œ๋ฌธ์ž์™€ ์–ธ๋”์Šค์ฝ”์–ด ์‚ฌ์šฉ (์˜ˆ: user_management.cpp, data_processor.h)
  • ํด๋ž˜์Šค๋ช…: ํŒŒ์Šค์นผ ์ผ€์ด์Šค ์‚ฌ์šฉ (์˜ˆ: class UserManager, class DataProcessor)
  • ํ•จ์ˆ˜๋ช…: ์นด๋ฉœ ์ผ€์ด์Šค ์‚ฌ์šฉ (์˜ˆ: void processData(), int getUserCount())
  • ๋ณ€์ˆ˜๋ช…: ์†Œ๋ฌธ์ž์™€ ์–ธ๋”์Šค์ฝ”์–ด ์‚ฌ์šฉ (์˜ˆ: int user_count, string file_name)
  • ์ƒ์ˆ˜: ๋Œ€๋ฌธ์ž์™€ ์–ธ๋”์Šค์ฝ”์–ด ์‚ฌ์šฉ (์˜ˆ: const int MAX_USERS = 100)
  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค: ์†Œ๋ฌธ์ž ์‚ฌ์šฉ (์˜ˆ: namespace utils)

์ผ๊ด€๋œ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์ด ๊ฐ ์š”์†Œ์˜ ์—ญํ• ์„ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์น˜ ์ฑ…์˜ ๋ชฉ์ฐจ๋ฅผ ๋ณด๊ณ  ๋‚ด์šฉ์„ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . ์—ฌ๋Ÿฌ๋ถ„์˜ ํŒ€์›๋“ค๋„ ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

์žฌ๋Šฅ๋„ท์—์„œ ํ˜‘์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค๋ฉด, ์ด๋Ÿฐ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์„ ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ•˜์„ธ์š”. ๋ชจ๋‘๊ฐ€ ๊ฐ™์€ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉด, ํ”„๋กœ์ ํŠธ๊ฐ€ ํ›จ์”ฌ ๋” ์ฒด๊ณ„์ ์œผ๋กœ ์ง„ํ–‰๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿ‘ฅ

1.3 ์‹ค์ „ ํŒ: ์ž๋™ํ™”์˜ ๋งˆ๋ฒ• ๐Ÿง™โ€โ™‚๏ธ

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

์ž๋™ํ™” ๋„๊ตฌ ํ™œ์šฉํ•˜๊ธฐ:

  • Clang-Format: ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์ž๋™์œผ๋กœ ๋งž์ถฐ์ฃผ๋Š” ๋„๊ตฌ
  • CMake: ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๊ณ  ๋นŒ๋“œ ๊ณผ์ •์„ ์ž๋™ํ™”
  • Git Hooks: ์ปค๋ฐ‹ ์ „ ์ฝ”๋“œ ์Šคํƒ€์ผ ๊ฒ€์‚ฌ๋ฅผ ์ž๋™ํ™”

์ด๋Ÿฐ ๋„๊ตฌ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ๋Š” ๋งˆ์น˜ ์Šค์Šค๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ๊ฑฐ์˜ˆ์š”. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ฃผ๋ฐ›์•˜์„ ๋•Œ, ์ด๋Ÿฐ ์ž๋™ํ™” ๋„๊ตฌ๋“ค์„ ํ™œ์šฉํ•œ๋‹ค๋ฉด ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ „๋ฌธ์„ฑ์— ๊ฐํƒ„ํ•  ๊ฑฐ์˜ˆ์š”! ๐ŸŒŸ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ํ”„๋กœ์ ํŠธ๋Š” ํŠผํŠผํ•œ ๊ธฐ์ดˆ๋ฅผ ๊ฐ–์ถ”๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด ๊ธฐ์ดˆ ์œ„์— ์–ด๋–ป๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™”ํ• ์ง€ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ฃ . ์ค€๋น„๋˜์…จ๋‚˜์š”? ๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€ ๋ด…์‹œ๋‹ค! ๐ŸŠโ€โ™‚๏ธ

2. ๋ชจ๋“ˆํ™”์™€ ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„: ๋ ˆ๊ณ  ๋ธ”๋ก์ฒ˜๋Ÿผ ์กฐ๋ฆฝํ•˜๊ธฐ ๐Ÿงฑ

์—ฌ๋Ÿฌ๋ถ„, ๋ ˆ๊ณ ๋กœ ๊ฑฐ๋Œ€ํ•œ ์„ฑ์„ ๋งŒ๋“ค์–ด๋ณธ ์  ์žˆ๋‚˜์š”? ๊ฐ๊ฐ์˜ ๋ธ”๋ก์€ ์ž‘์ง€๋งŒ, ์ด ๋ธ”๋ก๋“ค์„ ์ž˜ ์กฐํ•ฉํ•˜๋ฉด ๋†€๋ผ์šด ๊ตฌ์กฐ๋ฌผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ . C++ ํ”„๋กœ์ ํŠธ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ž‘์€ ๋ชจ๋“ˆ๋“ค์„ ์ž˜ ์„ค๊ณ„ํ•˜๊ณ  ์กฐํ•ฉํ•˜๋ฉด, ๋ณต์žกํ•œ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๋„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

2.1 ๋ชจ๋“ˆํ™”์˜ ์›์น™: ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ (SRP) ๐ŸŽฏ

๋‹จ์ผ ์ฑ…์ž„ ์›์น™(Single Responsibility Principle, SRP)์€ ๋ชจ๋“ˆํ™”์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ์ด ์›์น™์— ๋”ฐ๋ฅด๋ฉด, ๊ฐ ๋ชจ๋“ˆ์€ ๋‹จ ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ์„ ๊ฐ€์ ธ์•ผ ํ•ด์š”. ๋งˆ์น˜ ์ฃผ๋ฐฉ์—์„œ ๊ฐ ๋„๊ตฌ๊ฐ€ ํŠน์ • ์—ญํ• ๋งŒ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ .

SRP ์ ์šฉ ์˜ˆ์‹œ:


// ์ž˜๋ชป๋œ ์˜ˆ: ์—ฌ๋Ÿฌ ์ฑ…์ž„์„ ๊ฐ€์ง„ ํด๋ž˜์Šค
class UserManager {
public:
    void createUser(const User& user);
    void deleteUser(int userId);
    void sendEmail(const User& user, const std::string& message);
    void generateReport();
};

// ์ข‹์€ ์˜ˆ: ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•œ ํด๋ž˜์Šค๋“ค
class UserManager {
public:
    void createUser(const User& user);
    void deleteUser(int userId);
};

class EmailService {
public:
    void sendEmail(const User& user, const std::string& message);
};

class ReportGenerator {
public:
    void generateReport();
};
    

์œ„ ์˜ˆ์‹œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ๊ฐ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์ฑ…์ž„๋งŒ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง€๊ณ , ์ˆ˜์ •์ด ํ•„์š”ํ•  ๋•Œ ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๋ถ€๋ถ„์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”.

์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ๋ชจ๋“ˆํ™” ์›์น™์„ ์ ์šฉํ•˜๋ฉด ํ˜‘์—…์ด ํ›จ์”ฌ ์ˆ˜์›”ํ•ด์งˆ ๊ฑฐ์˜ˆ์š”. ๊ฐ ํŒ€์›์ด ํŠน์ • ๋ชจ๋“ˆ์„ ๋‹ด๋‹นํ•˜๋ฉด, ์„œ๋กœ์˜ ์ž‘์—…์ด ๊ฒน์น˜์ง€ ์•Š๊ณ  ํšจ์œจ์ ์œผ๋กœ ์ง„ํ–‰๋  ์ˆ˜ ์žˆ์ฃ . ๐Ÿ˜Š

2.2 ์ธํ„ฐํŽ˜์ด์Šค์™€ ์ถ”์ƒํ™”: ์œ ์—ฐ์„ฑ์˜ ๋น„๊ฒฐ ๐ŸŒˆ

๋ชจ๋“ˆํ™”์˜ ๋‹ค์Œ ๋‹จ๊ณ„๋Š” ์ธํ„ฐํŽ˜์ด์Šค์™€ ์ถ”์ƒํ™”์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์˜ ์—ฐ๊ฒฐ ๋ถ€์œ„์™€ ๊ฐ™์•„์š”. ํ‘œ์ค€ํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ๋ชจ๋“ˆ์„ ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•˜๊ณ  ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์ฃ .

์ถ”์ƒ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค ์˜ˆ์‹œ:


// ์ถ”์ƒ ํด๋ž˜์Šค (์ธํ„ฐํŽ˜์ด์Šค) ์ •์˜
class ILogger {
public:
    virtual void log(const std::string& message) = 0;
    virtual ~ILogger() = default;
};

// ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„
class ConsoleLogger : public ILogger {
public:
    void log(const std::string& message) override {
        std::cout << "Console: " << message << std::endl;
    }
};

class FileLogger : public ILogger {
public:
    void log(const std::string& message) override {
        // ํŒŒ์ผ์— ๋กœ๊ทธ ์“ฐ๊ธฐ ๊ตฌํ˜„
    }
};

// ์‚ฌ์šฉ ์˜ˆ
void doSomething(ILogger& logger) {
    // ... some operations ...
    logger.log("Operation completed");
}

int main() {
    ConsoleLogger consoleLogger;
    FileLogger fileLogger;

    doSomething(consoleLogger);
    doSomething(fileLogger);
}
    

์ด๋ ‡๊ฒŒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ์‰ฝ๊ฒŒ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๊น… ๋ฐฉ์‹์„ ์ฝ˜์†”์—์„œ ํŒŒ์ผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹จ์ˆœํžˆ ๋‹ค๋ฅธ ๋กœ๊ฑฐ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ผ์š”. ์ฝ”๋“œ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์€ ์ „ํ˜€ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์ฃ !

์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ์œ ์—ฐํ•œ ์„ค๊ณ„๋ฅผ ์ ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ ๋ณ€๊ฒฝ์—๋„ ์‰ฝ๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ๊ทธ๋ฆฌ๊ณ  ์ด๋Š” ๊ณง ์—ฌ๋Ÿฌ๋ถ„์˜ ์ „๋ฌธ์„ฑ์„ ์ธ์ •๋ฐ›๋Š” ๊ธธ์ด ๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿ†

2.3 ์˜์กด์„ฑ ์ฃผ์ž…: ๋ชจ๋“ˆ ๊ฐ„ ๊ฒฐํ•ฉ๋„ ๋‚ฎ์ถ”๊ธฐ ๐Ÿ’‰

์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)์€ ๋ชจ๋“ˆ ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ์กฐ๋ฆฝํ•  ๋•Œ, ๊ฐ ๋ธ”๋ก์ด ์„œ๋กœ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์™ธ๋ถ€์—์„œ ์ œ๊ณต๋ฐ›๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

์˜์กด์„ฑ ์ฃผ์ž… ์˜ˆ์‹œ:


// ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
class UserService {
private:
    DatabaseConnection db;  // ์ง์ ‘ ์ƒ์„ฑ

public:
    UserService() : db(DatabaseConnection()) {}
    // ... ๋ฉ”์„œ๋“œ๋“ค ...
};

// ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ
class UserService {
private:
    DatabaseConnection& db;  // ์ฐธ์กฐ๋กœ ๋ฐ›์Œ

public:
    UserService(DatabaseConnection& database) : db(database) {}
    // ... ๋ฉ”์„œ๋“œ๋“ค ...
};

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    DatabaseConnection realDb;
    UserService userService(realDb);

    // ํ…Œ์ŠคํŠธ ์‹œ
    MockDatabase mockDb;
    UserService testService(mockDb);
}
    

์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋ชจ๋“ˆ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋Œ€์‹  ๋ชฉ(mock) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์ฃ .

์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ์˜์กด์„ฑ ์ฃผ์ž… ํŒจํ„ด์„ ์ ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ํ’ˆ์งˆ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋  ๊ฑฐ์˜ˆ์š”. ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์œ ์—ฐํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฌ์šด์ง€ ๋ณด๊ณ  ๊ฐํƒ„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜ƒ

2.4 ์‹ค์ „ ํŒ: ๋ชจ๋“ˆ ๊ฐ„ ํ†ต์‹  ์„ค๊ณ„ํ•˜๊ธฐ ๐Ÿ“ก

๋ชจ๋“ˆ์„ ์ž˜ ์„ค๊ณ„ํ–ˆ๋‹ค๋ฉด, ์ด์ œ ์ด ๋ชจ๋“ˆ๋“ค์ด ์–ด๋–ป๊ฒŒ ์„œ๋กœ ํ†ต์‹ ํ• ์ง€ ๊ณ ๋ฏผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ๋“œ๋ฆด๊ฒŒ์š”:

  • ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ: ๋ชจ๋“ˆ ๊ฐ„ ์ง์ ‘์ ์ธ ์˜์กด์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”.
  • ๋ฉ”์‹œ์ง€ ํ: ๋น„๋™๊ธฐ ์ž‘์—…์ด ๋งŽ์€ ๊ฒฝ์šฐ, ๋ฉ”์‹œ์ง€ ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ ๊ฐ„ ํ†ต์‹ ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Facade ํŒจํ„ด: ๋ณต์žกํ•œ ์„œ๋ธŒ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ๋‹จ์ˆœํ™”๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋ชจ๋“ˆ ๊ฐ„ ํ†ต์‹ ์„ ๊ฐ„์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ํ†ต์‹  ๋ฐฉ์‹์„ ์ ์ ˆํžˆ ์กฐํ•ฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ๋Š” ๋งˆ์น˜ ์ž˜ ์กฐ์œจ๋œ ์˜ค์ผ€์ŠคํŠธ๋ผ์ฒ˜๋Ÿผ ์œ ๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•  ๊ฑฐ์˜ˆ์š”. ๐ŸŽผ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ํ”„๋กœ์ ํŠธ๋Š” ์ž˜ ๋ชจ๋“ˆํ™”๋˜๊ณ  ์œ ์—ฐํ•˜๊ฒŒ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹ˆ์—์š”! ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์„ค๊ณ„๋œ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ํšจ๊ณผ์ ์œผ๋กœ ๋นŒ๋“œํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ฃ . ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ณ„์†ํ•ด์„œ ๋‚˜์•„๊ฐ€๋ด…์‹œ๋‹ค! ๐Ÿš€

3. ๋นŒ๋“œ ์‹œ์Šคํ…œ๊ณผ ์˜์กด์„ฑ ๊ด€๋ฆฌ: ํ”„๋กœ์ ํŠธ์˜ ์‹ฌ์žฅ ๐Ÿ’“

์—ฌ๋Ÿฌ๋ถ„, ์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๋Š” ๋ฉ‹์ง„ ๋ ˆ๊ณ  ๋ธ”๋ก๋“ค์„ ๋งŒ๋“ค์—ˆ์–ด์š”. ์ด์ œ ์ด ๋ธ”๋ก๋“ค์„ ์–ด๋–ป๊ฒŒ ์กฐ๋ฆฝํ•˜๊ณ  ๊ด€๋ฆฌํ• ์ง€ ์•Œ์•„๋ณผ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ๋นŒ๋“œ ์‹œ์Šคํ…œ๊ณผ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋Š” ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ์˜ ์‹ฌ์žฅ๊ณผ๋„ ๊ฐ™์•„์š”. ์ด ๋ถ€๋ถ„์„ ์ž˜ ๋‹ค๋ฃจ๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ๋Š” ๊ฑด๊ฐ•ํ•˜๊ฒŒ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿ˜Š

3.1 CMake: ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋นŒ๋“œ์˜ ๋งˆ๋ฒ•์‚ฌ ๐Ÿง™โ€โ™‚๏ธ

CMake๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋นŒ๋“œ ๋„๊ตฌ์˜ ๊ฐ•์ž์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ์กฐ๋ฆฝํ•  ์ˆ˜ ์žˆ๋Š” ๋งŒ๋Šฅ ๋„๊ตฌ ๊ฐ™์ฃ . CMake๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ๊ณผ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•ด ์ผ๊ด€๋œ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

CMake ๊ธฐ๋ณธ ๊ตฌ์กฐ:


# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyAwesomeProject)

# C++17 ํ‘œ์ค€ ์‚ฌ์šฉ
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# ์†Œ์Šค ํŒŒ์ผ ์ถ”๊ฐ€
add_executable(MyApp 
    src/main.cpp
    src/user_manager.cpp
    src/data_processor.cpp
)

# ํ—ค๋” ํŒŒ์ผ ๊ฒฝ๋กœ ์ถ”๊ฐ€
target_include_directories(MyApp PRIVATE include)

# ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋งํฌ (์˜ˆ: Boost)
find_package(Boost REQUIRED COMPONENTS system filesystem)
target_link_libraries(MyApp PRIVATE Boost::system Boost::filesystem)
    

CMake๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์˜ ๊ตฌ์กฐ์™€ ์˜์กด์„ฑ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์œ„ ์˜ˆ์‹œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ์†Œ์Šค ํŒŒ์ผ, ํ—ค๋” ๊ฒฝ๋กœ, ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์ฃ . ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ค๋ช…์„œ์™€ ๊ฐ™์•„์š”. ๋ˆ„๊ตฌ๋‚˜ ์ด ์„ค๋ช…์„œ๋งŒ ์žˆ์œผ๋ฉด ํ”„๋กœ์ ํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค!

์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•  ๋•Œ, CMake๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋นŒ๋“œํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ์ด๋Š” ํ˜‘์—…๊ณผ ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ํ›จ์”ฌ ์ˆ˜์›”ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ๐Ÿ‘ฅ

3.2 ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž: Conan์˜ ๋งˆ๋ฒ• ๐Ÿงณ

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์˜์กด์„ฑ ๊ด€๋ฆฌ๊ฐ€ ํฐ ๋„์ „์ด ๋  ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๊ธฐ์„œ Conan์ด๋ผ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค! Conan์€ C++์šฉ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋กœ, ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ธํŠธ๋ฅผ ์ฃผ๋ฌธํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

Conan ์‚ฌ์šฉ ์˜ˆ์‹œ:


# conanfile.txt
[requires]
boost/1.75.0
poco/1.9.4
nlohmann_json/3.9.1

[generators]
cmake
    

์ด๋ ‡๊ฒŒ conanfile.txt๋ฅผ ์ž‘์„ฑํ•˜๋ฉด, Conan์ด ์ž๋™์œผ๋กœ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ CMake์™€ ํ†ตํ•ฉํ•˜๋ฉด, ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋”์šฑ ๋งค๋„๋Ÿฌ์›Œ์ ธ์š”!

Conan์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด์„ฑ ๊ด€๋ฆฌ์— ๋“ค์ด๋Š” ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ํšจ์œจ์ ์ธ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ „๋ฌธ์„ฑ์— ๊ฐํƒ„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Ž

3.3 ์ง€์†์  ํ†ตํ•ฉ (CI): ์ž๋™ํ™”์˜ ํž˜ ๐Ÿค–

์ง€์†์  ํ†ตํ•ฉ(Continuous Integration, CI)์€ ํ˜„๋Œ€ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์˜ ํ•ต์‹ฌ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๊ณต์žฅ์—์„œ ๋ชจ๋“  ๋ธ”๋ก์ด ์ œ๋Œ€๋กœ ๋งž๋Š”์ง€ ์ž๋™์œผ๋กœ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”. CI๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž์ฃผ, ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GitHub Actions๋ฅผ ์ด์šฉํ•œ CI ์„ค์ • ์˜ˆ์‹œ:


# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    
    - name: Install dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y cmake
        pip install conan
    
    - name: Configure Conan
      run: |
        conan install . --build=missing
    
    - name: Configure CMake
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release
    
    - name: Build
      run: cmake --build ${{github.workspace}}/build --config Release
    
    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest -C Release
    

์ด๋Ÿฐ CI ์„ค์ •์„ ํ†ตํ•ด, ์ฝ”๋“œ๋ฅผ ํ‘ธ์‹œํ•˜๊ฑฐ๋‚˜ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ๋นŒ๋“œ์™€ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ ˆ๊ณ  ์„ฑ์„ ์ž๋™์œผ๋กœ ๊ฒ€์‚ฌํ•˜๊ณ  ๋ณด์™„ํ•ด์ฃผ๋Š” ๋กœ๋ด‡ ๊ฐ™์•„์š”!

CI๋ฅผ ๋„์ž…ํ•˜๋ฉด ๋ฒ„๊ทธ๋ฅผ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•˜๊ณ , ์ฝ”๋“œ ํ’ˆ์งˆ์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, CI๋ฅผ ์ ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋†’์€ ์‹ ๋ขฐ๋„๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์–ด์š”. "์šฐ๋ฆฌ ํŒ€์€ ํ•ญ์ƒ ์ตœ๊ณ  ํ’ˆ์งˆ์˜ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค!"๋ผ๊ณ  ์ž์‹  ์žˆ๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ๐Ÿ˜‰

3.4 ์‹ค์ „ ํŒ: ๋นŒ๋“œ ์ตœ์ ํ™”ํ•˜๊ธฐ ๐Ÿš€

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”. ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”! ์—ฌ๊ธฐ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ์†Œ๊ฐœํ•ด๋“œ๋ฆด๊ฒŒ์š”:

  • ํ”„๋ฆฌ์ปดํŒŒ์ผ๋“œ ํ—ค๋”(PCH) ์‚ฌ์šฉ: ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ—ค๋” ํŒŒ์ผ์„ ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผํ•˜์—ฌ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์œ ๋‹ˆํ‹ฐ ๋นŒ๋“œ(Unity Build) ํ™œ์šฉ: ์—ฌ๋Ÿฌ ์†Œ์Šค ํŒŒ์ผ์„ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ ์ปดํŒŒ์ผํ•จ์œผ๋กœ์จ ์ „์ฒด ๋นŒ๋“œ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ณ‘๋ ฌ ๋นŒ๋“œ ํ™œ์„ฑํ™”: CMake์˜ -j ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ๋ฉ€ํ‹ฐ์ฝ”์–ด๋ฅผ ํ™œ์šฉํ•œ ๋ณ‘๋ ฌ ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์ฆ๋ถ„ ๋นŒ๋“œ ์ตœ์ ํ™”: ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋นŒ๋“œํ•˜๋„๋ก ์˜์กด์„ฑ์„ ์ž˜ ๊ด€๋ฆฌํ•˜์„ธ์š”.

์ด๋Ÿฐ ์ตœ์ ํ™” ๊ธฐ๋ฒ•๋“ค์„ ์ ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ๋Š” ๋งˆ์น˜ ์ดˆ์Œ์† ์ œํŠธ๊ธฐ์ฒ˜๋Ÿผ ๋น ๋ฅด๊ฒŒ ๋นŒ๋“œ๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿ›ซ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ํ”„๋กœ์ ํŠธ๋Š” ํŠผํŠผํ•œ ๊ธฐ์ดˆ ์œ„์— ์ž˜ ๋ชจ๋“ˆํ™”๋˜๊ณ , ํšจ์œจ์ ์œผ๋กœ ๋นŒ๋“œ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ–์ถ”๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹ˆ์—์š”! ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ํšจ๊ณผ์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ’ˆ์งˆ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ฃ . ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ณ„์†ํ•ด์„œ ๋‚˜์•„๊ฐ€๋ด…์‹œ๋‹ค! ๐Ÿš€

4. ํ…Œ์ŠคํŠธ์™€ ํ’ˆ์งˆ ๊ด€๋ฆฌ: ๊ฒฌ๊ณ ํ•œ ์„ฑ์„ ์Œ“์•„๋ผ ๐Ÿฐ

์—ฌ๋Ÿฌ๋ถ„, ์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๋Š” ๋ฉ‹์ง„ ๋ ˆ๊ณ  ์„ฑ์„ ์„ค๊ณ„ํ•˜๊ณ  ์กฐ๋ฆฝํ–ˆ์–ด์š”. ํ•˜์ง€๋งŒ ์ด ์„ฑ์ด ์ •๋ง ํŠผํŠผํ•œ์ง€, ๋ชจ๋“  ๋ถ€๋ถ„์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ ํ…Œ์ŠคํŠธ์™€ ํ’ˆ์งˆ ๊ด€๋ฆฌ์˜ ์ค‘์š”์„ฑ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ๋ชจ๋“  ๋ธ”๋ก๊ณผ ๊ธฐ๋Šฅ์„ ๊ผผ๊ผผํžˆ ์ ๊ฒ€ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๋„ ์ฒ ์ €ํžˆ ํ…Œ์ŠคํŠธํ•˜๊ณ  ๊ด€๋ฆฌํ•ด์•ผ ํ•ด์š”. ๐Ÿ˜Š

4.1 ๋‹จ์œ„ ํ…Œ์ŠคํŠธ: ๊ธฐ๋ณธ ์ค‘์˜ ๊ธฐ๋ณธ ๐Ÿงช

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์ฝ”๋“œ์˜ ๊ฐ€์žฅ ์ž‘์€ ๋‹จ์œ„(๋ณดํ†ต ํ•จ์ˆ˜๋‚˜ ๋ฉ”์„œ๋“œ)๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํ’ˆ์งˆ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

Google Test๋ฅผ ์‚ฌ์šฉํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์˜ˆ์‹œ:


#include <gtest/gtest.h>
#include "user_manager.h"

TEST(UserManagerTest, CreateUser) {
    UserManager manager;
    User user{"John Doe", "john@example.com"};
    
    EXPECT_TRUE(manager.createUser(user));
    EXPECT_EQ(manager.getUserCount(), 1);
    
    User retrievedUser = manager.getUser("john@example.com");
    EXPECT_EQ(retrievedUser.name, "John Doe");
    EXPECT_EQ(retrievedUser.email, "john@example.com");
}
    

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ฐ ๊ธฐ๋Šฅ์ด ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋˜ํ•œ, ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์—ฌ์ „ํžˆ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์ฃ . ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ฒ ์ €ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๋ณด์žฅํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋ฌด๊ธฐ๊ฐ€ ๋  ๊ฑฐ์˜ˆ์š”! ๐Ÿ’ช

4.2 ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ: ๋ถ€ํ’ˆ๋“ค์˜ ์กฐํ™” ๐ŸŽญ

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋Š” ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ํ•จ๊ป˜ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์„ ์กฐ๋ฆฝํ•œ ํ›„, ์ „์ฒด์ ์œผ๋กœ ์ž˜ ๋งž๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์˜ˆ์‹œ:


TEST(UserSystemIntegrationTest, CreateAndAuthenticateUser) {
    UserManager userManager;
    AuthenticationService authService(userManager);
    
    User user{"Jane Doe", "jane@example.com", "password123"};
    
    EXPECT_TRUE(userManager.createUser(user));
    EXPECT_TRUE(authService.authenticate("jane@example.com", "password123"));
    EXPECT_FALSE(authService.authenticate("jane@example.com", "wrongpassword"));
}
    

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ํ•จ๊ป˜ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ์‹ค์ œ ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

4.3 ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ: ์†๋„์™€ ํšจ์œจ์„ฑ ์ฒดํฌ ๐ŸŽ๏ธ

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์„ฑ๋Šฅ๋„ ์ค‘์š”ํ•œ ํ’ˆ์งˆ ์ง€ํ‘œ์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์ด ์–ผ๋งˆ๋‚˜ ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

Google Benchmark๋ฅผ ์‚ฌ์šฉํ•œ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ์˜ˆ์‹œ:


#include <benchmark/benchmark.h>
#include "data_processor.h"

static void BM_DataProcessing(benchmark::State& state) {
    DataProcessor processor;
    std::vector<int> data(state.range(0));
    
    for (auto _ : state) {
        processor.processData(data);
    }
    
    state.SetComplexityN(state.range(0));
}

BENCHMARK(BM_DataProcessing)->Range(8, 8<<10)->Complexity();
    

์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณ‘๋ชฉ ์ง€์ ์„ ์ฐพ๊ณ  ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ์ œ์‹œํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ํšจ์œจ์ ์ธ์ง€ ํ•œ๋ˆˆ์— ์•Œ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿš€

4.4 ์ฝ”๋“œ ํ’ˆ์งˆ ๋„๊ตฌ: ์ž๋™ํ™”๋œ ํ’ˆ์งˆ ๊ด€๋ฆฌ ๐Ÿ› ๏ธ

์ฝ”๋“œ ํ’ˆ์งˆ์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์ž๋™ํ™” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์„ ์ž๋™์œผ๋กœ ๊ฒ€์‚ฌํ•˜๊ณ  ๋‹ฆ์•„์ฃผ๋Š” ๊ธฐ๊ณ„์™€ ๊ฐ™์•„์š”!

  • ์ •์  ๋ถ„์„ ๋„๊ตฌ: Clang-Tidy, Cppcheck ๋“ฑ์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ์˜ ์ž ์žฌ์  ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์–ด์š”.
  • ์ฝ”๋“œ ํฌ๋งทํ„ฐ: Clang-Format์„ ์‚ฌ์šฉํ•ด ์ผ๊ด€๋œ ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์‚ฌ: Valgrind๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์–ด์š”.
  • ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€: gcov๋‚˜ lcov๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ์–ผ๋งˆ๋‚˜ ์ปค๋ฒ„ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๋„๊ตฌ๋“ค์„ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜๋ฉด, ์ฝ”๋“œ ํ’ˆ์งˆ์„ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ํ’ˆ์งˆ์„ 24์‹œ๊ฐ„ ๊ฐ์‹œํ•˜๋Š” ๊ฒฝ๋น„์›์„ ๋‘๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ ! ๐Ÿ‘ฎโ€โ™‚๏ธ

4.5 ์‹ค์ „ ํŒ: ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ (TDD) ๐Ÿงญ

ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ(Test-Driven Development, TDD)์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋จผ์ € ์ž‘์„ฑํ•˜๊ณ , ๊ทธ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ์„ค๊ณ„๋„๋ฅผ ๋จผ์ € ๊ทธ๋ฆฌ๊ณ , ๊ทธ์— ๋งž์ถฐ ๋ธ”๋ก์„ ์กฐ๋ฆฝํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

TDD ์‚ฌ์ดํด:

  1. ์‹คํŒจํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ž‘์„ฑ (Red)
  2. ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š” ์ตœ์†Œํ•œ์˜ ์ฝ”๋“œ ์ž‘์„ฑ (Green)
  3. ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง (Refactor)
  4. ๋ฐ˜๋ณต

TDD๋ฅผ ์‹ค์ฒœํ•˜๋ฉด ์ฝ”๋“œ์˜ ํ’ˆ์งˆ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, TDD ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœํ–ˆ๋‹ค๊ณ  ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ „๋ฌธ์„ฑ์— ๊ฐํƒ„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Ž

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ C++ ํ”„๋กœ์ ํŠธ๋Š” ํŠผํŠผํ•œ ๊ธฐ์ดˆ ์œ„์— ์ž˜ ๋ชจ๋“ˆํ™”๋˜๊ณ , ํšจ์œจ์ ์œผ๋กœ ๋นŒ๋“œ๋˜๋ฉฐ, ์ฒ ์ €ํžˆ ํ…Œ์ŠคํŠธ๋œ ๊ฒฌ๊ณ ํ•œ ์„ฑ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋์ด ์•„๋‹ˆ์—์š”! ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ํ”„๋กœ์ ํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ํšจ๊ณผ์ ์œผ๋กœ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ฃ . ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ณ„์†ํ•ด์„œ ๋‚˜์•„๊ฐ€๋ด…์‹œ๋‹ค! ๐Ÿš€

5. ๋ฌธ์„œํ™”์™€ ์œ ์ง€๋ณด์ˆ˜: ํ”„๋กœ์ ํŠธ์˜ ์ƒ๋ช…์ค„ ๐Ÿ“š

์—ฌ๋Ÿฌ๋ถ„, ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค! ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ๋ฉ‹์ง„ C++ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค๊ณ„ํ•˜๊ณ , ๊ตฌ์ถ•ํ•˜๊ณ , ํ…Œ์ŠคํŠธํ–ˆ์–ด์š”. ํ•˜์ง€๋งŒ ์ด๊ฒƒ์œผ๋กœ ๋์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ์ง„์ •ํ•œ ๊ฐ€์น˜๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚˜๋„ ์œ ์ง€๋˜๊ณ  ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ๋น›์„ ๋ฐœํ•˜์ฃ . ๊ทธ๋ž˜์„œ ๋ฌธ์„œํ™”์™€ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ์„ค๋ช…์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ์ •๊ธฐ์ ์œผ๋กœ ์„ฑ์„ ์ ๊ฒ€ํ•˜๊ณ  ๋ณด์ˆ˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”. ๐Ÿ˜Š

5.1 ์ฝ”๋“œ ๋ฌธ์„œํ™”: ์ฃผ์„์˜ ์˜ˆ์ˆ  ๐ŸŽจ

์ข‹์€ ์ฝ”๋“œ๋Š” ์Šค์Šค๋กœ๋ฅผ ์„ค๋ช…ํ•˜์ง€๋งŒ, ํ›Œ๋ฅญํ•œ ์ฃผ์„์€ ์ฝ”๋“œ๋ฅผ ๋”์šฑ ๋น›๋‚˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. C++์—์„œ๋Š” Doxygen๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ ๋ฌธ์„œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

Doxygen ์Šคํƒ€์ผ ์ฃผ์„ ์˜ˆ์‹œ:


/**
 * @brief ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค
 * 
 * ์ด ํด๋ž˜์Šค๋Š” ์‚ฌ์šฉ์ž์˜ ์ƒ์„ฑ, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
 */
class UserManager {
public:
    /**
     * @brief ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
     * @param user ์ƒ์„ฑํ•  ์‚ฌ์šฉ์ž ์ •๋ณด
     * @return ์‚ฌ์šฉ์ž ์ƒ์„ฑ ์„ฑ๊ณต ์—ฌ๋ถ€
     */
    bool createUser(const User& user);

    // ... ๊ธฐํƒ€ ๋ฉ”์„œ๋“œ๋“ค ...
};
    

์ž˜ ์ž‘์„ฑ๋œ ์ฃผ์„์€ ์ฝ”๋“œ์˜ ์˜๋„์™€ ๋™์ž‘์„ ๋ช…ํ™•ํžˆ ์„ค๋ช…ํ•ด์ค๋‹ˆ๋‹ค. ์žฌ๋Šฅ๋„ท์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•  ๋•Œ, ์ด๋ ‡๊ฒŒ ์ž˜ ๋ฌธ์„œํ™”๋œ ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ“–

5.2 README ์ž‘์„ฑ: ํ”„๋กœ์ ํŠธ์˜ ์–ผ๊ตด ๐Ÿ˜Š

README ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ์˜ ์ฒซ์ธ์ƒ์„ ๊ฒฐ์ •์ง“๋Š” ์ค‘์š”ํ•œ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ํ”„๋กœ์ ํŠธ์˜ ๊ฐœ์š”, ์„ค์น˜ ๋ฐฉ๋ฒ•, ์‚ฌ์šฉ๋ฒ• ๋“ฑ ํ•ต์‹ฌ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์•ผ ํ•ด์š”.

์ข‹์€ README์˜ ๊ตฌ์„ฑ ์š”์†Œ:

  • ํ”„๋กœ์ ํŠธ ์ œ๋ชฉ๊ณผ ๊ฐ„๋‹จํ•œ ์„ค๋ช…
  • ์„ค์น˜ ๋ฐฉ๋ฒ•
  • ์‚ฌ์šฉ ์˜ˆ์‹œ
  • ์˜์กด์„ฑ ์ •๋ณด
  • ๋ผ์ด์„ ์Šค ์ •๋ณด
  • ๊ธฐ์—ฌ ๋ฐฉ๋ฒ•
  • ์—ฐ๋ฝ์ฒ˜ ์ •๋ณด

์ž˜ ์ž‘์„ฑ๋œ README๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ธํŠธ์˜ ๋ฐ•์Šค ์ปค๋ฒ„์™€ ๊ฐ™์•„์š”. ํ•œ๋ˆˆ์— ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์ฃ !

5.3 ๋ณ€๊ฒฝ ์ด๋ ฅ ๊ด€๋ฆฌ: Git์˜ ๋งˆ๋ฒ• ๐Ÿง™โ€โ™‚๏ธ

Git์„ ์‚ฌ์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” ํ˜„๋Œ€ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์˜ ํ•„์ˆ˜ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์„ ์ง€์œผ๋ฉด์„œ ๊ฐ ๋‹จ๊ณ„๋ฅผ ์‚ฌ์ง„์œผ๋กœ ๋‚จ๊ธฐ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”.

ํšจ๊ณผ์ ์ธ Git ์‚ฌ์šฉ ํŒ:

  • ์˜๋ฏธ ์žˆ๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ์ž‘์„ฑํ•˜๊ธฐ
  • ๊ธฐ๋Šฅ๋ณ„๋กœ ๋ธŒ๋žœ์น˜ ๋งŒ๋“ค์–ด ์ž‘์—…ํ•˜๊ธฐ
  • Pull Request๋ฅผ ํ†ตํ•œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์ง„ํ–‰ํ•˜๊ธฐ
  • ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์š” ๋ฒ„์ „ ํ‘œ์‹œํ•˜๊ธฐ
  • GitFlow๋‚˜ GitHub Flow ๊ฐ™์€ ๋ธŒ๋žœ์นญ ์ „๋žต ์‚ฌ์šฉํ•˜๊ธฐ

Git์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ์žฌ๋Šฅ๋„ท์—์„œ ํ˜‘์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ์ฒด๊ณ„์ ์ธ ๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” ํŒ€์›Œํฌ๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ๊ฑฐ์˜ˆ์š”! ๐Ÿค

5.4 ์ด์Šˆ ํŠธ๋ž˜ํ‚น: ๋ฌธ์ œ๋ฅผ ๋†“์น˜์ง€ ๋งˆ์„ธ์š” ๐Ÿ•ต๏ธโ€โ™€๏ธ

๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ฒ„๊ทธ, ๊ฐœ์„ ์‚ฌํ•ญ, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์š”์ฒญ ๋“ฑ์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. GitHub Issues๋‚˜ Jira ๊ฐ™์€ ์ด์Šˆ ํŠธ๋ž˜ํ‚น ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•ด๋ณด์„ธ์š”.

ํšจ๊ณผ์ ์ธ ์ด์Šˆ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•:

  • ๋ช…ํ™•ํ•˜๊ณ  ๊ตฌ์ฒด์ ์ธ ์ด์Šˆ ์ œ๋ชฉ ์‚ฌ์šฉํ•˜๊ธฐ
  • ์žฌํ˜„ ๋‹จ๊ณ„, ์˜ˆ์ƒ ๊ฒฐ๊ณผ, ์‹ค์ œ ๊ฒฐ๊ณผ ๋“ฑ ์ƒ์„ธ ์ •๋ณด ํฌํ•จํ•˜๊ธฐ
  • ๊ด€๋ จ ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ๋กœ๊ทธ ์ฒจ๋ถ€ํ•˜๊ธฐ
  • ์ ์ ˆํ•œ ๋ผ๋ฒจ๊ณผ ๋งˆ์ผ์Šคํ†ค ์ง€์ •ํ•˜๊ธฐ
  • ๋‹ด๋‹น์ž ํ• ๋‹นํ•˜๊ธฐ

์ฒด๊ณ„์ ์ธ ์ด์Šˆ ๊ด€๋ฆฌ๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ๋ชจ๋“  ๋ฌธ์ œ์ ์„ ๊ผผ๊ผผํžˆ ๊ธฐ๋กํ•˜๊ณ  ํ•ด๊ฒฐํ•ด๋‚˜๊ฐ€๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”. ์ด๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ฐœ์„ ํ•˜๊ณ  ๋ฐœ์ „์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5.5 ์ง€์†์ ์ธ ๋ฆฌํŒฉํ† ๋ง: ์ฝ”๋“œ์˜ ์ฒญ์†Œ๋ถ€ ๐Ÿงน

์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ์ฝ”๋“œ๋Š” ๋ณต์žกํ•ด์ง€๊ณ  ๋น„ํšจ์œจ์ ์œผ๋กœ ๋ณ€ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ •๊ธฐ์ ์ธ ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ๊นจ๋—ํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ์œ ์ง€ํ•˜์„ธ์š”.

๋ฆฌํŒฉํ† ๋ง ์ฒดํฌ๋ฆฌ์ŠคํŠธ:

  • ์ค‘๋ณต ์ฝ”๋“œ ์ œ๊ฑฐํ•˜๊ธฐ
  • ๊ธด ํ•จ์ˆ˜ ๋‚˜๋ˆ„๊ธฐ
  • ๋ณต์žกํ•œ ์กฐ๊ฑด๋ฌธ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ
  • ๋ช…ํ™•ํ•œ ์ด๋ฆ„ ์‚ฌ์šฉํ•˜๊ธฐ
  • ์ฃผ์„ ๋Œ€์‹  ์ฝ”๋“œ๋กœ ์„ค๋ช…ํ•˜๊ธฐ
  • ๋””์ž์ธ ํŒจํ„ด ์ ์šฉํ•˜๊ธฐ

์ง€์†์ ์ธ ๋ฆฌํŒฉํ† ๋ง์€ ์ฝ”๋“œ์˜ ํ’ˆ์งˆ์„ ๋†’์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์žฌ๋Šฅ๋„ท์—์„œ ์žฅ๊ธฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์ด๋Ÿฐ ๊พธ์ค€ํ•œ ์ฝ”๋“œ ๊ฐœ์„ ์€ ํ”„๋กœ์ ํŠธ์˜ ์ˆ˜๋ช…์„ ์—ฐ์žฅ์‹œํ‚ค๊ณ  ๊ฐ€์น˜๋ฅผ ๋†’์—ฌ์ค„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ’Ž

5.6 ์‹ค์ „ ํŒ: ๋ฌธ์„œํ™” ์ž๋™ํ™”ํ•˜๊ธฐ ๐Ÿค–

๋ฌธ์„œํ™” ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๋ฉด ํ•ญ์ƒ ์ตœ์‹  ์ƒํƒœ์˜ ๋ฌธ์„œ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๊ธฐ ๋ช‡ ๊ฐ€์ง€ ํŒ์„ ์†Œ๊ฐœํ• ๊ฒŒ์š”:

  • Doxygen์„ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜์—ฌ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์ž๋™์œผ๋กœ API ๋ฌธ์„œ ์ƒ์„ฑํ•˜๊ธฐ
  • Markdown์œผ๋กœ ๋ฌธ์„œ ์ž‘์„ฑํ•˜๊ณ  GitHub Pages๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์›น์‚ฌ์ดํŠธ ์ƒ์„ฑํ•˜๊ธฐ
  • README ํ…œํ”Œ๋ฆฟ์„ ๋งŒ๋“ค์–ด ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์‹œ ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ ๊ตฌ์กฐ ๊ฐ–์ถ”๊ธฐ
  • ๋ณ€๊ฒฝ ๋กœ๊ทธ(CHANGELOG) ์ž๋™ ์ƒ์„ฑ ๋„๊ตฌ ์‚ฌ์šฉํ•˜๊ธฐ

์ด๋Ÿฐ ์ž๋™ํ™” ๋„๊ตฌ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด, ๋ฌธ์„œํ™”์— ๋“ค์ด๋Š” ์‹œ๊ฐ„์€ ์ค„์ด๋ฉด์„œ๋„ ํ•ญ์ƒ ์ตœ์‹ ์˜ ์ •ํ™•ํ•œ ๋ฌธ์„œ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ๋ ˆ๊ณ  ์„ฑ์˜ ์„ค๋ช…์„œ๊ฐ€ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ ! ๐Ÿฐโœจ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ C++ ํ”„๋กœ์ ํŠธ๋Š” ์ž˜ ์„ค๊ณ„๋˜๊ณ , ๊ตฌ์ถ•๋˜๊ณ , ํ…Œ์ŠคํŠธ๋˜์—ˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฒด๊ณ„์ ์œผ๋กœ ๋ฌธ์„œํ™”๋˜๊ณ  ์ง€์†์ ์œผ๋กœ ๊ด€๋ฆฌ๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋Œ€๊ทœ๋ชจ C++ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋น„๊ฒฐ์ด์—์š”. ์—ฌ๋Ÿฌ๋ถ„๋„ ์ด์ œ ์žฌ๋Šฅ๋„ท์—์„œ ๋‹น๋‹นํžˆ C++ ํ”„๋กœ์ ํŠธ ์ „๋ฌธ๊ฐ€๋กœ ํ™œ์•ฝํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐ŸŒŸ

์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์—ฌ์ •์ด ํ•ญ์ƒ ์ฆ๊ฒ๊ณ  ๋ณด๋žŒ์ฐผ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. ํ™”์ดํŒ…! ๐Ÿ’ช๐Ÿ˜Š