๐๏ธ ํด๋ฆฐ ์ฝ๋๋ฅผ ์ํ 8๊ฐ์ง ํ
ํด๋ฆฐ ์ฝ๋๋ ์ฝ๊ธฐ ์ฝ๊ณ ์ ์ง๋ณด์๋ ์ฌ์ฐ๋ฉฐ ์ดํดํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ๋ปํฉ๋๋ค. ํด๋ฆฐ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ธฐ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ํ ์ฐ์ต์ผ๋ก ํฅ์ํ ์ ์๋ ๊ธฐ์ ์ด๋ผ๊ณ ๋ ์๊ฐํฉ๋๋ค. ํด๋ฆฐ ์ฝ๋ฉ์ ์ฐ์ตํ ๋ ๊ฐ์ฅ ์ข์ํ๋ ๋ฐฉ๋ฒ์ ๋ฆฌํฉํ ๋ง์ ๋๋ค. ํด๋ฆฐ ์ฝ๋ ์์น์ ์ ์ฉํ์ฌ ์ค๋ ํ ๋จ๊ณ์ฉ ๊ฐ์ ํด ๋๊ฐ๋ด ์๋ค. ``` public void Process(Order? order) { if(order is null) { if(order.isVerified) { if(order.Items.Count > 0) { if(order.Items.Count > 15) { throw new Exception("The order " + order.Id + " has too many items"); } if(order.Status != "ReadyToProcess") { throw new Exception("The order " + order.Id + " isn't ready to process"); } order.IsProcessed = true; } } } ``` 1๏ธโฃ ์กฐ๊ธฐ ๋ฐํ ์์น if ๋ฌธ์ด ๊น๊ฒ ์ค์ฒฉ๋ ๊ฒ์ ๊ต์ฅํ ๊ณ ํต์ค๋ฝ์ต๋๋ค. ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ ์ฆ์ ๋ฐํํด์ผ ํ๋ค๋ ์กฐ๊ธฐ ๋ฐํ ์์น์ ์ฌ์ฉํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ์๋ค. ``` public void Process(Order? order) { if(order is null) { return; } if(!order.isVerified) { return; } if(order.Items.Count ==0) { return; } if(order.Items.Count > 15) { throw new Exception("The order " + order.Id + " has too many items"); } if(order.Status != "ReadyToProcess") { throw new Exception("The order " + order.Id + " isn't ready to process"); } order.IsProcessed=true; } ``` 2๏ธโฃ ๊ฐ๋ ์ฑ ํฅ์์ ์ํ ๋ฌธ์ฅ ๋ณํฉ ๋ง์ฝ ๋ฐํํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ผํ๋ค๋ฉด, ๋ฌธ์ฅ์ ๋ณํฉ์ํค๋ ๋ฐฉ๋ฒ๋ ๊ณ ๋ คํด ๋ด ์๋ค. ``` public void Process(Order? order) { if(order is null | !order.isVerified | order.Items.Count == 0) { return; } order.IsProcessed=true; } ``` 3๏ธโฃ ๋ ๊ฐ๊ฒฐํ ์ฝ๋๋ฅผ ์ํด LINQ ์ฌ์ฉ LINQ๋ฅผ ์ด์ฉํ์ฌ ์ฝ๋๋ฅผ ๋ณด๋ค ๊ฐ๊ฒฐํ๊ณ ํํ์ ์ผ๋ก ๋ง๋ญ์๋ค. Items.Count == 0์ผ๋ก ์ฒดํฌํ๋ ๋์ , ์ ๋ Any ๋ฉ์๋๋ฅผ ์ ํธํฉ๋๋ค. LINQ์ ์ฑ๋ฅ์ด ๋ ๋์๋ค๊ณ ์ฃผ์ฅํ ์ ์์ง๋ง, ์ ๋ ๊ฐ๋ ์ฑ์ ์ํด ํ์ฉํฉ๋๋ค. ์ด ๋ฉ์๋ ํธ์ถ๋ณด๋ค๋ ํจ์ฌ ๋ ํฐ ๋น์ฉ์ ์๋ชจํ๋ ์์ ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ด๋๊ฐ์ ์์ ๊ฒ๋๋ค. ``` public void Process(Order? order) { if(order is null || !order.IsVerified || !order.Items.Any()) { return; } if(order.Items.Count > 15) { throw new Exception("The order " + order.Id + " has too many items"); } if(order.Status != "ReadyToProcess") { throw new Exception("The order " + order.Id + " isn't ready to process"); } order.IsProcessed = true; } ``` 4๏ธโฃ ๋ถ์ธ ์์ ๋ฉ์๋๋ก ๋์ฒด if๋ฌธ์์ ์ฌ๋ฌ ์กฐ๊ฑด์ ํ๋๋ก ๋ณํฉํ๋ ๊ฒ์ ์ฝ๋๋ฅผ ์ ๊ฒ ์ฌ์ฉํ์ง๋ง, ๋ณต์กํ ์กฐ๊ฑด์ผ๋ก ์ธํด ๊ฐ๋ ์ฑ์ ์ ํํ ์ ์์ต๋๋ค. ๋ณ์๋ ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ``` public void Process(Order? order) { if(!Processable(order)) { return; } if(order.Items.Count > 15) { throw new Exception("The order " + order.Id + " has too many items"); } if(order.Status != "ReadyToProcess") { throw new Exception("The order " + order.Id + " isn't ready to process"); } order.IsProcessed = true; } static bool IsProcessable(Order? order) { return order is not null && order.IsVerified&& order.Items.Any() ) ``` 5๏ธโฃ ์ฌ์ฉ์ ์ง์ ์์ธ๋ฅผ ์ ํธ ์ ๋ "์์ธ"์ ์ธ ์ํฉ์์๋ง ์์ธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ํ๊ณ , ์ฝ๋์์ ํ๋ฆ ์ ์ด๋ฅผ ์ํด ์์ธ๋ฅผ ์ฌ์ฉํ์ง๋ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ๋ ํ๋ฆ ์กฐ์ ์ ์์ธ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ์ฌ์ฉ์ ์ง์ ์์ธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ``` public void Process(Order? order) { if(!Processable(order)) { return; } if(order.Items.Count > 15) { throw new TooManyLineItemsException(order.Id); } if(order.Status != "ReadyToProcess") { throw new NotReadyForProcessingException(order.Id); } order.IsProcessed = true; } static bool IsProcessable(Order? order) { return order is not null && order.IsVerified&& order.Items.Any() ) ``` 6๏ธโฃ ์์๋ฅผ ์ด์ฉํด ๋งค์ง ๋๋ฒ ๊ณ ์น๊ธฐ ์์ฃผ ๋ฐ์ํ๋ ์ฝ๋ ๋์๋ ๋งค์ง ๋๋ฒ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋งค์ง ๋๋ฒ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋๋ฅผ ์ถ๋ก ํ๊ธฐ ์ด๋ ต๊ณ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ์ต๋๋ค. ๋งค์ง ๋๋ฒ๋ฅผ ๊ณ ์ ํ๋ ๊ฒ์ ๊ฐ๋จํด์ผ ํ๋ฉฐ, ํ ๊ฐ์ง ํด๊ฒฐ์ฑ ์ ์์๋ฅผ ๋์ ํ๋ ๊ฒ์ ๋๋ค. ``` const int MaxNumberOfLineItems = 15; public void Process(Order? order) { if(!Processable(order)) { return; } if(order.Items.Count > MaxNumberOfLineItems ) { throw new TooManyLineItemsException(order.Id); } if(order.Status != "ReadyToProcess") { throw new NotReadyForProcessingException(order.Id); } order.IsProcessed = true; } static bool IsProcessable(Order? order) { return order is not null && order.IsVerified&& order.Items.Any() ) ``` 7๏ธโฃ ๋งค์ง ์คํธ๋ง์ ์ด๊ฑฐํ์ผ๋ก ๊ณ ์น๊ธฐ ๋งค์ง ๋๋ฒ์ ์ ์ฌํ๊ฒ ๋งค์ง ์คํธ๋ง์์๋ ์ฝ๋ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค. ๋งค์ง ์คํธ๋ง์ ์ ํ์ ์ธ ์ฌ๋ก๋ ์ผ์ข ์ ์ํ๋ฅผ ๋ํ๋ด๋ ๊ฒ์ ๋๋ค. ์ด๊ฑฐํ์ ์ด์ฉํ์ฌ ๋งค์ง ์คํธ๋ง์ ๋ค๋ฃน์๋ค. ``` enum OrderStatus { Pending = 0, ReadyToProcess = 1, Processed = 2 } ``` 8๏ธโฃ Result Object Pattern ์ฌ์ฉ ์ ๋ ํ๋ฆ ์กฐ์ ์ ์์ธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํ์ง ์๋๋ค๊ณ ๋งํ์ต๋๋ค. ํ์ง๋ง ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น์? ๊ฒฐ๊ณผ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ ํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค. ``` public class ProcessOrderResult { public ProcessOrderResultType Type { get; } public long OrderId { get; } public string? Message { get; } public static ProcessOrderResult NotProcessable() => new(ProcessOrderResultType.NotProcessable, default, "Not processable"); public static ProcessOrderResult TooManyLineItems(long oderId) => new(ProcessOrderResultType.TooManyLineItems, orderId, "Too many items"); public static ProcessOrderResult NotReadyForProcessing(long oderId) => new(ProcessOrderResultType.NotReadyForProcessing, oderId, "Not ready"); public static ProcessOrderResult Success(long oderId) => new(ProcessOrderResultType.Success, oderId, "Success"); } ``` ํด๋ฆฐ ์ฝ๋๋ฅผ ์ฐ๋ ๊ฒ์ ์๋์ ์ธ ์ฐ์ต๊ณผ ๊ฒฝํ์ ๋ฌธ์ ์ ๋๋ค. ๋ง์ ์ฌ๋์ด ํด๋ฆฐ ์ฝ๋ ์๋ฆฌ์ ๋ํด ์ฝ์ง๋ง, ๋งค์ผ ์ ์ฉํ๋ ค๊ณ ๋ ธ๋ ฅํ๋ ์ฌ๋์ ๊ฑฐ์ ์์ต๋๋ค. ๋ฐ๋ก ์ด๊ฒ์ด ๋น์ ์ ๋ค๋ฅด๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค. ๐ฃ ์๋ฌธ์์ ์ฝ๋๊ฐ ์ต์ข ์ ์ผ๋ก ์ด๋ป๊ฒ ๋ฌ๋ผ์ก๋์ง ํ์ธํด ๋ณด์ธ์!