<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>iOS with BeePeach</title>
    <link>https://beepeach.tistory.com/</link>
    <description>iOS, Swift 개발 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 4 Jul 2026 10:32:25 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Beepeach</managingEditor>
    <image>
      <title>iOS with BeePeach</title>
      <url>https://tistory1.daumcdn.net/tistory/4202061/attach/aa7e2d6f36644d27907a80ca9df67052</url>
      <link>https://beepeach.tistory.com</link>
    </image>
    <item>
      <title>Clean Code 2장 - 의미있는 이름</title>
      <link>https://beepeach.tistory.com/825</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;name.jpeg&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxH6nn/btsvmAKhoMx/CbrWgpDkYJ1t0lLkykJqi0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxH6nn/btsvmAKhoMx/CbrWgpDkYJ1t0lLkykJqi0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxH6nn/btsvmAKhoMx/CbrWgpDkYJ1t0lLkykJqi0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxH6nn%2FbtsvmAKhoMx%2FCbrWgpDkYJ1t0lLkykJqi0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;552&quot; data-filename=&quot;name.jpeg&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;프로그래밍을 하면 가장 많이 하는게 이름을 짓는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 장에서는 이름을 잘 짓는 간단한 규칙 소개하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;의도를 분명하게 밝혀라&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름은 변수, 함수, 클래스의&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;존재 이유&lt;/li&gt;
&lt;li&gt;수행 기능&lt;/li&gt;
&lt;li&gt;사용 방법&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 세가지에 모두 답할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695457327405&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public func getThem() -&amp;gt; [[Int]] {
    var list1: [[Int]] = []
    
    for x in theList {
        if x[0] == 4 {
            list1.append(x)
        }
    }
    
    return list1
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 코드 자체가 어려운 코드는 아니지만 이해하기 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 아래의 정보를 이미 알고 있다고 가정하고 있기때문이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;theList에는 뭐가 들어가 있는지&lt;/li&gt;
&lt;li&gt;theList에 0번째 값이 무엇인지&lt;/li&gt;
&lt;li&gt;4는 무슨 의미인지&lt;/li&gt;
&lt;li&gt;리턴하는 list1을 어떻게 사용하는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695457732385&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public func getFlageedCells() -&amp;gt; [[Int]] {
    var flaggedCells: [[Int]] = []
    
    for cell in gameBoard {
        if cell[statusValue] == flagged {
            flaggedCells.append(cell)
        }
    }
    
    return flaggedCells
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 이름만 변경해도 코드를 이해하기 한결 더 좋아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695457889397&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public func getFlageedCells() -&amp;gt; [Cell] {
    var flaggedCells: [Cell] = []
    
    for cell in gameBoard {
        if cell.isFlagged() {
            flaggedCells.append(cell)
        }
    }
    
    return flaggedCells
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 나아가서 [Int]를 Cell이라는 클래스로 만들고 cell의 status를 판별하는 식을 메서드로 빼면 더 보기 좋은 코드가 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;잘못된 정보를 피하라.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에 잘못된 단서를 남기면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 널리 쓰이는 의미가 있는 단어는 다른 의미로 사용하면 안된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 List라는 접두어가 들어가면 타입이 []인것으로 혼돈될 수 있으므로 되도록 사용하지 않는것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 서로 흡사한 이름을 사용하지 않도록 주의하자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 모듈에서 XYZControllerForEfficientHandlingOfString 이라는 이름을 사용하고 다른 모듈에서 XYZControllerForEfficientStorageOfString 이라는 이름을 사용하면 서로 같은 단어로 오해하기 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 유사한 개념은 유사한 표기법을 사용하자. 일관성일 떨어지는 표기도 잘못된 정보이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- L이나 O 사용에 주의하자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐가 O인지 0인지 L인지 1인지 구별하기 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백문이 불여일견 직접 보도록하자.&lt;/p&gt;
&lt;pre id=&quot;code_1695458677750&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let a: Int = 1
if (O == 1) {
    a = O1
} else {
    l = 01
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지는 이어서...&lt;/p&gt;</description>
      <category>Book/Clean Code</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/825</guid>
      <comments>https://beepeach.tistory.com/825#entry825comment</comments>
      <pubDate>Sat, 23 Sep 2023 17:52:47 +0900</pubDate>
    </item>
    <item>
      <title>Clean Code 1장 - 깨끗한 코드</title>
      <link>https://beepeach.tistory.com/815</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍의 유행이나 스타일은 조금씩 바뀌기 때문에 이 책에서 설명하는 원칙이 지금과 잘 맞지 않는 부분도 있기 마련이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이 책에 나온 내용이 절대적은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 팀에서 서로 동의하는 합리적인 원칙을 세우기 위한 소통이 중요하다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;깨끗한 코드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 모두 시간에 쫒겨 일단 돌아가는 코드를 짠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 안돌아가는 프로그램보다 돌아가는 쓰레기가 좋다고 스스로를 위로한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 다시 정리하겠다고 다짐한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 결코 &lt;b&gt;나중&lt;/b&gt;은 오지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2023-05-28 at 4.34.22 PM.png&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1088&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgt4td/btshCdhjltZ/eTlJUl9MUujCxNRa66HvV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgt4td/btshCdhjltZ/eTlJUl9MUujCxNRa66HvV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgt4td/btshCdhjltZ/eTlJUl9MUujCxNRa66HvV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcgt4td%2FbtshCdhjltZ%2FeTlJUl9MUujCxNRa66HvV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2356&quot; height=&quot;1088&quot; data-filename=&quot;Screenshot 2023-05-28 at 4.34.22 PM.png&quot; data-origin-width=&quot;2356&quot; data-origin-height=&quot;1088&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머라면 누구나 나쁜 코드가 업무 속도를 늦춘다는 것을 알고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기한을 맞추기 위해서는 나쁜 코드를 작성할 수 밖에 없다고 느낀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 나쁜 코드를 양산하면 오히려 기한을 맞추지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 빨라 보이지만 뒤로 갈수록 생산성이 나오지 않고 기한을 놓치게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빨리 가는 유일한 방법은 언제나 코드를 최대한 깨끗하게 유지하는 습관이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 구현하는 행위는 그림을 그리는 것과 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 한 눈에 이것이 잘 그린 그림인지 못 그린 그림인지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 구분하는 것과 그림을 잘 그리는 것은 별개의 능력이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 나쁜 코드인지 깨끗한 코드인지 아닌지 알아본다고해서 깨끗한 코드를 작성할 수 있다는 의미는 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예술 책을 읽는다고해서 바로 예술가가 될 수 있는 게 아니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예술 책은 화가가 사용하는 도구와 기법, 그들의 사고방식을 소개할 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 읽는다고 해서 좋은 코드를 작성하는 프로그래머가 될 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;똑같이 그들이 생각하는 방식과 사용하는 기술, 도구를 소개할 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나머지는 연습하는 우리의 몫이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;깨끗한 코드란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깨끗한 코드에 대한 정의는 사람에 따라 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 유명한 사람들의 의견을 남긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;논리가 간단해야 한다.&lt;br /&gt;의존성을 최대한 줄여야 유지보수가 쉬워진다.&lt;br /&gt;오류는 명백한 전략에 의거해 철처히 처리한다.&lt;br /&gt;깨끗한 코드는 한 가지를 제대로 한다.&lt;br /&gt;&lt;br /&gt;- Bjarne Stroustrup (C++ 창시자)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;깨끗한 코드는 잘 쓴 문장처럼 읽힌다.&lt;br /&gt;깨끗한 코드는 작성자의 의도를 숨기지 않는다. 오히려 명쾌한 추상화와 단순한 제어문으로 가득하다.&lt;br /&gt;&lt;br /&gt;- Grady Booch&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다.&lt;br /&gt;테스트 케이스가 존재한다.&lt;br /&gt;깨끗한 코드에는 의미 있는 이름이 붙는다.&lt;br /&gt;의존성은 최소이며 각 의존성을 명확히 정의한다.&lt;br /&gt;&lt;br /&gt;- Dave Thomas (OTI 창립자)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;모든 테스트를 통과한다.&lt;br /&gt;중복이 없다.&lt;br /&gt;시스템 내 모든 설계 아이디어를 표현한다.&lt;br /&gt;클래스, 메서드등을 최대한 줄인다.&lt;br /&gt;&lt;br /&gt;- Ron Jeffries&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;보이스카우트 규칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에서 계속해서 소개하는 규칙이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캠프장은 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체크아웃할 때보다 조금 더 깨끗한 코드를 체크인한다면 코드는 절대 나빠지지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번에 많은 시간과 노력을 들여 코드를 정리할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 이름 개선, 긴 함수를 작은 함수로 분할, 약간의 중복 제거, 복잡한 if문 정리와 같이 작은 일이라도 하나씩 하자.&lt;/p&gt;</description>
      <category>Book/Clean Code</category>
      <category>cleancode</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/815</guid>
      <comments>https://beepeach.tistory.com/815#entry815comment</comments>
      <pubDate>Sun, 28 May 2023 17:07:11 +0900</pubDate>
    </item>
    <item>
      <title>영어 공부</title>
      <link>https://beepeach.tistory.com/783</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;used to ~ 하곤했다,&lt;br /&gt;go go 가, 가&lt;br /&gt;go on 쭉 가&lt;br /&gt;awful: 끔직한&lt;br /&gt;nothing but: 딴게 아니라.&lt;br /&gt;I&amp;rsquo;m a student (저 학생이에요.)&lt;br /&gt;I&amp;rsquo;m nothing but a student. (나 딴게 아니고 학생이에요.)&lt;br /&gt;&lt;br /&gt;lean on: 기대는건 면에 기대는거니까 on을 쓴다.&lt;br /&gt;everlasting: 끊임없는,&lt;br /&gt;increase 천천히 증가 , soar 가파르게 치솟는 느낌&lt;/p&gt;</description>
      <category>성장하기/  영어</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/783</guid>
      <comments>https://beepeach.tistory.com/783#entry783comment</comments>
      <pubDate>Wed, 1 Feb 2023 08:48:58 +0900</pubDate>
    </item>
    <item>
      <title>Clean Architecture - 컴포넌트 원칙</title>
      <link>https://beepeach.tistory.com/769</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 챕터에서는 3가지에 대해서 알아본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;소프트웨어 컴포넌트란?&lt;/li&gt;
&lt;li&gt;컴포넌트의 구성요소&lt;/li&gt;
&lt;li&gt;컴포넌트를 결합하여 시스템을 구성하는 방법&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;컴포넌트란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트는 시스템의 구성요소로 배포할 수 있는 가장 작은 단위이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;루비에서는 gem&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷넷에서 DLL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위프트는 컴파일 언어이기 때문에 바이너리 파일의 결합체가 하나의 컴포넌트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 설계된 컴포넌트라면 독립적으로 배포 가능해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100p에서부터는 컴포넌트의 역사에 대해서 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;컴포넌트 응집도&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스들을 어떤 컴포넌트에 넣을것인지?에 관한 세 가지 원칙이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;REP: Reuse/Release Equivalence Principle&lt;/li&gt;
&lt;li&gt;CCP: Common Closure Principle&lt;/li&gt;
&lt;li&gt;CRP: Common Reuse Principle&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;REP: 재사용 릴리스 등가 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재사용단위는 릴리스 단위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처 관점에서 보면 단일 컴포넌트는 응집성 높은 클래스와 모듈들로 구성되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 공유하는 중요한 목적이 있어야 한다,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CCP: 공통 폐쇄 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 이유로 동일한 시점에 변경되는 클래스들을 하나의 컴포넌트로 묶어라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRP를 컴포넌트 관점에서 다시 말한 원칙이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CRP: 공통 재사용 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트 사용자들을 필요하지 않은 것에 의존하게 강요하지 말아라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 같이 재사용되는 경향이 있는 클래스와 모듈을 같은 컴포넌트에 포함해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 가능성과 재사용성 사이에서 균형을 잘 이루어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 프로젝트가 진행되면서 변할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초창기에는 재사용성보다 개발가능성에 초점이 맞춰지고 이후에 점점 재사용성에 초점이 맞춰지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;컴포넌트 결합&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 컴포넌트 사이의 관계를 설명하는 세 가지 원칙&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ADP&lt;/li&gt;
&lt;li&gt;SDP&lt;/li&gt;
&lt;li&gt;SAP&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ADP: 의존성 비순환 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트 의존성 그래프에 순환이 있으면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순환 의존성을 제거하기 위해서 개발환경을 릴리즈 가능한 컴포넌트 단위로 분리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 컴포넌트를 단일 개발팀이 맞게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트를 릴리즈해서 다른 개발자들이 사용할 수 있도록 하고 릴리즈번호를 부여해서 다른 개발자들이 사용하는 디렉토리로 이동시킨 후 컴포넌트를 지속적으로 수정한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 개발자들은 릴리즈 된 버전을 이용하고 버전이 업데이트되면 새 릴리즈버전을 적용할지 고민하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 컴포넌트가 변경되더라도 다른 팀에게 영향을 바로 주지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이렇게 동작하기 위해서는 반드시 컴포넌트 의존성을 관리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성에 순환이 생기면 서로 영향을 끼치기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;117p에서부터 의존성 순환이 미치는 영향에 대해서 설명하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;순환 끊기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트 사이의 순환을 끊고 의존성을 돌리기 위해서 주요한 메커니즘 2가지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. DIP(의존성 역전 원칙) 인터페이스를 하나 만들어서 의존성을 역전시킨다.&lt;br /&gt;2. 둘 다 모두 의존하는 새로운 컴포넌트 생성하고 둘 다 의존하는 클래스들을 새로운 컴포넌트로 옮기기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트 의존성 구조는 프로그램이 성장하면서 변하게 된다. 이때 중요한 것은 의존성 순환이 발생하는지를 잘 보고 어떤 식으로든 이것을 끊어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;ADP 결론&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트구조는 하향식 설계를 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트를 가장 먼저 설계하고 개발을 하는 게 아니다. 컴포넌트는 프로그램과 같이 변경되기 때문이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 아무런 클래스도 만들지 않았는데 컴포넌트 의존성 구조를 설계하려고 하면 큰 실패를 겪게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 원하는 것은 자주 변경되는 컴포넌트들로 인해 잘 변경되지 않는 컴포넌트가 영향을 받지 않는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SDP: 안정된 의존성 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 안정된 쪽으로 의존해라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 변경이 쉽지 않은 컴포넌트를 변경이 잦을 것으로 예상되는 컴포넌트에 의존하도록 하면 절대!!! 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 변동성이 큰 컴포넌트도 변경하기 어려워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 변경하기 쉬운 모듈을 만들었어도 누군가 여기에 의존성을 걸면 내 모듈도 변경하기 힘들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경하면 다른 모듈도 변경이 필요 해질 테니까!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;안정성이란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트를 변경하기 어렵게 만드는 것 중에 하나는 수많은 다른 컴포넌트가 이 컴포넌트를 의존하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경하기 어렵다는 것은? -&amp;gt; 안정적이라는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나를 의존하는 게 많을수록 안정적이라는 뜻&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안정성 지표를 파악하려면 들어오고 나가는 의존성을 체크해보면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fan-in: 안으로 들어오는 의존성&lt;/li&gt;
&lt;li&gt;Fan-out: 밖으로 나가는 의존성&lt;/li&gt;
&lt;li&gt;I(불안정성 지표) = Fan-out % (Fan-in + Fan-out)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I는 0~1의 값을 가지고 1이면 불안정하고 0이면 안정하다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I == 1이면 최고로 불안정하다는 의미이고 이는 자신을 의존하는 컴포넌트(Fan-in)는 하나도 없지만 내가 의존하는 컴포넌트(Fan-out)는 있다는 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이 컴포넌트는 변경하지 말아야 할 이유가 없다. 즉 언젠가 변경할 일이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.52.49.png&quot; data-origin-width=&quot;1668&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sff5Q/btrTFbgGzSY/KfuAMZleVFhsKgxrxMgVbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sff5Q/btrTFbgGzSY/KfuAMZleVFhsKgxrxMgVbK/img.png&quot; data-alt=&quot;불안정한 컴포넌트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sff5Q/btrTFbgGzSY/KfuAMZleVFhsKgxrxMgVbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSff5Q%2FbtrTFbgGzSY%2FKfuAMZleVFhsKgxrxMgVbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1668&quot; height=&quot;550&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.52.49.png&quot; data-origin-width=&quot;1668&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;불안정한 컴포넌트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I == 0이면 안정한 상태이고 자신을 의존하는 컴포넌트(Fan-in)만 존재하고 내가 의존하는 컴포넌트(Fan-out)는 없다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상태는 다른 컴포넌트를 책임지며 독립적인 상태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립적이기 때문에 변경을 강제하는 의존성은 없다. 하지만 변경을 해야 한다면 의존하고 있는 컴포넌트들이 있기 때문에 변경이 쉽지 않다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.26.45.png&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AnT2s/btrTFmoJhDO/lyK36037tVUU6Rkdy6OT90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AnT2s/btrTFmoJhDO/lyK36037tVUU6Rkdy6OT90/img.png&quot; data-alt=&quot;안정한 컴포넌트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AnT2s/btrTFmoJhDO/lyK36037tVUU6Rkdy6OT90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAnT2s%2FbtrTFmoJhDO%2FlyK36037tVUU6Rkdy6OT90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1444&quot; height=&quot;562&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.26.45.png&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;안정한 컴포넌트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SDP는 I가 의존하는 방향으로 갈수록 감소해야 한다는 말을 하는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 의존하는 컴포넌트가 나보다 I가 크면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 컴포넌트가 안정한 상태이면 프로그램은 변경이 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 게 안정한 게 좋은 상황이 아니라 안정한 컴포넌트와 불안정한 컴포넌트가 섞여있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이어그램을 그릴 때는 관례적으로 불안정한 컴포넌트를 위쪽에 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 다이어그램에서 위로 향하는 화살표가 있다면 SDP를 위배하는 다이어그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SDP 문제 해결 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.36.13.png&quot; data-origin-width=&quot;1524&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwT9Tj/btrTFga1ZCx/ByKhbK8YjL4W2dZJU0q5lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwT9Tj/btrTFga1ZCx/ByKhbK8YjL4W2dZJU0q5lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwT9Tj/btrTFga1ZCx/ByKhbK8YjL4W2dZJU0q5lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwT9Tj%2FbtrTFga1ZCx%2FByKhbK8YjL4W2dZJU0q5lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1524&quot; height=&quot;312&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.36.13.png&quot; data-origin-width=&quot;1524&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 SDP를 위배하게 된다면 어떤 식으로든 의존성을 끊어내야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.46.02.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;484&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP346W/btrTGRawfSC/hTK2rXt4IlLKIQbEBLu7dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP346W/btrTGRawfSC/hTK2rXt4IlLKIQbEBLu7dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP346W/btrTGRawfSC/hTK2rXt4IlLKIQbEBLu7dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP346W%2FbtrTGRawfSC%2FhTK2rXt4IlLKIQbEBLu7dK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1260&quot; height=&quot;484&quot; data-filename=&quot;스크린샷 2022-12-15 오전 9.46.02.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;484&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DIP를 이용해서 US 프로토콜을 만들고 UServer 컴포넌트에 위치시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러고 나서 C에서 프로토콜을 채택하고 구현하면 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토콜만 포함한 컴포넌트(UServer)가 이상하게 보일 수 있지만 이 방식은 꼭 필요한 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 추상 컴포넌트라고 하며 추상 컴포넌트는 실제 구현 코드가 없기 때문에 상당히 안정적이어서&amp;nbsp; 상대적으로 I가 높은 컴포넌트가 의존하기 좋은 대상이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이는 정적 타입 언어에서만 사용하고 동적 타입 언어에서는 사용할 필요가 없다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SAP: 안정화된 추상화 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴포넌트는 안정된 정도만큼만 추상화되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAP는 안정성과 추상화 정도 사이의 관계를 정의하는 원칙이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고수준 정책을 캡슐화하는 소프트웨어는 반드시 안정된 컴포넌트(I=0)에 위치해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이렇게 하면 해당 정책을 포함하는 코드는 수정하기 힘들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I=0을 유지하면서 이를 해결하기 위해서는 OCP의 개념을 생각해보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안정된 컴포넌트는 추상 컴포넌트로 하고 안정성이 확장을 방해해서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불안정한 컴포넌트는 반드시 구체 컴포넌트여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 안정적인 컴포넌트라면 프로토콜과 추상 클래스로 구성되어 쉽게 확장할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SAP와 SDP를 같이 생각해보면 의존성은 반드시 안정한 쪽으로 향해야 하고 안정할수록 추상화가 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 컴포넌트를 클래스로 바꿔 생각해보면 DIP나 마찬가지 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상적인 것이 구체적인 것을 의존하면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;추상화 정도&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안정성 지표(I)처럼 추상화정도(A)도 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Nc: 컴포넌트의 클래스 개수&lt;/li&gt;
&lt;li&gt;Na: 컴포넌트의 추상 클래스와 인터페이스의 개수&lt;/li&gt;
&lt;li&gt;A: 추상화정도 = Na / Nc&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A는 0~1의 값을 가지며 0이면 추상 클래스가 없다는 의미이고 1이라면 추상 클래스로만 구성돼어있다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 1일 수록 추상화 정도가 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;A/I 그래프&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2022-12-16 at 7.16.08 PM.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biZV19/btrTRozonTv/KKWFvAK3uy3f7lVFhyAZS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biZV19/btrTRozonTv/KKWFvAK3uy3f7lVFhyAZS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biZV19/btrTRozonTv/KKWFvAK3uy3f7lVFhyAZS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiZV19%2FbtrTRozonTv%2FKKWFvAK3uy3f7lVFhyAZS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;435&quot; data-filename=&quot;Screenshot 2022-12-16 at 7.16.08 PM.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화정도와 안정성으로 그래프를 그려볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 그래프에서 설명하고자 하는 바는 컴포넌트가 위치해서는 안 되는 구역을 시각화해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고통의 구역&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원점에 가깝다면, 즉 고통의 구역이라면 컴포넌트는 안정적이며 구체적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 추상적이지 않아서 확장하기도 힘들고 안정적이므로 변경하기도 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일부 소프트웨어 엔티티는 여기에 위치하곤 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB Schme가 대표적인 예시이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변동성이 높지만 매우 구체적이고 많은 컴포넌트가 의존하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;쓸모없는 구역&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1.1)에 가깝다면 매우 추상적이지만 어떠한 컴포넌트도 여기에 의존하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 것은 사실상 쓸모없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;주계열&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 구역에서 최대한 멀리 존재하는 구역이 바로 주계열이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 존재하는 컴포넌트가 가장 이상적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 주계열에서 컴포넌트가 얼마나 떨어져 있는지의 정도인 D에 대해서 설명하는데 이 부분은 P137에서 설명하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Book/Clean Architecture</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/769</guid>
      <comments>https://beepeach.tistory.com/769#entry769comment</comments>
      <pubDate>Wed, 14 Dec 2022 09:17:10 +0900</pubDate>
    </item>
    <item>
      <title>Clean Architecture - 설계 원칙</title>
      <link>https://beepeach.tistory.com/759</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;좋지 못한 코드를 작성하면 아키텍처가 큰 의미가 없게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 코드가 좋아도 아키텍처를 엉망으로 만들면 큰 의미가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 코드로 좋은 아키텍처를 정의하는 원칙이 필요한데 이를 SOLID 원칙이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOLID 원칙은 함수와 데이터 구조를 클래스로 배치하고 이 클래스를 서로 결합하는 방법을 제시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 의미하는 클래스는 함수와 데이터를 결합한 집합이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOLID 원칙의 목적은 중간 수준의 소프트웨어 구조를 다음과 같이 만드는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경에 유연하다.&lt;/li&gt;
&lt;li&gt;이해하기 쉽다.&lt;/li&gt;
&lt;li&gt;많은 시스템에 사용될 수 있는 컴포넌트의 기반이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SOLID의 간단한 설명&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SRP(Single Responsibility Principle): 단일 책임 원칙&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 소프트웨어 모듈은 변경의 이유가 단 하나여야만 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;OCP(Open Closed Principle): 개방 폐쇠 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 코드를 수정하기보다 새로운 코드를 추가하는 방식으로 시스템 행위를 변경할 수 있도록 설계해아한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;LSP(Liskov Substitution Principle): 리스코프 치환 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상호 대체 가능한 구성요소를 이용해서 시스템을 만들려면 구성요소는 반드시 서로 치환가능해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;ISP(Interface Segregation Principle): 인터페이스 분리 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하지 않는 것에 의존하지 않아야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DIP(Dependency Inversion Principle): 의존성 역전 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고수준 정책&amp;nbsp;코드는 저수준 세부사항을 구현하는 코드에 의존해서는 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세부사항이 정책에 의존해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOLID는 워낙 유명하므로 자세한 설명보다는 아키텍처 관점에서 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SRP: 단일 책임 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 모듈이 단 하나의 일만 해야한다는 의미가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수는 반드시 하나의 일만 해야한다는 원칙과 헷갈리면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRP는 단일 모듈은 변경의 이유가 하나뿐이어야한다. 라는 원칙이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경을 요청하는 한명 이상의 사람, 즉 집단을 액터(Actor)라는 단어를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경을 요청하는 사람이 한명이 아닐 수 있기때문에 오해를 없애기 위해서 단어를 명확하게 한 거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하나의 모듈은 하나의 액터에 대해서만 책임을 져야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 모듈이란?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스파일이라고 생각해도 되고 만약 코드를 소스파일에 저장하지 않는 경우에는 함수와 데이터구조로 구성된 집합으로 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(클래스를 함수와 데이터의 집합이라고 본다면 이 클래스들이 모인것을 모듈이라고 생각하면 될듯하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 SRP를 위반하는 예시인 Employee 클래스를 이용해 SRP를 이해시키는 부분이 들어가있는데 여기다 옮기지는 않겠다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;67P부터 읽어보면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRP를 지키는 방법으로 여러가지가 있는데 여기서는 Data와 Method를 구분하는 방법을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이때 생기는 단점인 나눠진 클래스의 인스턴스화와 추적에 대해서는 Facade 패턴을 이용해서 해결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;OCP: 개방 폐쇄 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Artifact(개체)는 확장에는 열려 있어야하고 변경에는 닫혀 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 행위는 확장할 수 있어야하지만 이때 개체를 변경하면 안된다는 의미다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 아키텍처를 공부하는 근본적인 이유이기도한데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요구사항을 수정하다가 코드의 엄청 많은 부분을 수정해야하는 경우가 바로 이 경우다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재무 데이터 출력에 대한 예시로 이해를 돕고 있는데 이 부분은 74P를 참고하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OCP의 목표는 시스템을 확장하기 쉽게 만드는 동시에 변경으로 인해서 시스템이 너무 많은 영향을 받지 않도록 하는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는 시스템을 컴포넌트 단위로 분리하고 저수준의 컴포넌트에서 발생한 변경으로부터 고수준의 컴포넌트를 보호할 수 있는 의존성 계층 구조를 설계해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LSP: 리스코프 치환 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Subtype(하위타입)의 정의는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A타입의 객체 a와 B타입의 객체 b가 있다면 B타입을 이용해서 정의한 프로그램에서 b의 자리를 a로 바꿔도 프로그램의 행위가 변하지 않는다면 A는 B의 subtype이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LSP를 위반하는 문제로 정사각형/직사각형 문제를 예를 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 정사각형을 직사각형의 하위타입이라고 생각할 수 있지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직사각형은 가로, 세로를 따로따로 지정할 수 있지만 정사각형은 가로 세로 둘 중에 하나만 변경할 수 없기때문에 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670887880768&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let rectangle: Rectangle = ...
rectangle.setW(5)
rectangle.setH(2)
rectangle.area() == 10 // true? false?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직사각형일때는 아래가 true겠지만 정사각형이라면 false가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setH(2)를 하면 자동적으로 Width도 2로 변경되기때문!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LSP와 아키텍처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기에는 상속을 이용하도록 했지만 언어가 발전된 지금은 프로토콜을 이용해서 LSP를 지키도록 노력할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LSP를 지키지않으면 어떤일이 일어날 수 있는지는 taxi dispatch의 예를 들어서 p84에서 설명하고 있으니 읽어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ISP: 인터페이스 분리 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-13 오전 8.43.06.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H9ov0/btrTtAnh2bI/FDJzZWdECSeKc4txTqA71k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H9ov0/btrTtAnh2bI/FDJzZWdECSeKc4txTqA71k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H9ov0/btrTtAnh2bI/FDJzZWdECSeKc4txTqA71k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH9ov0%2FbtrTtAnh2bI%2FFDJzZWdECSeKc4txTqA71k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;238&quot; data-filename=&quot;스크린샷 2022-12-13 오전 8.43.06.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ISP를 설명할때 유명한 다이어그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;User1은 op2를 사용하지 않아도 해당 코드와 관련이 생길수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아래와 같이 변경하는게 좋다는 말을 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-13 오전 8.43.51.png&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H1nxp/btrTvW3ZacS/5K7bB8pGdvekdUxkVYQVN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H1nxp/btrTvW3ZacS/5K7bB8pGdvekdUxkVYQVN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H1nxp/btrTvW3ZacS/5K7bB8pGdvekdUxkVYQVN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH1nxp%2FbtrTvW3ZacS%2F5K7bB8pGdvekdUxkVYQVN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;476&quot; height=&quot;284&quot; data-filename=&quot;스크린샷 2022-12-13 오전 8.43.51.png&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요 이상으로 많은 것을 포함하는 모듈에 의존하는것은 위험하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 의존성뿐만 아니라 불필요한 재컴파일, 재배포를 강제하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 문제는 정적언어와 동적언어에 따라서 재컴파일과 재배포가 필요없을 수도 있다는 말을 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&amp;nbsp; ISP가 아키텍처가 아니라 언어와 관련된 문제라고 생각할 여지가 있다고 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DIP: 의존성 역전 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유연성이 극대화된 시스템이란 의존성이 추상에 의존하고 구체에 의존하지 않는다는것을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 규칙은 지키기 힘들다고 한다. 어쩔 수 없이 의존할 수 밖에 없지만 그래도 최대한 피하라고 설명하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상 인터페이스가 변경이 생기면 이를 구체화한 구현체도 수정을 해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 반대로 구현체를 수정한다해도 인터페이스가 변경되는 일은 거의 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;변동성이 큰 구체 클래스를 참조하지말고 추상 인터페이스를 참조하자.&lt;/li&gt;
&lt;li&gt;변동성이 큰 쿠체 클래스를 상속하지 말자.&lt;/li&gt;
&lt;li&gt;구체함수를 override하지 말자.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존성을 처리할때 추상 팩토리를 사용하는 방법에 대해서 설명을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DIP 위배를 모두 없앨 수는 없지만 DIP를 위배하는 클래스들을 구체 컴포넌트 내부로 모을 수 있고 이를 다른 부분과 분리 시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SOLID 관련 자료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Uhzoseuhkbk&quot;&gt;https://www.youtube.com/watch?v=Uhzoseuhkbk&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=Uhzoseuhkbk&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cd98pA/hyPVqsR4h8/j2EKkSa7KVJkHa5AwbPc3K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Uhzoseuhkbk&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mangkyu.tistory.com/194&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mangkyu.tistory.com/194&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664096850923&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID&quot; data-og-description=&quot;이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아&quot; data-og-host=&quot;mangkyu.tistory.com&quot; data-og-source-url=&quot;https://mangkyu.tistory.com/194&quot; data-og-url=&quot;https://mangkyu.tistory.com/194&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/C5OKF/hyPVnJGksM/UBw9SFty6MjNMXtwsiVZfK/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/cYa9fO/hyPT03Djzg/IRYMWCmrzi6d2ok0Z37L91/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/bc2BB8/hyPVp8zrTU/D8JfKCp5Ya6YA2LOJB3JZK/img.png?width=1258&amp;amp;height=426&amp;amp;face=0_0_1258_426&quot;&gt;&lt;a href=&quot;https://mangkyu.tistory.com/194&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mangkyu.tistory.com/194&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/C5OKF/hyPVnJGksM/UBw9SFty6MjNMXtwsiVZfK/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/cYa9fO/hyPT03Djzg/IRYMWCmrzi6d2ok0Z37L91/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/bc2BB8/hyPVp8zrTU/D8JfKCp5Ya6YA2LOJB3JZK/img.png?width=1258&amp;amp;height=426&amp;amp;face=0_0_1258_426');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mangkyu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Book/Clean Architecture</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/759</guid>
      <comments>https://beepeach.tistory.com/759#entry759comment</comments>
      <pubDate>Mon, 26 Sep 2022 08:52:12 +0900</pubDate>
    </item>
    <item>
      <title>Clean Architecture - 프로그래밍 패러다임</title>
      <link>https://beepeach.tistory.com/756</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;패러다임이란 프로그래밍을 하는 방법으로 대체적으로 언어에 독립적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패러다임은 어떤 프로그래밍 구조를 사용할지 언제 이 구조를 사용하는지 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재까지는 구조적(Structrued), 객체지향(Object-Oriented), 함수형(Functional) 프로그래밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 3가지 패러다임이 존재하고 아마 세 가지 외에 다른 패러다임은 존재하지 않을 것이다. &amp;lt;- 밥 아저씨 생각 뒤에 그 이유를 말해준다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구조적 프로그래밍&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초로 만들어진 패러다임은 아니지만 최초로 적용된 패러다임이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무분별한 goto문은 프로그램 구조에 해롭다는 사실로 출발해서 점프구조를 if/then/else do/while/until과 같은 구조로 대체했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한마디로 &lt;b&gt;구조적 프로그래밍은 제어흐름의 직접적인 전환에 대해 규칙을 부과한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;객체지향 프로그래밍&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째로 만들어지고 두 번째로 도입된 패러다임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 호출 스택프레임을 heap으로 옮기면서 함수 호출이 반환된 후에도 함수에서 선언한 지역변수가 유지될 수 있음을 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수가 바로 클래스의 생성자이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 포인터를 특정 규칙에 따라 사용하는 과정을 통해서 필연적으로 다형성이 등장하게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;객체지향 프로그래밍은 제어 흐름의 간접적인 전환에 대해 규칙을 부과한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 구조적프로그래밍이 직접적인 전환에 규칙을 부여한다는 건 알겠는데 객체지향이 간접적인 전환에 대해 규칙을 부과한다는 말이 뭔 말인지 이해를 못 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터와 관계가 있어 보이는데 더 읽어봐야 이해가 갈듯!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 뒤에서 다형성과 관련해서 설명을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;함수형 프로그래밍&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 처음 만들어진 패러다임이지만 가장 나중에 도입된 패러다임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수학적 문제를 해결하는 과정에서 람다 계산법을 발명했는데 이 계산법에 영향을 받아 함수형 프로그래밍이 생겨났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다 계산법에 기초는 불변성으로 값이 변경되지 않는다는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수형 언어가 변수의 값을 변경하는 방법을 제공하지만 매우 까다로운 조건에서만 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;함수형 프로그래밍은 할당문에 대해 규칙을 부과한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 패러다임은 개발자에게서 권한을 박탈한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;새로운 권한을 부여하는 것이 아니라 추가적인 규칙을 부여한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 패러다임은 무엇을 해야 할지를 말하는 게 아니라 무엇을 하면 안 되는지를 말해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 패러다임은 goto, 함수 포인터, 할당문을 제한했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 가지 말고 우리에게서 더 가져갈 건 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 무엇인가를 제한하는 부정적 의도를 가진 패러다임은 이 세 가지가 전부일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이래서 더 이상의 패러다임은 생기지 않을 것이라고 주장한 것!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;왜 패러다임을 알아봤을까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈 기반 알고리즘으로 구조적 프로그래밍을 사용하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처의 경계를 넘나들기 위해서 다형성을 이용하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수형 프로그래밍을 이용해서 데이터의 위치와 접근방법에 대해 규칙을 부과한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 가지 패러다임과 아키텍처의 세 가지 관심사(함수, 컴포넌트 분리, 데이터 관리)가 어떻게 연관되는지에 주목해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;구조적 프로그래밍&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;증명이라는 수학적인 원리를 적용하여 문제를 해결하려고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 goto 문장이 모듈을 더 작은 단위로 분해하는 과정에 방해가 되는 경우가 있다는 것을 발견한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈을 분해할 수 없다면 증명할 때 필수적인 기법인 분할 정복 접근법을 사용할 수 없게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 모듈을 분해할 때 문제가 되지 않는 goto문도 있었는데 이게 바로 if/then/else do/while과 같은 분기문과 반복문이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어 흐름을 아무 제약 없이 직접 전환 할 수 있던 과거와 달리 현재는 지원하지 않거나 아주 제한적으로 사용하도록 변했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구조적 프로그래밍을 통해서 모듈을 증명 가능한 더 작은 단위로 분해할 수 있게 됐다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 말은 즉 모듈을 기능적으로 분해할 수 있다는 의미이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 문제라도 고수준의 기능으로 분해할 수 있고&amp;nbsp;이 고수준의 기능을 저수준의 기능으로 분해할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기법을 사용하면 개발자는 대규모 시스템을 모듈과 컴포넌트로 나눌 수 있고 이 둘은 입증할 수 있는 아주 작은 기능들로 세분화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조적 프로그래밍은 프로그램을 증명 가능한 작은 기능 집합으로 재귀적으로 분해하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 테스트를 통해서 기능들이 거짓인지 증명하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거짓인지 증명하는 게 실패한다 해서 이 프로그램이 맞다는 의미는 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 의미하는 것은 이 기능들은 목표에 충족시킬 만큼만 참이라고 여길 수 있게 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(언제든 우리가 생각하지 못한 반례가 있을 수 있는 가능성이 있다. 테스트가 통과한다고 해서 무조건 맞는 게 아니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조적 프로그래밍이 가치 있는 이유는 &lt;b&gt;프로그래밍에서 반증 가능한 단위를 만들어 낼 수 있는 능력 때문이다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈, 컴포넌트, 서비스가 쉽게 반증 가능하도록 즉, 테스트하기 쉽도록 만들기 위해서 노력해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서 구조적 프로그래밍과 비슷한 제한적인 규칙들을 활용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;객체지향 프로그래밍&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 아키텍처를 만드는 것은 객체 지향 설계 원칙을 이해하고 응용하는데서 출발한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체지향(Object Oriented)란 이미 많이 정리된 게 있으니 여기서의 설명은 넘어가고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처의 관점에서 보는 객체지향이란 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;캡슐화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터와 함수가 집단을 서로 구분 짓는 선을 그을 수 있게 된다. 밖에서 데이터는 숨겨지고 일부 함수만 외부에 노출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제로 많은 객체지향 언어가 캡슐화를 강제하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오히려 C언어에서 더 강력한 캡슐화가 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 아키텍처 관점에서 크게 중요한 부분이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;상속&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상속이란 단순히 어떤 변수와 함수를 하나의 범위로 묶어서 재정의하는 일에 불과하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 언어에 관련 없이 C에서도 가능한 방법이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 다중 상속이나 업캐스팅 같은 것을 쉽게 해 준 것은 맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 아키텍처 관점에서 중요한 부분이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;다형성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C에서도 다형성을 이용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 가리키는 포인터를 응용한 것이 다형성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체지향 언어는 다형성을 새로 제공한것은 아니지만 안전하고 편리하게 사용할수 있게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포인터를 이용하는 것은 위험을 수반하게 되는데 객체지향언어는 이러한 단점을 없애주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 객체지향은 제어 흐름을 간접적으로 전환하는 규칙을 부과한다고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 관점에서 본다면 캡슐화와 상속보다는&lt;b&gt; 다형성이 아키텍처 측면에서 의미가 크다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에서 들고 있는 예시는 복사하는 함수에서 입출력 장치가 변경되면 프로그램에서 변경되어야 하는 부분이 있는가를 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복사 코드는 입출력 드라이버 코드에 의존하지 않기 때문에 새로운 입출력 장치가 생겨도 복사 코드는 변경할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 입출력 드라이버가 복사 프로그램에 플러그인(Plugin)되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인 아키텍처는 입출력 장치 독립성을 지원하기 위해서 만들어졌고 등장 이후 거의 모든 OS에서 구현되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 초기에는 포인터를 직접 사용해야 했기 때문에 플러그인 개념을 프로그램에 적용하기 쉽지 않았지만 객체지향이 등장하고 나서 이러한 위험이 사라졌기 때문에 플러그인 아키텍처를 적용할 수 있게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;의존성 역전&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다형성을 자유롭게 사용하지 못했을 때의 메커니즘을 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전형적인 호출트리의 경우 고수준 함수가 중간 수준 함수를 중간 수준 함수가 저수준 함수를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우 &lt;b&gt;소스코드 의존성의 방향은 반드시 제어 흐름의 방향을 따르게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 다형성을 추가하면 이 흐름이 깨지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인터페이스를 통해서 간접적으로 고수준 모듈이 저수준 모듈의 함수를 호출한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 고수준 모듈과 인터페이스 간의&lt;b&gt; 코드 의존성이 제어 흐름과 반대가 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체지향 언어가 다형성을 안전하고 편리하게 제공한다는 것은 인터페이스를 추가함으로써 소스코드의 의존성을 어디에서든 역전시킬 수 있다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그럼 개발자가 코드의 의존성 방향을 결정할 수 있는 절대적 권한을 가지게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 바로 아키텍처 관점에서 객체지향이 가지는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 이걸 이용하면 비즈니스 룰이 UI와 DB에 의존하는 대신에 시스템의 코드 의존성을 반대로 배치하여 UI와 DB가 비즈니스 룰에 의존하게 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 비즈니스룰 코드에서는 UI나 DB를 호출하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 되면 이 3가지를 분리된 컴포넌트로 만들 수 있고 비즈니스 룰을 포함하는 컴포넌트는 UI와 DB에 의존하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 특정 컴포넌트에 소스코드가 변경돼도 나머지 컴포넌트에 영향을 주지 않는다. 그렇게 되면 배포 독립성과 개발 독립성이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면 객체지향은 다형성을 이용해서 전체 시스템의 모든 소스코드 의존성에 대한 절대적인 제어 권한을 가지게 만들어 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용하면 플러그인 아키텍처를 구축할 수 있고 고수준 모듈은 저수준 모듈에 대해서 독립성을 보장받게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;함수형 프로그래밍&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수형 언어에서는 변수가 변경되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처 관점에서 이게 왜 중요할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멀티 스레드와 프로세스를 사용하는 앱에서 마주치는 모든 문제는 가변 변수가 없다면 일어나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장공간이 무한하고 프로세스가 무한히 빠르다면 불변성의 문제는 크게 문제 될 게 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현실을 그렇지 않으므로 적절한 선에서 타협해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;앱 내부의 서비스를 가변 컴포넌트와 불변 컴포넌트로 분리하는 일&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수를 변경해야 하는 컴포넌트와 변경하지 않는 컴포넌트로 분리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이렇게 하기 위해서 가변 변수를 보호하는 수단을 동원해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;다시 한번 정리&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조적 프로그래밍은 제어 흐름의 직접적인 전환에 제한을 건다.&lt;/li&gt;
&lt;li&gt;객체지향 프로그래밍은 제어흐름의 간접적인 전환에 제한을 건다.&lt;/li&gt;
&lt;li&gt;함수형 프로그래밍은 변수 할당에 제한을 건다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Book/Clean Architecture</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/756</guid>
      <comments>https://beepeach.tistory.com/756#entry756comment</comments>
      <pubDate>Sun, 18 Sep 2022 12:03:29 +0900</pubDate>
    </item>
    <item>
      <title>Clean Architecture - Robert C. Martin</title>
      <link>https://beepeach.tistory.com/755</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;book-library-with-open-textbook.jpg&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1001&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRGP95/btrMkHf2A4I/pI2eWbCdPBSqmrWoxIPXDk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRGP95/btrMkHf2A4I/pI2eWbCdPBSqmrWoxIPXDk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRGP95/btrMkHf2A4I/pI2eWbCdPBSqmrWoxIPXDk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRGP95%2FbtrMkHf2A4I%2FpI2eWbCdPBSqmrWoxIPXDk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;406&quot; data-filename=&quot;book-library-with-open-textbook.jpg&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1001&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면서 읽지 않으면 다 까먹어 버리기 때문에... 정리해가면 읽는 Clean Architecture&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 정리하면서 읽어도 까먹는건 똑같지만 핵심을 다시 보기엔 편하므로 읽으면서 정리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빨리 가는 유일한 방법은 제대로 가는 것이다. - Robert C. Martin&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서문&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처 규칙은 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근본적으로 다른 시스템들이 왜 비슷한 아키텍처 규칙을 공유하는 것일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 소프트웨어 아키텍처의 규칙은 다른 모든 변수에 독립적이다. &amp;lt;-- 밥아저씨의 생각&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 여전히 sequence, selection, iteration의 집합체일 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언어가 발전하고 도구가 좋아졌지만 프로그래밍을 이루는 기본 구성요소는 조금도 바뀌지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 코드가 변하지 않았다는 사실이 시스템 종류와 상관없이 아키텍처의 규칙이 일관된 이유이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아키텍처의 규칙이란 프로그램의 구성요소를 정렬하고 조립하는 방법에 관한 규칙이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성요소들이 변하지 않았으므로 구성요소들을 정렬하는 규칙도 변한것이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 바로 이러한 규칙에 관한 책이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램을 동작하게 만드는것은 그리 어려운 일이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 제대로 만드는 일은 전혀 다르다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제대로 만들게 되면 소수의 인원으로도 프로그램이 지속적으로 동작하게 만들 수 있다. 그리고 새로운 기능을 추가하고 유지보수할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 우리의 상황은?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 강하게 연관되고 복잡하게 결합되어 있어서 작은 변경에도 많은 시간이 걸릴 뿐만 아니라 제대로 동작하지 않는 위험을 감수해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;설계(Design)와 아키텍처(Architecture)란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설계는 무엇이고 아키텍처는 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;둘 사이에는 차이가 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 설계는 저수준의 구조 또는 결정사항을 의미하고 아키텍처는 고수준의 무언가를 가리킬 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 저수준이든 고수준이든 이 둘을 구분 짓는 경계는 뚜렷하지 않다. 그래서 둘 사이에는 차이가 없다고 봐도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고수준에서 저수준으로 향하는 의사결정의 연속성만이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이러한 의사결정의 목표는?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 소프트웨어 아키텍처의 목표는 시스템을 만들고 유지보수하는데 투입되는 인력을 최소화하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 설계란 고객의 요구를 만족시키는데 드는 비용이 적고 시스템의 수명이 다할 때까지 이 비용을 낮게 유지시키는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 기능이 추가될 때마다 비용이 증가하면 좋은 설계라고 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자들은 &quot;코드는 나중에 정리하면 돼! 당장은 시장에 출시하는 게 먼저야!&quot;라는 거짓말에 속는다&lt;/b&gt;. - 완전 뜨끔...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 만들어야 할 기능들이 기다리고 있으므로 이전에 작성한 코드로 돌아가서 정리하는 일은 일어나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 결국 생산성은 0을 향해 가기 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 처음부터 다시 시스템을 재설계하는 것이 해답이라고 생각할 수 있지만 이러한 생각은 잘못됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신을 과신한다면 재설계를 하더라고 원래 코드와 같이 똑같이 엉망으로 내몰린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 조직이 할 수 있는 최고의 선택지는 과신을 인지해서 방지하고 아키텍처의 품질을 심각하게 고민하기 시작하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 어떤 아키텍처가 좋은 아키텍처인지 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비용을 최소화하고 생산성은 최대화할 수 있는 설계와 아키텍처를 만들려면 시스템 아키텍처가 지닌 속성을 이해해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에서는 훌륭하고 깔끔한 아키텍처와 설계가 무엇인지에 대해서 다루고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;두 가지 가치에 대해서&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자들은 두 가지 가치를 제공해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행위(Behavior)와 구조(Structure)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 두 가지를 모두 높게 유지할 책임이 있는데 대부분은 한 가지에 집중하고 나머지는 버리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;행위&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자들은 기계가 요구사항을 만족하도록 코드를 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분 개발자들이 이러한 활동이 자신의 할 일의 전부라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;구조&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어가 가진 본연의 목적을 추구하려면 소프트웨어 이름답게 부드러워야 한다. 즉 변경이 쉬워야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능에 변경사항이 있으면 이 변경을 쉽게 적용할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 변경사항을 적용하는데 드는 어려움은 변경되는 범위에 비례해야 하고 형태와는 관련이 없어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경사항의 형태와 관계가 있게 되면 새로운 요청사항이 발생할 때마다 적용하는 게 힘들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 시스템의 형태와 변경사항의 형태가 서로 맞지 않기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 &lt;b&gt;아키텍처는 형태에 독립적이어야 하고 이럴수록 더 실용적이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 시스템이 동작하도록 만드는 게 중요한가? 변경을 쉽게 하도록 만드는게 중요한가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자는 대다수가 동작하는 게 중요하다고 대답할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 양 극단의 사례를 들면 명확해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 완벽하게 동작하지만 수정이 아예 불가능한 프로그램이 있다면 이는 요구사항이 변경되면 동작하지 않게 되고 결국에는 프로그램이 동작하지 않게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 동작하지는 않지만 변경이 쉬운 프로그램이 있다면 이를 돌아가도록 만들 수 있고 변경사항이 있어도 동작하도록 유지 보수할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 변경이 아예 불가능한 프로그램이란 없으니 이 예시가 올바르다곤 할 수없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 현실적으로 변경에 들어가는 비용이 변경으로 인한 수익보다 높은 경우 변경하는 게 불가능하다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 중요한 건 변경 비용이 너무 커서 현실적으로 변경을 할 수 없는 상태가 된다면 이 상황이 될 때까지 프로그램을 방치한 개발자에게 책임이 있다는 건 분명하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 일은 긴급함과 중요함이 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이를 통해 4가지로 분류가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 긴급하고 중요한 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 긴급하지 않지만 중요한 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 긴급하지만 중요하지 않은 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 긴급하지도 않고 중요하지도 않은 일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처는 2번째에 해당하는 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행위는 1, 3번째에 해당하는 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 것은 3번째에 해당하는 일을 1번째로 격상시키는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴급하지만 중요하지 않은 일과 진짜 긴급하고 중요한 일을 구분하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 일 때문에 중요도가 높은 아키텍처를 무시한 채 기능을 택하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리자는 보통 아키텍처의 중요성을 모르기 때문에 개발자는 딜레마에 빠진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 개발자를 고용하는 이유는 이 딜레마를 해결하기 위해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;따라서 기능의 긴급성이 아닌 아키텍처의 중요성을 설득하는 일은 개발팀이 책임져야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나만 기억하자&lt;b&gt; 아키텍처가 후순위가 되면 시스템 개발비용이 점점 증가하고 시스템을 변경하는 게 현실적으로 불가능해지는 순간이 온다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 상황이 발생하는 것은 전적으로 개발팀이 스스로 옳다고 믿는 가치를 위해 충분히 투쟁하지 않았다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2장은 다음 시간에!&lt;/p&gt;</description>
      <category>Book/Clean Architecture</category>
      <category>CleanArchitecture</category>
      <category>독서</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/755</guid>
      <comments>https://beepeach.tistory.com/755#entry755comment</comments>
      <pubDate>Sat, 17 Sep 2022 19:47:39 +0900</pubDate>
    </item>
    <item>
      <title>Swift - Result Type</title>
      <link>https://beepeach.tistory.com/701</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;542.jpg&quot; data-origin-width=&quot;3103&quot; data-origin-height=&quot;2000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAqilp/btrx4SHVWee/bLaSlejeYT9sEhyOGSK1D0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAqilp/btrx4SHVWee/bLaSlejeYT9sEhyOGSK1D0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAqilp/btrx4SHVWee/bLaSlejeYT9sEhyOGSK1D0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAqilp%2Fbtrx4SHVWee%2FbLaSlejeYT9sEhyOGSK1D0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3103&quot; height=&quot;2000&quot; data-filename=&quot;542.jpg&quot; data-origin-width=&quot;3103&quot; data-origin-height=&quot;2000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요 BeePeach입니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 공부해볼 내용은 Swift5부터 새롭게 추가된 Error handling 방식인 Result입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(작성하다가 다 날아가서 다시 작성하는 ㅠㅠ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result를 이해하기 위해서는 Enumeration과 Associated Value 그리고 Generic을 정확하게 이해하고 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 사용하던 throws는 이 함수, 메서드, 클로저, 생성자가 Error를 던질 수 있다는 것을 나타냈지만 어떤 형식의 Error가 전달될지는 알려주지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 do-catch문에서 Error를 처리할 때 패턴 매칭을 이용하거나 타입 캐스팅을 하는 방식으로 Error를 특정한 뒤에 처리해야 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식이 완전 나쁜 방식은 아니지만 문제는 컴파일 타임에 형식을 할 수 없다는 큰 단점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 만약 catch로 처리하지 못한 Error가 있다면 crash가 발생하는 경우도 종종 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면에 Result Type은 Error의 타입을 특정할 수 있기 때문에 컴파일 시점에 알 수 있게 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 do-catch처럼 Error 프로토콜 타입으로 처리할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 throws 키워드를 사용하지 않고 Result를 리턴하는 메서드를 만들어서 Error를 발생시킬 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 Result는 어떠한 장점을 가지고 있는지 같이 공부해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Result &amp;nbsp;Type&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-03-31 at 1.26.26 AM.png&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7k1ft/btrx0uWbq1r/C1s4Tw8Q3OAsyGLfrdSx9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7k1ft/btrx0uWbq1r/C1s4Tw8Q3OAsyGLfrdSx9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7k1ft/btrx0uWbq1r/C1s4Tw8Q3OAsyGLfrdSx9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7k1ft%2Fbtrx0uWbq1r%2FC1s4Tw8Q3OAsyGLfrdSx9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1836&quot; height=&quot;388&quot; data-filename=&quot;Screen Shot 2022-03-31 at 1.26.26 AM.png&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result는 Generic Enum으로 선언되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Enum case에는 success와 failure가 있고 모두 associated value(연관 값)을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 타입 파라미터로 Sucess와 Failure를 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Success는 모든 타입이 가능하지만 Failure는 Error 프로토콜 타입만 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공하면 success case의 연관 값에 데이터를 담으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패하면 failure case의 연관 값에 Error를 담으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하죠? 그럼 Result 인스턴스를 생성하는 방법부터 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Result 생성하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result는 enum이기 때문에 Type이죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 인스턴스를 생성자로 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;create를 파라미터로 받는 생성자를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파라미터로 throws 클로저를 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 클로저에서 바로 try로 호출하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/76a10a7678563bf36f21d8080fe39f9b.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 NumberError를 선언했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 check(number)라는 throwing func을 정의했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0보다 작다면 NumberError.negativeNumber&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;100보다 크다면 NumberError.largeNumber(over:) Error를 throw하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 do-catch로 이 함수를 처리하는 방법을 먼저 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/4569c57724cd8c6bc682a58c7de89db0.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do-catch를 이용하면 이런 식으로 사용할 수 있겠죠??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;check(number:) 함수가 Error를 던진다면 catch로 Error가 전달되는데 이때 Error의 타입은 Error입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NumberError가 아니죠!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 사용할 때 패턴 매칭이나 타입 캐스팅을 이용해서 경우에 맞게 처리를 해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 그냥 catch로 &amp;nbsp;Error의 종류를 따지지 않고 모두 처리해버릴 수도 있죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이번엔 Result 인스턴스를 생성해서 처리해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/fb08e326aa102c416cda0423c6f314c5.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result에서 제공하는 생성자를 이용해서 클로저에 check(number:) throwing 함수를 호출했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;check(number:)가 성공하면 Int를 리턴하고 실패하면 Error를 던지기 때문에 Type이 Result&amp;lt;Int, Error&amp;gt;가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Result 인스턴스를 생성할 때 NumberError로 Error를 지정하면 에러가 발생합니다. 이 부분에 대해서는 공부가 조금 더 필요할 거 같습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 Result를 사용하면 Error의 Type을 특정할 수 있다면서 아니잖아 똑같은데?? 라고 생각할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error의 Type을 특정하는 방법은 바로 뒤에서 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이렇게 처리하면 do-catch와 뭐가 다를까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Error의 처리 시점이 달라졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do-catch에서는 Error처리 시점이 try를 이용해 throws 함수를 호출할 때 이루어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Result를 이용하면 Error처리 시점이 try를 이용해 함수를 호출할 때가 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과를 처리할 때 Error를 처리하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 처리하는 방법이 조금 달라졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result는 enum이기 때문에 switch로 처리가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이렇게 case별로 나누어서 처리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;success라면 try의 실행결과가 연관 값에 담깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패하면 error가 연관 값에 담깁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 Result에 다른 용도에 대해서 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Result를 리턴하는 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws를 이용해서 Error를 throw 하는 함수 대신 Result를 리턴하는 함수를 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 만들어보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/4bce7a26b4fb7665c17ecd2ef2c8313a.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 check(number:) 함수의 리턴 타입을 Result&amp;lt;Int, NumberError&amp;gt;로 변경했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 check(number:)의 리턴 타입이 Int였고 Error가 발생하면 NumberError를 throw 했었기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 변경하면 이제&amp;nbsp;throws 키워드는 필요 없어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐하면 실패할 경우&amp;nbsp;Error를 throw 하지 않고 failure case의 연관 값에 Error를 담아서 리턴하기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throw 키워드를 사용하지 않으니 throws키워드도 필요 없어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0 보다 작다면 NumberError에 negativeNumber Error를 Result의 failure case에 연관 값에 담아 리턴해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발생할 Error가 NumberError라는 게 특정이 됐기 때문에 생략하고 .negativeNumber로 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비슷한 예시로 1000보다 클 경우 Error를 담아서 리턴해야 하는데 리턴 타입이 Result인 것을 알고 있죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 Line 7처럼 Result도 생략이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 정상적으로 흘러갔다면 성공입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 success case에 원하는 데이터를 연관 값으로 담아서 리턴하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result가 제네릭이기 때문에 정의할 때 타입을 명시해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 Error가 어떤 형식인지 컴파일 타임에 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 이 함수를 어떻게 사용하는지 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/a78612b932c8e3dcd8ca8cc5a76a9610.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;checkWithResult(number:) 함수를 호출할 때 try? 또는 do-catch를 사용하지 않아도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws 키워드가 없기 때문이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 결과를 처리할 때 이제 Error의 타입이 NumberError인 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Result를 이용하면 throws 키워드를 사용하지 않고 Error를 전달할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 사용할 때 try 또는 do-catch를 사용하지 않아도 되겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Error의 Type을 컴파일 시점에 명확하게 알 수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 do-catch문에서는&amp;nbsp;do에서 throws함수를 호출하고 catch에서 Error를 처리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 throws 함수를 호출할 때 Error를 처리해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 Result는 호출할 때가 아니라 결과를 사용할 때 에러를 처리하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result 인스턴스를 생성할 때 즉 throws함수를 호출할 때 에러 처리를 하지 않고 Result 인스턴스를 참조하고 있다가 결과를 처리할 때 에러를 처리하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Result에서 제공하는 메서드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result에서 제공하는 몇 가지 메서드들이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;get&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tFrS4/btrx6YH8H7k/L9gEzhKbruGekByReylNYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tFrS4/btrx6YH8H7k/L9gEzhKbruGekByReylNYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tFrS4/btrx6YH8H7k/L9gEzhKbruGekByReylNYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtFrS4%2Fbtrx6YH8H7k%2FL9gEzhKbruGekByReylNYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;996&quot; height=&quot;334&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result가 제공하는 get 인스턴스 메서드는 Success 타입을 리턴하는 throws 메서드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 우리가 Result를 리턴하는 함수를 만들었는데 이 함수를 이전에 throws를 포함한 함수처럼 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 메서드를 이용해서 do-catch, try?로 에러를 처리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/8934f0c8d5952b50b4caca7f633d1c5d.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 Result를 리턴하는 함수를 처리할 때는 switch를 이용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 switch이기 때문에 success만 처리하고 싶다면 failure부분을 break 하거나 default를 이용해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 여기서 Result에서 제공해주는 get 메서드를 이용하면 Optional try와 함께 처리해서 success만 처리하거나 do-catch를 이용해서 에러 처리를 할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 async 한 코드에서 completion handler로 Result를 사용하는 예시를 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고자료&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/result&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/documentation/swift/result&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648706951453&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apple Developer Documentation&quot; data-og-description=&quot;&quot; data-og-host=&quot;developer.apple.com&quot; data-og-source-url=&quot;https://developer.apple.com/documentation/swift/result&quot; data-og-url=&quot;https://developer.apple.com/documentation/swift/result&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swift/result&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.apple.com/documentation/swift/result&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apple Developer Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.apple.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kxcoding.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kxcoding.com&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648706962989&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;여러분의 새로운 도전을 응원합니다 | KxCoding&quot; data-og-description=&quot;Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기&quot; data-og-host=&quot;kxcoding.com&quot; data-og-source-url=&quot;https://kxcoding.com&quot; data-og-url=&quot;https://kxcoding.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bH3vZY/hyNR2owhIS/fHGj46CMaQq2dCFGah3IJK/img.png?width=2048&amp;amp;height=1537&amp;amp;face=0_0_2048_1537,https://scrap.kakaocdn.net/dn/fisF9/hyNR40UuZI/ETsIY3SwEEG3lUVzhNmrOk/img.png?width=2048&amp;amp;height=1537&amp;amp;face=0_0_2048_1537,https://scrap.kakaocdn.net/dn/izNkS/hyNSe3yHEu/KYEdGK7qBiiKHBwmGTvw70/img.png?width=2049&amp;amp;height=1536&amp;amp;face=0_0_2049_1536&quot;&gt;&lt;a href=&quot;https://kxcoding.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kxcoding.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bH3vZY/hyNR2owhIS/fHGj46CMaQq2dCFGah3IJK/img.png?width=2048&amp;amp;height=1537&amp;amp;face=0_0_2048_1537,https://scrap.kakaocdn.net/dn/fisF9/hyNR40UuZI/ETsIY3SwEEG3lUVzhNmrOk/img.png?width=2048&amp;amp;height=1537&amp;amp;face=0_0_2048_1537,https://scrap.kakaocdn.net/dn/izNkS/hyNSe3yHEu/KYEdGK7qBiiKHBwmGTvw70/img.png?width=2049&amp;amp;height=1536&amp;amp;face=0_0_2049_1536');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;여러분의 새로운 도전을 응원합니다 | KxCoding&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kxcoding.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Swift</category>
      <category>failure</category>
      <category>result</category>
      <category>Success</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/701</guid>
      <comments>https://beepeach.tistory.com/701#entry701comment</comments>
      <pubDate>Wed, 30 Mar 2022 20:07:29 +0900</pubDate>
    </item>
    <item>
      <title>Swift - Error Handling(do-catch, try?, try!)</title>
      <link>https://beepeach.tistory.com/688</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;30366.jpg&quot; data-origin-width=&quot;6422&quot; data-origin-height=&quot;3425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP93fx/btrxJqUk5V6/PwU6qBMDo2jnxUOa8BQr2k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP93fx/btrxJqUk5V6/PwU6qBMDo2jnxUOa8BQr2k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP93fx/btrxJqUk5V6/PwU6qBMDo2jnxUOa8BQr2k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP93fx%2FbtrxJqUk5V6%2FPwU6qBMDo2jnxUOa8BQr2k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6422&quot; height=&quot;3425&quot; data-filename=&quot;30366.jpg&quot; data-origin-width=&quot;6422&quot; data-origin-height=&quot;3425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요 BeePeach입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Error Handling 방법 중에 2, 3번째에 해당하는 do-catch와 Optional try에 대해서 공부해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;try와 do-catch&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 try는 이전 포스팅에서 사용해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 try를 사용했더니 Error를 handling하고 있지 않다고 컴파일 에러가 나서 throws를 추가해 문제를 해결했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 4가지 방법중 첫 번째 방법인 propagating error입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws를 사용하지않고 try를 사용하는 방법은 do-catch문과 함께 사용하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;do-catch&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do-catch문은 Error 예외처리를 할 때 많이 사용하는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do 안에서 try와 함께 Error를 throw하는 코드를 호출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 아무런 에러가 발생하지 않았다면 원하는대로 나머지 코드를 작성하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catch는 do에서 작성한 코드에 Error가 발생했을 때 예외처리를 하는 부분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 pattern matching을 사용해서 Error별로 따로 처리할 수도 있고 한 번에 모두 처리할 수 도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 do-catch로 try로 발생가능한 Error를 모두 처리했다면 throws를 사용하지 않아도 더 이상 Error를 handling 하고 있지 않는다는 &amp;nbsp;에러가 발생하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 문법부터 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/5f31efed8cb4de1b5aaa9de31e5a1808.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do - catch에서 do는 필수적인 부분입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catch는 없어도 되는 부분이지만 catch가 없거나 catch로 발생 가능한 Error의 모든 부분을 처리하지 못한다면 throws 키워드를 이용해서 propagating Error를 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do 코드 블록 안에서 try를 이용해 throws 함수를 호출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Errorr가 발생하지 않고 무사히 실행되면 바로 아래에 코드가 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Error가 발생한다면 catch문으로 넘어가게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 패턴 매칭을 이용해서 각 Error에 맞는 예외 처리를 해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;where을 이용해서 조건을 추가하거나 ,(comma)를 이용해서 여러 개의 패턴을 한 번에 매칭 하는 것도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 바로 예시를 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/f01139d4b612fb643d972ddf0bf93cac.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://beepeach.tistory.com/686&quot;&gt;이전 포스팅&lt;/a&gt;에서 사용했던 예시를 사용하도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VendingMachine이라는 class와 Error를 정의했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/ff3f29b2c38f21965600c30db7033619.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에는 throws로 만들었던 buyFavoritesDrink 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이번에는 throws 키워드를 삭제했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 do-catch문을 선언하고 여기서 try를 사용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 vend(itemNamed:) 메서드가 Error 없이 실행된다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Get Drink!!&quot;라는 문구가 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Error가 발생한다면 아래 catch문으로 넘어가게 되고 패턴에 맞는 코드가 실행되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기선 coin이 부족해서 500원을 더 넣어주라는 문구가 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Catch 주의사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catch문을 사용할 때는 catch의 순서에 주의해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if else 문을 생각하시면 이해하기 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catch문은 위에서부터 매칭을 하기 때문에 만약 맨 위의 catch문에서 광범위한 error를 처리하게 되면 대부분의 에러는 여기에 걸리고 맙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 catch를 작성할 때는 까다로운 조건부터 작성해주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어서 위 예시에서 catch를 가장 위로 올려보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/289b249057a50fd62804f69d1be6331b.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;catch문의 위치만 변경됐을 뿐인데 결과가 달라졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 catch는 맨 처음 catch문에 걸리므로 어떤 Error가 발생해도 해당 catch문만 실행되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 아래 코드는 의미가 없어진 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 주의사항은 catch로 모든 Error를 처리하지 못했다면 throws로 Error를 전파해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/04786c07a7ffebaeeaf4bdf3976d896a.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서는 catch문으로 try로 실행된 throws 메서드의 모든 Error를 처리하지 못했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VendingMachineError.insufficientFunds 경우가 빠졌죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 이전에 try를 혼자 사용했던 것처럼 Error를 handling하지 못했다는 에러가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이전에 하던 것과 마찬가지로 함수 파라미터 뒤에 throws 키워드를 이용해서 이 함수가 Error를 전파할 수 있도록 해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 예제에 보면 throws 키워드가 추가된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Optioanl try&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;try에는 try? try! 키워드도 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;? 과 !를 보면 떠오르는 것은 Optional이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 키워드도 Optional과 관계가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;try? 는 Optional try라고 불립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Error가 발생한다면 nil이 리턴됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;try!는 Forced try라고 불립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;try!는 Error가 발생하지 않는다고 확실할 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 do-catch 또는 throws를 사용하지 않고 throws 함수를 쉽게 실행할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 만약 Error가 발생한다면 crash가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편리하지만 되도록 사용하지 않아야 하는 키워드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/cdb2c596ba5733dc71083e21041a8162.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시에서는 랜덤 한 number를 생성하고 만약 0보다 작다면 NumberError.negativeNumber Error를 던지고 아니라면 number를 리턴하는 함수를 정의했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이 함수를 호출하는데 do-catch를 쓰지 않고 바로 try?를 이용해서 호출했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 에러가 발생한다면 x에는 Error가 담기는 게 아니라 nil이 할당됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 아래 do-catch로 작성한 코드와 같은 코드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실패하면 nil이 리턴되므로 주로 optional binding과 함께 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 하나 더 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/0b51e4b0f1c7782288630e4031cd32f4.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 do-catch로 작성해야 하는 코드를 optional binding과 함께 사용해서 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Swift</category>
      <category>catch</category>
      <category>do</category>
      <category>try!</category>
      <category>try?</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/688</guid>
      <comments>https://beepeach.tistory.com/688#entry688comment</comments>
      <pubDate>Tue, 29 Mar 2022 23:12:10 +0900</pubDate>
    </item>
    <item>
      <title>Swift - Error Handling (throws와 rethrows)</title>
      <link>https://beepeach.tistory.com/692</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요 BeePeach입니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 이전에 공부했던 throws와 헷갈리기 쉬운 rethrows에 대해서 공부해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;throws&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws 키워드 말고 rethrows라는 키워드도 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;rethrows는&amp;nbsp;&lt;/span&gt;&lt;b&gt;파라미터&lt;/b&gt;로 throws를 포함하는 함수를 받을 때 사용하는 키워드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 '파라미터로 throws 함수를 받는다'라는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 외부에 존재하는 throws 함수를 사용하는 것과 구별해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/6811a633d27efdad75db97956b1d4753.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;My&lt;span&gt;Error를 정의해주고 someErrorFunction을 정의했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수는 단순하게 Error를 던지는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부에서 Error를 throw 하고 있으니까 throws 키워드를 사용해줘야겠죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지는 이전 포스팅에서 공부한 내용입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/0abcacef4e1681cba6bf30ab94ed44ce.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 파라미터로 callback이라는 이름으로 throws 함수를 받는 함수 2개를 선언했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nonThrowsFunction(callback:) 함수는 throws 키워드가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throwsFunction(callback:) 함수는 throws 키워드가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 두 함수 모두 파라미터로 callback이라는 함수를 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 파라미터 함수는 throws 키워드를 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 파라미터 함수를 호출할 때 try를 적어서 이 파라미터가 호출할 때 Error가 발생할 수 있는 함수라고 알려줘야 하죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 함수에 throws 키워드가 있다면 그냥 try만 적어주고 파라미터를 호출해도 문제가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 배운 Propagate Error를 이용한 에러 처리 방법이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 throws 키워드가 없는 nonThrowsFunction(callback:) 함수는 그냥 try만을 사용하면 안됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do-catch를 이용하거나 try? try!를 이용해서 에러 처리를 해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지도 이전 포스팅에서 배운 내용입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 진짜 rethrows를 다뤄보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;rethrows&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/e8a943d07097c3a8b4bc5bf29e46053c.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws와 비교하기 위해서 이전에 정의했던 throwsFunction(callback:)과 함께 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrows는 throws 대신 rethrows를 적어주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 파라미터로 전달되는 함수가 throws일 때 적어주는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 파라미터로 기본 함수가 전달되는데 rethrows를 적으면 컴파일 에러가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 간단한 차이점을 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 rethrows 함수는 내부에서 바로 throw 키워드를 사용할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrowsFunction(callback:) 함수를 보면 바로 throw를 사용했는데 에러가 나는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면에 throwsFunction(callback:) 함수는 throw를 바로 사용해도 에러가 나지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 throw를 사용하고 싶다면 함수에 throws 키워드를 적어줘야 했다는 것을 기억해주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 그렇다고 rethrows에서 throw키워드를 완전히 못쓰는 것일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그건 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do-catch에서 catch 부분에서 throw를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 여기서도 주의할 점은 파라미터로 전달된 함수가 아니라면 throw 할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;anotherRethrowsFunction(callback:) 함수를 보면 파라미터로 받은 함수에 대해서는 throw 할 수 있지만 외부에 존재하는 함수는 throw할 수 없는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 rethrows가 파라미터로 받은 함수에 대해서 작용하는 키워드이기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 부분만 차이가 있다면 의아한 부분이 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니 그냥 다 throws로 하면 내부에서 바로 throw도 할 수 있고 외부 함수에 대해서 throw로 할 수 있는데 뭐하러 rethrows를 써?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에도 throwsFunction(callback:) rethrowsFucntion(callback:)은 throws와 rethrows 키워드를 제외하면 겉보기에 차이가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 반드시 파라미터로 throws함수를 받으면 rethrows를 사용해야 해!라는 제약이 걸린 것도 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시에서도 보면 파라미터로 throws 함수를 받을 때 rethrows대신 throws키워드를 사용해도 무리가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오히려 rethrows를 사용하면 제약이 더 생기는 것같이 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;사용성의 차이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrows를 사용하고 있는 예시를 보면 왜 rethrows를 사용하는지 이해할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2022-03-27 at 12.19.25 PM.png&quot; data-origin-width=&quot;2540&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mIld2/btrxmBa0wQ8/ZqkRryWeoX5X05WdK4I7a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mIld2/btrxmBa0wQ8/ZqkRryWeoX5X05WdK4I7a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mIld2/btrxmBa0wQ8/ZqkRryWeoX5X05WdK4I7a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmIld2%2FbtrxmBa0wQ8%2FZqkRryWeoX5X05WdK4I7a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2540&quot; height=&quot;296&quot; data-filename=&quot;Screen Shot 2022-03-27 at 12.19.25 PM.png&quot; data-origin-width=&quot;2540&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히 접할 수 있는 예시로는 map, filter, reduce가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrows로 되어있는 것을 확인할 수 있죠?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 갑자기 드는 생각이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어?? 우리가 이 고차 함수들을 사용할 때 try를 사용했던가...?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맞습니다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이런 고차 함수를 쓸 때 대부분의 경우 try를 붙여주지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 사용했죠. 그래서 사실 이 함수가 rethrows인지도 모르고 있을 확률이 높습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrows의 핵심은 파라미터로 전달되는 함수가 throws 함수이지만 사용할 때 파라미터로 전달된 함수가 throws함수가 아닐 수 있다는 점에 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws 함수를 파라미터로 받으니까 받는 함수가 반드시 throws일거라고 생각하면 안 됩니다. 그냥 일반 함수가 전달돼도 괜찮습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 map, filter를 사용할 때 throws 클로저를 사용한 게 아니였잖아요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://gist.github.com/Beepeach/b6365ae2488643102fbbe46bd5bdff48.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;throws 함수는 호출할 때 파라미터로 전달되는 함수가 throws이던 아니던 무조건 try를 적어줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 rethrows 함수는 호출할 때 파라미터로 전달되는 함수가 throws가 아니라면 try를 적어주지 않아도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rethrows함수는 throw함수와 달리 직접 에러를 throw 하는 게 아니기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시에서도 rethrowsFunction(callback:)을 호출하는데 파라미터로 그냥 함수를 전달할 때 try를 사용하지 않는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 rethrows와 throws의 차이를 공부해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파라미터로 throws함수를 받으면 rethrows, throws 키워드를 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;rethrows를 사용하면 throw 키워드를 바로 사용할 수 없다.&lt;/li&gt;
&lt;li&gt;rethrows에서 throw 키워드를 사용하고 싶다면 파라미터로 받은 함수를 do-catch로 처리할 때 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;throws는 사용 시에 반드시 try를 사용해야 하지만 rethrows는 파라미터로 받은 함수가 throws가 아니라면 try를 사용하지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=15479573&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=15479573&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1648351837904&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;스위프트 프로그래밍&quot; data-og-description=&quot;문법을 넘어 프로그래밍 패러다임도 익히는 스위프트 5스위프트 5의 핵심 키워드는 &amp;lsquo;안정화&amp;rsquo;다. ABI 안정화 덕분에 버전과 환경에 크게 영향받지 않고 더 유연하게 스위프트를 사용할 수 있게 &quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=15479573&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.naver?bid=15479573&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nZ7fL/hyNPMMmxdJ/sz7gajdsEmwXwFyn4wmlxk/img.jpg?width=140&amp;amp;height=179&amp;amp;face=0_0_140_179&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=15479573&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=15479573&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nZ7fL/hyNPMMmxdJ/sz7gajdsEmwXwFyn4wmlxk/img.jpg?width=140&amp;amp;height=179&amp;amp;face=0_0_140_179');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;스위프트 프로그래밍&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;문법을 넘어 프로그래밍 패러다임도 익히는 스위프트 5스위프트 5의 핵심 키워드는 &amp;lsquo;안정화&amp;rsquo;다. ABI 안정화 덕분에 버전과 환경에 크게 영향받지 않고 더 유연하게 스위프트를 사용할 수 있게&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648351815365&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Declarations &amp;mdash; The Swift Programming Language (Swift 5.6)&quot; data-og-description=&quot;Declarations A declaration introduces a new name or construct into your program. For example, you use declarations to introduce functions and methods, to introduce variables and constants, and to define enumeration, structure, class, and protocol types. Yo&quot; data-og-host=&quot;docs.swift.org&quot; data-og-source-url=&quot;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&quot; data-og-url=&quot;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.swift.org/swift-book/ReferenceManual/Declarations.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Declarations &amp;mdash; The Swift Programming Language (Swift 5.6)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Declarations A declaration introduces a new name or construct into your program. For example, you use declarations to introduce functions and methods, to introduce variables and constants, and to define enumeration, structure, class, and protocol types. Yo&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.swift.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648351806007&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What are the differences between throws and rethrows in Swift?&quot; data-og-description=&quot;After searching for some references to figure it out, -unfortunately- I could not find useful -and simple- description about understanding the differences between throws and rethrows. It is kind of&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&quot; data-og-url=&quot;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cfpMSr/hyNPP3oxNj/YtxqxUat5rIe8CIW3GBsM1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/43305051/what-are-the-differences-between-throws-and-rethrows-in-swift&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cfpMSr/hyNPP3oxNj/YtxqxUat5rIe8CIW3GBsM1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What are the differences between throws and rethrows in Swift?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;After searching for some references to figure it out, -unfortunately- I could not find useful -and simple- description about understanding the differences between throws and rethrows. It is kind of&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Swift</category>
      <category>Rethrows</category>
      <category>throws</category>
      <author>Beepeach</author>
      <guid isPermaLink="true">https://beepeach.tistory.com/692</guid>
      <comments>https://beepeach.tistory.com/692#entry692comment</comments>
      <pubDate>Sun, 27 Mar 2022 12:36:41 +0900</pubDate>
    </item>
  </channel>
</rss>