Specification Pattern

๊ฝค ๊ดœ์ฐฎ์€ ๊ธ€์ด ์žˆ์–ด ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

Avoid Proliferating DbContext or IQueryable in .NET Apps | Blog (ardalis.com)

์š”์ง€

  1. DbContex, DbSet, IQueryable ์„ ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด ์™ธ๋ถ€๋กœ ๋…ธ์ถœ์‹œํ‚ค์ง€ ๋งˆ๋ผ.
  2. Specification ๊ฐ์ฒด๋กœ ์ฟผ๋ฆฌ๋ฅผ ํ•œ์ •ํ•˜๋ผ.

DbContex, DbSet, IQueryable ์„ ์™ธ๋ถ€๋กœ ๋…ธ์ถœ์‹œํ‚ค์ง€ ๋งˆ๋ผ.

๋Œ€ํ‘œ์ ์ธ ์ด์œ ๋Š” IQueryable ์ด IEnumerable ์„ ํŒŒ์ƒํ•˜๊ณ  ์žˆ์–ด, ์‚ฌ์šฉ ์ฝ”๋“œ์—์„œ IEnumerable๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

foreach ๋Œ๋ฆด ๋•Œ๋งˆ๋‹ค ์ฟผ๋ฆฌ๊ฐ€ ์ „์†ก๋˜๊ธฐ ํ•˜๊ณ , ์‚ฌ์šฉ์ž ์ฝ”๋“œ ๋‹จ์—์„œ IEnumerable ์˜ ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ–ˆ์„ ๊ฒฝ์šฐ, IQueryable ์„ ์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ์ด๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฐ ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ฌธ์ œ๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค.

Specification ๊ฐ์ฒด๋กœ ์ฟผ๋ฆฌ๋ฅผ ํ•œ์ •ํ•˜๋ผ.

์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์œ„ํ—˜ํ•œ ์ฝ”๋“œ๋„ ์—†์ฃ .

var allUsers = context.Users.ToList();

์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ์œ„ํ—˜์„ ์ดˆ๋ž˜ํ•˜๋Š” ์ฝ”๋“œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ฝ”๋“œ๊ฐ€ ์ œํ•œ ์—†์ด ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋งค์šฐ ์œ„ํ—˜ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์™”์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์›น API ๊ฐ™์€ ๋„๋ฉ”์ธ ์™ธ๋ถ€ ๋…ธ์ถœ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹น์—ฐํ•˜๊ณ , ๋„๋ฉ”์ธ ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด, ๋ฐ์ดํ„ฐ ์„œ๋น„์Šค๊ฐ€ DbContext ๋ฅผ ๊ฐ์‹ธ๊ณ , ํ•„ํ„ฐ๋ง๋œ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๋…ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

sealed class UserService
{
   public const int MaxUserRetrieveCount = 50;
   private IQueryable<User> _users;
   private int _retrieved;
   ...
   public List<User> Next(int count) 
   {
      if (count < 1)
         return new();

      if (MaxUserRetrieveCount < count)
         count = MaxUserRetrieveCount;

      var skip = _retrieved;
      _retrieved += count;
      return _users.Skip(skip).Take(count).ToList();
   }
   ...
}

์ €๋Š” ์ด ๋ฐฉ๋ฒ•์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•ด ์™”๋Š”๋ฐ ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋Š” ์œ ์ง€ ๋ณด์ˆ˜์ž…๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋ง ์ผ€์ด์Šค๊ฐ€ ๋ณ€๊ฒฝ/์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค UserService ์˜ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•ด์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.
ํŠนํžˆ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ํ˜ธ์ถœ๋˜๊ณ  ์žˆ๋Š” ์ผ€์ด์Šค๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ˆ˜์ •ํ•ด์•ผ ํ•  ์ฝ”๋“œ์˜ ์–‘์ด ์‰ฝ๊ฒŒ ๋งŽ์•„์ง‘๋‹ˆ๋‹ค.

Specification ํŒจํ„ด์€ ๋‹จ์ผ ํ•„ํ„ฐ๋ง ์ผ€์ด์Šค๋ฅผ ์บก์Šํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ๋งค์šฐ ๋›ฐ์–ด๋‚œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

์ง์ ‘ ์ฟผ๋ฆฌ๋ฅผ ์ œํ•œํ•˜๊ณ  Interface๋กœ ์ ‘๊ทผํ•œ๋‹ค๋Š”๊ฒƒ์ด ์›๋ก ์ ์œผ๋กœ ๋งž๊ธด ํ•˜๋‚˜ ?
์‚ฌ์‹ค ์‹ค๋ฌด์—์„œ ๊ทธ๋Ÿฌ๊ธฐ๊ฐ€ ๋งŒ๋งŒ์น˜ ์•Š์Šต๋‹ˆ๋‹ค.
์ œํ•œํ•  ์ฟผ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค๋Š”๊ฒƒ์€ ์ด๋ฏธ ์—…๋ฌด ๋กœ์ง์„ ๊ฑฐ์˜ ๋๋ƒˆ๋‹ค๋Š” ์• ๊ธฐ์ผ์ˆ˜๋„ ์žˆ๊ณ 
ํŒ€๋‹จ์œ„๋กœ ๊ฐœ๋ฐœํ• ๋•Œ ์ž‘์€ ๋ณ€๊ฒฝ์—๋„ ๋‹ด๋‹น์ž๊ฐ€ ์ˆ˜์ •ํ•ด์ค˜์•ผ ํ• ์ˆ˜๋„ ์žˆ๊ณ 
๊ทธ๋ฆฌ๊ณ  ๋””๋ฒ„๊น…์‹œ ํ•œ๋‹จ๊ณ„ ๋” ๊ฑฐ์ณ์•ผ ํ•œ๋‹ค๋Š”๊ฒƒ์ผ์ˆ˜๋„ ์žˆ๊ณ 
๋ญ ๋‹จ์ ๋งŒ ๋‚˜์—ดํ•˜๋ฉด ์ด๋Ÿฐ๋ฐ ๋งž๋Š” ๋ฐฉํ–ฅ์€ ๋งž์œผ๋‚˜ ๊ท€์ฐฎ๋‹ค๋ผ๋Š” ๋‹จ์ ๊ฐ™๋„ค์š”

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

์‚ฌ์‹ค ๋ง์”€ํ•˜์‹  ๊ฒƒ๋“ค ๋ชจ๋‘ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ•ด๊ฒฐ๋˜๋Š” ๋ฌธ์ œ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. OOP์—์„œ ์ฃผ์žฅํ•˜๋Š”๊ฒŒ ๊ทธ๊ฑฐ์ฃ .

๋‹ค๋งŒ ๋ฌธ์ œ๋Š” ๋ชจ๋“  ํŒ€์›๋“ค์˜ OOP ์ˆ˜์ค€์ด ๊ฐ™์ง€ ์•Š๋‹ค๋Š” ์  ์ผ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฐœ๋…์ด๋‚˜ ์šฉ๋„๋ฅผ ์ž˜ ๋ชจ๋ฅด๋‹ˆ๊นŒ ๊ทธ์ € ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํด๋ž˜์Šค ๋ง๊ณ  ๋˜ ๋ญ”๊ฐ€ ๋งŒ๋“ค์–ด์ค˜์•ผํ•˜๋Š” ๊ท€์ฐฎ์€ ๊ฒƒ.

์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ผ ๊ฒƒ ๊ฐ™๋„ค์š”. ์ œ๊ฐ€ ๊ทธ๋Ÿค๋˜ ๊ฒƒ์ฒ˜๋Ÿผโ€ฆ

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

์•„ ๋ฌผ๋ก  ์—ฌ๊ธฐ์„œ ์–ธ๊ธ‰ํ•˜์‹œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ฝ”๋”ฉ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ฒฐ๊ตญ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ๋งŒ ํ•˜๋ฉด ์‚ฌ์šฉํ•˜๋Š” ์ธก์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์ ‘๊ทผํ•˜๊ณ  ์‹ค์งˆ์ ์ธ ๊ตฌํ˜„์€๋‹‰์„ ํ•จ์œผ๋กœ์จ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ์— ์ง‘์ค‘ํ•œ๋‹ค๋Š” ๋งฅ๋ฝ์—์„œ ๋ง์”€๋“œ๋ ธ์Šต๋‹ˆ๋‹ค.

์˜คํ•ด๋Š” ์—†์œผ์‹œ๊ธฐ๋ฅผโ€ฆ!

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

์–ด๋–ค ๋ ˆ์ด์–ด๋ฅผ ๋ณ„๋„๋กœ ์—…๋ฌด ๋ถ„์žฅํ–ˆ์œผ๋ฉด, ๊ทธ ๋ ˆ์ด์–ด์— ๊ด€ํ•œ ์ฝ”๋“œ๋Š” ๊ทธ ๋‹ด๋‹น์ž์—๊ฒŒ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ๋‹น์—ฐํ•œ ๊ฒƒ ์•„๋‹Œ์ง€์š”?

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

์ด ํŒจํ„ด์€ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ดํ•ดํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์‹œ์ง€ ๊ฐฏ์ˆ˜๋ฅผ ํ™•์žฅ(๋ฉ”์„œ๋“œ ์ข…๋ฅ˜๋ฅผ ๋Š˜๋ฆผ)ํ•  ๊ฒƒ๋ณด๋‹ค๋Š”, ๋ฉ”์‹œ์ง€๋Š” ๋‹จ์ผํ™”ํ•˜๊ณ , ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ํ–‰์œ„๋ฅผ ํ™•์žฅํ•˜๋Š” ๊ฒƒ์ด์ฃ .

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

๋„ค๋„ค ์ œ๊ฐ€ ์ฝ”๋“œ์˜ interface๋ฅผ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด์„œ ์˜คํžˆ๋ ค ์ œ๊ฐ€ ๋งํ•˜๋ ค ํ–ˆ๋˜ ์˜๋„๊ฐ€ ํ—ท๊ฐˆ๋ฆฌ์‹ค ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ๊ฒƒ์˜ ๋ณธ์งˆ์„ ๋งํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์ €์—๊ฒŒ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ฝ˜์„ผํŠธ ๊ฐ™์€ ๊ฒƒ์ด๋ผ์„œ ์‚ฌ๋žŒ์ด ์ „๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ฝ˜์„ผํŠธ ๋’ทํŽธ์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€๋Š” ๋ชฐ๋ผ๋„ ๋˜๊ณ  ๊ทธ์ € 220V ์ „์› ์„ ์„ ๊ฝ‚๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค ๋ผ๋Š” ๋ช…ํ™•ํ•œ ํ–‰๋™๋งŒ ์žˆ๊ฒŒ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ณ ๋งˆ์šด ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

์ œ๊ฐ€ ์•„๋Š” ์„ ์—์„  ๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค๋ผ ๋ถˆ๋ฆฌ๋Š” ๊ฒƒ๋“ค์ด ๋‹ค ์ด๋Ÿฐ ๊ฐœ๋…์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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