<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>charlie_dev.log</title>
        <link>https://velog.io/</link>
        <description>찬찬히 써내려가는 개발일지</description>
        <lastBuildDate>Sat, 11 Apr 2026 12:28:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>charlie_dev.log</title>
            <url>https://velog.velcdn.com/images/woong_crouch/profile/a61a229a-4aad-4f73-b9e9-4d4c20c9836d/image.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. charlie_dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/woong_crouch" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SW 공학 및 테스팅 (8) - Embedded SW & Dependable SW]]></title>
            <link>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%85-8-Embedded-SW-Dependable-SW</link>
            <guid>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%85-8-Embedded-SW-Dependable-SW</guid>
            <pubDate>Sat, 11 Apr 2026 12:28:27 GMT</pubDate>
            <description><![CDATA[<h2 id="embedded-software">Embedded Software</h2>
<p>대규모 데이터의 분류와 저장, 검색에 초점을 맞추는 일반적인 정보 시스템과 달리, 임베디드 시스템은 <strong>더 큰 시스템 내부에 논리적으로 통합된 부품으로서 연산 자체가 주 목적이 아닌 시스템</strong>을 말한다.</p>
<p><strong>대규모이며 수명이 길고, 실시간 응답</strong>과 <strong>고장시 안전을 보장하는 신뢰성</strong>이 필수적이다. 또한 <strong>비동기적</strong>이고 <strong>병렬적인 특성</strong>을 가지며 <strong>분산된 환경에서도 동작</strong>하는 경향이 있다.</p>
<h3 id="응답-속도에-따른-분류">응답 속도에 따른 분류</h3>
<p>응답 속도에 따라 <strong>일괄 처리(batch), 대화형(interactive on-line), 실시간 시스템(real-time)</strong>으로 분류할 수 있다.</p>
<p>이 때 batch 시스템은 결과가 언제 오는지는 상관하지 않는다. 실시간 시스템(real time)은 time-deadline이 존재하는 시스템을 말한다.</p>
<h3 id="실시간-시스템의-임계성">실시간 시스템의 임계성</h3>
<p>데드라인의 엄격성으로 Hard와 Soft로 구분이 가능하고 실행 속도에 따라 Fast와 Slow로 구분할 수 있다. 
<img src="https://velog.velcdn.com/images/woong_crouch/post/ece7966e-0cd0-4c17-9dcc-c6d64ef17a1d/image.png" alt=""></p>
<h3 id="임베디드-시스템-특징">임베디드 시스템 특징</h3>
<p>임베디드 시스템을 설계할 때, 3가지의 특성을 중심으로 고려해야하는데 <strong>환경, 성능, 고장 모드</strong> 이렇게 3가지로 이뤄진다. 이 3가지 모두를 고려할 수 있어야 한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/cf4228b7-f644-4062-a42b-4e0e53bd9ef6/image.png" alt=""></p>
<h4 id="1-environmental-aspects">1. Environmental Aspects</h4>
<p>임베디드는 일반적으로 PC와 달리 <strong>물리,전기적으로 가혹한 환경에 노출되는 경우가 많아 이를 견딜 수 있어야한다.</strong> 그래서 온도, 전기적 간섭이 강한 공간, 장기 유지보수의 설계까지 반영되어야한다.</p>
<h4 id="2-performance-aspect">2. Performance Aspect</h4>
<p>임베디드 시스템의 설계자는 시스템이 <strong>환경과 상호작용하며 내야하는 성능을 예측해야한다.</strong> 정해진 주기에 따라 지속적으로 백그라운드에서 수행되어야하고, 외부의 무작위 이벤트를 즉각 반응해서 처리해야한다.</p>
<h4 id="3-failure-and-their-effects">3. Failure and their effects</h4>
<p>시스템의 하드웨어나 소프트웨어는 수명 주기 내에 어떤 이유로든 반드시 <strong>고장이 발생할 수밖에 없다는 것을 전제</strong>로 한다. 따라서 예외 처리 매커니즘을 필수적으로 포함해야한다.</p>
<h2 id="dependable-software">Dependable Software</h2>
<h3 id="3가지-품질-속성">3가지 품질 속성</h3>
<p><strong>신뢰성있는 소프트웨어(Dependable SW)</strong>는 단순히 결함이 없는 상태를 넘어 3가지 핵심 품질 속성을 충족해야한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/83ae44f3-7d06-46c2-95dc-552c993bf1fb/image.png" alt=""></p>
<ul>
<li><p><strong>정확성(Correctness)</strong>
프로그램이 <strong>요구사항 명세서와 일치하는지 나타내는 정적(static)인 속성</strong>이다. 오류가 발생하면 부정확한 결과를 보내는 것보다 아무 결과를 내보내지 않고 시스템을 멈추는 것이 낫다는 것을 의미한다.</p>
</li>
<li><p><strong>신뢰성(Reliability)</strong>
프로그램이 요구되는 정밀도에 맞춰 <strong>의도된 기능을 실제로 얼마나 잘 수행하는지 나타내는 동적(dynamic)인 속성</strong>이다. 런타임 중에 고장이 발생하는 빈도를 최소화해서 서비스가 중단 없이 유지되도록 하는 것이 중요하다는 것이다.</p>
</li>
<li><p><strong>안전성(Safety)</strong>
시스템이 정상적이거나 <strong>비정상적인 상황에서 작동하더라도 인명 피해나 재산상의 손상을 초래하는 위험없이 작동할 수 있는 능력</strong>이다. 고장이 나더라도 그것이 치명적인 사고로 이어지지 않도록 방어하는 것이다.</p>
</li>
</ul>
<h3 id="고장-발생-시-시스템-동작-전략">고장 발생 시 시스템 동작 전략</h3>
<p>완벽한 소프트웨어는 없으므로 고장이 발생하면 시스템이 어떻게 반응하고 대처할 것인지를 4가지 전략에 따라 동작한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/3b1baaf6-7dd6-4cb0-8c14-7f6f2e5c0036/image.png" alt=""></p>
<ul>
<li><strong>Fail-operational (운영 유지)</strong>: 고장이 발생한 상황에서도 <strong>전체 서비스를 온전히 유지하며 작동</strong>하는 방식이다.</li>
<li><strong>Fail-soft (성능 저하 운영)</strong>: 고장이 존재할 때 시스템의 <strong>성능이나 서비스 수준은 어느 정도 저하되더라도, 동작 자체는 계속해서 유지</strong>하는 방식이다.</li>
<li><strong>Fail-hard (즉시 중단)</strong>: 고장이 발생하면 <strong>전체 시스템을 즉시 완전히 멈추게(Halt)</strong> 하는 방식이다.</li>
<li><strong>Fail-safe (안전 중심 중단)</strong>: 정상적인 시스템 운영을 복구하려고 노력하는 대신, 고장으로 인해 발생할 수 있는 <strong>위험이나 피해를 제한하고 최소화하는 데 목적</strong>을 두는 방식이다.</li>
</ul>
<h2 id="software-error">Software Error</h2>
<h3 id="소프트웨어-오류의-3가지-범주">소프트웨어 오류의 3가지 범주</h3>
<p>소프트웨어 오류란 오작동을 일으키는 프로그램의 요소들을 총괄한 내용인데, 크게 3가지 범주로 나눌 수 있다.</p>
<p><strong>시스템 설계 오류</strong>
설계자가 시스템이 작동할 물리적 환경이나 동작 시간에 대해 잘못된 가정을 내렸을 때 발생하는 치명적 오류이다.</p>
<p><strong>설계 및 코딩 오류</strong>
개념을 실제 컴퓨터 코드로 번역하는 과정에서 발생한다. 우리가 흔히 생각하는 개발 중에 일어나는 오류들이 거의 대부분 여기에 포함된다. 소프트웨어가 고객의 의도나 의미를 잘못 이해한 <strong>의미론적 오류</strong>, 우발적 무한루프, 데드락 등의 <strong>논리적 오류</strong>, 0으로 나누기나 오버플로우 등의 <strong>알고리즘적 오류</strong> 등으로 구성된다.</p>
<p><strong>환경적 요인</strong>
소프트웨어가 정상적인 환경에서 작동할 때 발생하는 하드웨어의 오작동, 사람의 실수, 예상치 못한 외부 간섭 등 <strong>예측 불가능한 오류</strong>이다. 이는 설계 단계에서 완벽하게 제거할 수 없기에 심층 분석으로 문제 발생 가능성을 최소화 해야한다.</p>
<h2 id="좋은-소프트웨어-설계를-위한-원칙">좋은 소프트웨어 설계를 위한 원칙</h2>
<p>나쁜 소프트웨어가 만들어지는 원인은 경영진 또는 상관에게 문제가 있거나 설계가 부족한 상황, 전문성 결여, 문서화 부족, 프로토타이핑 부재 등의 여러 문제들을 꼽을 수 있다.</p>
<p>그럼 반면 좋은 소프트웨어 개발의 기본은 무엇일까 <strong>1) 우선 명확한 요구사항이 정의</strong>되어야 한다. 사용자가 무엇을 원하는지 잘 파악하는것이 중요하다는 것이다. 그리고 <strong>2)설계를 할 때 목표 달성이 가능한 수준</strong>이어야하고, <strong>3)관리에 있어서 유연한 프로젝트 조직으로 구성</strong>이 되어야한다. 마지막으로 <strong>4)테스트가 쉽게 이뤄지도록 설계와 검증된 방법을 사용</strong>하는 것이 필요하다.</p>
<p>이식성과 재사용성 또한 좋은 소프트웨어 하면 빠질 수 없는데, 검증된 컴포넌트를 사용해서 작업을 하면 설계, 코딩, 디버깅 시간 및 비용이 감소하고 신뢰성을 높일 수 있다. 이식성과 재사용성을 고려하면 소프트웨어가 더욱 효율적으로 구성될 수 있다.</p>
<h2 id="defensive-programming">Defensive Programming</h2>
<h3 id="오류-회피와-방어적-프로그래밍">오류 회피와 방어적 프로그래밍</h3>
<p>우리는 기본적으로 오류에 대해 회피를 해야한다. 오류를 회피한다는게 무슨말이냐, _오류 회피는 기본적으로 잘못된 값이 들어오거나 잘못된 접속이 발생했을 때 큰 문제가 발생하지 않으면 가능한 회피_하는 방향으로 움직이는 것이다. 이러한 오류 회피를 실질적인 프로그래밍에 접목하면 <strong>&quot;방어적 프로그래밍&quot;</strong>이 된다. </p>
<p>방어적 프로그래밍은 예상치 못한 입력에도 소프트웨어가 계속 수행을 보장할 수 있도록 한 프로그래밍 기법이다. 방어적 프로그래밍은 목표가 존재하는데 <strong>오류가 발생했을 때, 도입 자체를 방지하고, 발생 시 감지는 필수적이며 마지막으로 시스템의 반응을 제어</strong>한다.</p>
<p>방어적 프로그래밍이 모토로 이끄는 문장이 있는데 <strong>&quot;Garbage in, nothing out&quot;</strong>이라고 하며, 좋은 프로그램은 잘못된 값이 들어오면 이를 아무것도 내보내지 않는 방식으로 방어해야한다.</p>
<h3 id="단언문assertion의-활용과-가이드-라인">단언문(Assertion)의 활용과 가이드 라인</h3>
<p><strong>단언문</strong>이란 개발 중에 프로그램이 예상대로 작동하는지 <strong>스스로 확인하도록 하는 코드</strong>이다. 복잡한 프로그램에서 잘못된 인터페이스나 코드 수정시에 발생한 오류를 빠르게 찾아내는 데에 유용하다. 주로 절대 발생하면 안되는 조건에만 사용한다.</p>
<p>그리고 <strong>Assertion 내에는 실행코드를 넣으면 안된다.</strong> 만약 넣게되면 그 코드가 배포 등을 했을 경우 무시될 가능성이 존재하기 때문이다. 그리고 마지막으로 사전 조건과 사후 조건을 문서화하고 검증할 때도 사용한다.</p>
<h2 id="exception-handling">Exception Handling</h2>
<h3 id="오류처리-기법">오류처리 기법</h3>
<p>오류를 처리하는 기법은 여러가지가 있는데 아래에 간결하게 정리해보면 다음과 같다.</p>
<ul>
<li><strong>중립적인 값 반환</strong> : 안전한 값을 반환하는 방식이다.</li>
<li><strong>다음의 유효한 데이터로 대체</strong> : 손상된 기록을 건너뛰고 다음 값을 넣는다.</li>
<li><strong>이전과 동일한 응답 반환</strong> : 이전에 출력한 값을 이어서 출력하는 형태이다.</li>
<li><strong>가장 가까운 합법적 값으로 대체</strong> : 최대/최소 허용치로 값을 조정한다.</li>
<li><strong>파일에 경고 메세지 기록</strong> : 메세지만 남기고 계속 수행한다.</li>
<li><strong>에러 코드 반환</strong> : 예외 처리를 통해서 오류의 발생을 알린다.</li>
<li><strong>에러 처리 루틴/객체 호출</strong> : 중앙 집중식이며 코드를 재사용할 때 종속성을 계속 호출해야한다.</li>
<li><strong>에러 발생 위치에 바로 메세지 표시</strong> : 흔히 단순히 생각하는 출력구문을 이용하는 것이다.</li>
<li><strong>가장 적합한 최소한의 방법으로 처리</strong> : 유연성은 높지만 시스템 전체의 정확성/강건성은 못 맞출 수 있다.</li>
<li><strong>시스템 종료</strong> : 안전 필수 애플리케이션에서 유용하다.</li>
</ul>
<h3 id="딜레마--강건성robustness-vs-정확성">딜레마 : 강건성(Robustness) vs 정확성</h3>
<p>강건성과 정확성이 있다. 여기서 _<strong>강건성</strong>_이란, 소프트웨어가 중단되지 않고 어떻게든 작동하도록 하는 것을 말한다. 설령 <strong>기능적으로 성능이 저하되더라도 실행시키는 것</strong>에 의미를 둔다. 반대로 _<strong>정확성</strong>_이란 소프트웨어가 고장이나 에러가 발생하면 심각한 문제를 초래할 가능성이 높기에 <strong>부정확한 결과보다 아예 결과 자체를 반환하지 않는 것</strong>을 말한다.</p>
<p>소프트웨어는 그 종류에 따라서 강건성을 더 중요시할수도, 정확성을 중요시할수도 있다. 만약 에어백이나 방사선 치료기와 같이 조금의 문제도 발생해서는 안되는 기기에는 정확성을 요할 것이고, 그냥 우리가 자주 쓰는 유튜브나 서비스 프로그램들은 강건성에 힘을 더 주어서 중단되지 않고 이어가는 것을 중요시해야한다.</p>
<h3 id="프로그래밍-언어-수준의-예외처리">프로그래밍 언어 수준의 예외처리</h3>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/804b96cd-ccbd-48f5-99d7-8beeaa0dd100/image.png" alt="">
<code>Exception</code>은 코드가 스스로 처리하지 못하는 <strong>예기치 않은 예외 이벤트를 마주쳤을 때, 이를 자신을 호출한 코드쪽으로 전달하는 특정 매커니즘</strong>이다. 언어에 따라서 예외처리를 하는 표현의 방식은 다르다는 점을 유의해서 접근해야한다.</p>
<br>
<br>

<p>이렇게 <strong>임베디드 시스템</strong>와 관련된 내용을 알아보았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Software Engineering & Testing (7) - Design Patterns & Behavioral Model]]></title>
            <link>https://velog.io/@woong_crouch/Software-Engineering-Testing-7-Design-Patterns-Behavioral-Model</link>
            <guid>https://velog.io/@woong_crouch/Software-Engineering-Testing-7-Design-Patterns-Behavioral-Model</guid>
            <pubDate>Wed, 08 Apr 2026 02:57:09 GMT</pubDate>
            <description><![CDATA[<h2 id="introduction">Introduction</h2>
<p>디자인 패턴은 대규모 시스템 설계에서 특히 중요한 지점을 가진다.</p>
<p>공통의 설계 어휘를 통해서 <strong>1) 개발자들간의 의사소통을 명확</strong>하게 가져갈 수 있고, <strong>2) 설계 복잡성이 감소</strong>하고 재사용성을 촉진한다. 또한 <strong>3) 시행착오를 방지</strong>하고 <strong>4) 유지보수성을 향상</strong>시키는 장점을 가진다.</p>
<p>패턴의 목적에 따라서 <strong>생성, 구조, 행위 패턴</strong>으로 구분해서 분류한다.</p>
<h2 id="인터페이스-관점의-상속">인터페이스 관점의 상속</h2>
<h3 id="상속을-통한-내부-은폐">상속을 통한 내부 은폐</h3>
<p>인터페이스 관점에서 <strong>상속은 내부 은폐의 도구로 사용</strong>되기도 한다. 클라이언트에게 Parent 클래스만 보이게 하여 내부의 복잡한 상황들을 숨긴다. 
<img src="https://velog.velcdn.com/images/woong_crouch/post/4658772a-b27a-4ac9-a31a-0c971565a323/image.png" alt=""></p>
<p>Parent로 Child를 Abstract했다고도 볼 수 있다. 주로 서브 시스템 간의 커뮤니케이션에서 잘 사용된다.</p>
<h3 id="재귀적-구조-정의">재귀적 구조 정의</h3>
<p>재귀적인 구조관계를 상속으로 정의할 수 있는데 디렉토리는 파일이기도 하지만 파일을 포함하고 또 다른 디렉토리도 포함한다. </p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/be0ef310-4fe9-4f87-8a23-ba5f09643d08/image.png" alt=""></p>
<p>이걸 단순하게 이야기해서 결론만 도출하면 <strong>클라이언트에게 모두 File 클래스로만 인지</strong>되며 <strong>내부의 복잡한 재귀적인 정의들은 숨겨버린다.</strong></p>
<h2 id="생성-패턴-creational-design-patterns">생성 패턴 (Creational Design Patterns)</h2>
<h3 id="singleton">Singleton</h3>
<p>하나의 애플리케이션 내에서 특정 클래스의 <strong>인스턴스를 오직 하나만 생성해 보장</strong>하고, 어디서든 그인스턴스에 접근할 수 있도록 하는 생성 디자인이다.</p>
<p>시스템 전체를 포괄적으로 관리해야 하는 객체는 <strong>무분별하게 여러 개의 객체가 만들어지는 것을 통제</strong>해야할 때 사용된다. 구현 원리는 아래와 같다.</p>
<h4 id="생성자-은닉">생성자 은닉</h4>
<p>클라이언트가 <code>new</code> 키워드를 이용해 함부로 인스턴스를 만들지 못하도록 <strong>생성자를 <code>protected</code>나 <code>private</code>로 숨긴다.</strong></p>
<h4 id="static-변수와-메서드-활용">Static 변수와 메서드 활용</h4>
<p>클래스 내부에 유일한 인스턴스를 저장할 <code>static</code> 포인터를 둔다. <strong>외부에서는 <code>instance()</code>라는 <code>static</code> 메서드만으로 객체에 접근</strong>한다</p>
<h4 id="지연-생성">지연 생성</h4>
<p><code>instance()</code> 메서드가 호출되면, <strong>인스턴스가 없는 경우(NULL), 최초로 하나 생성하고, 이미 생성된 경우 기존의 것을 그대로 반환</strong>한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/1540a96c-0904-458f-8c7f-fea3115cdbfa/image.png" alt=""></p>
<h3 id="prototype">Prototype</h3>
<p>생성할 객체의 종류를 명시하는 Prototypee 객체를 만들어두고 새로운 객체가 필요할 때, 구체적인 생성자(<code>new</code>)를 부르는 대신 이 객체를 Clone하여 새로운 객체를 만든다.</p>
<h4 id="clone-메서드-활용">Clone() 메서드 활용</h4>
<p>미리 만들어둔 원형의 객체(Prototype)에 자신을 복제하는 <code>Clone()</code> 메서드를 정의해둔다.</p>
<h4 id="클라이언트-추상화">클라이언트 추상화</h4>
<p>상위 인터페이스(prototype)에 <code>Clone()</code>을 호출하기만 하면 실제 할당된 객체가 무엇이든 알아서 새 객체가 만들어진다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/c1687351-1123-49ca-8233-d69379c9e2fb/image.png" alt=""></p>
<h2 id="구조-패턴-structural-design-patterns">구조 패턴 (Structural Design Patterns)</h2>
<h3 id="facade">Facade</h3>
<p>내부와 외부 시스템은 강한 연결을 하지 않는다. 내/외부의 시스템을 연결할 때, facade interface를 만들어 이를 통해서만 소통하게 한다.약한 연결로 소통하는 방식으로 이어간다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/4d1cccca-8cbf-41f0-9a82-7ed4a6b08215/image.png" alt=""></p>
<p>클라이언트가 서브 시스템의 내부를 알 필요 없이 퍼사드(창구)하고만 통신하므로서 의존성을 최소화하고 로직이 변해도 클라이언트에게 영향이 덜해 유지보수도 쉽다.</p>
<h3 id="adapter">Adapter</h3>
<p>우리가 생각하는 그 어댑터가 맞다. 각기 따로 개발된 클래스나 외부 라이브러리를 수정없이 기존 시스템에 통합할 수 있다. 호환성을 보장해주기 위해 존재하며 클라이언트가 원하는 target 인터페이스로 변환해주는 패턴이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/f9f510b1-8864-4b1c-acad-af093a5b6fdf/image.png" alt=""></p>
<h3 id="composite">Composite</h3>
<p>부분-전체 관계를 나타내기 위해 객체들을 트리로 구성하는 패턴으로, 클라이언트가 단일 객체와 이들이 묶인 복합 객체를 동일한 방식으로 취급한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/d567f126-8d44-43af-9918-0491e7417835/image.png" alt=""></p>
<h2 id="행위-패턴-behavioral-design-patterns">행위 패턴 (Behavioral Design Patterns)</h2>
<h3 id="template-method">Template Method</h3>
<p>여러 클래스에서 <strong>공통으로 사용되는 메서드를 템플릿화하여 상위 클래스에서 정의</strong>하고 <strong>하위 클래스마다 세부 동작 사항을 다르게 구현</strong>하는 것이다. 
<img src="https://velog.velcdn.com/images/woong_crouch/post/c9468b72-8169-4d62-8e2c-f85ad3a22c20/image.png" alt=""></p>
<p><strong>변하지 않는 기능들만 상위 클래스</strong>에 두고 <strong>자주 변하는 기능들을 하위 클래스에 둠</strong>으로서 하위 클래스를 수정해서 업로드하면 상위 클래스에 잘 적용되는 것을 목적으로 한다.</p>
<h3 id="observer-pattern">Observer Pattern</h3>
<p>옵저버 패턴은 <strong>옵저버들이 관찰하고 있는 대상의 상태가 변하면</strong> 대상이 <strong>옵저버들에게 통지하고 옵저버들은 알림을 받고 조치</strong>하는 행동 패턴이다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/5176dfec-0170-412b-bdc8-f4872b4e0f07/image.png" alt=""></p>
<p>다른 디자인 패턴들과는 다르게 <strong>one-to-many의 의존성</strong>을 가진다. 일종의 interactive한 디자인 패턴이라고 볼 수 있다.</p>
<h2 id="행위-모델--sequence-diagram">행위 모델 : Sequence Diagram</h2>
<h3 id="syntax">Syntax</h3>
<p>철저히 클래스가 아닌 객체 단위로 그려야한다. 아래에 표기법과 관련된 내용을 그림으로 정의해둔다.</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/5d5d5946-0eb6-4730-99d8-6dfb695918bd/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/a5877b4d-f1a3-4925-b0ea-c4a5acdb2700/image.png" alt=""></th>
</tr>
</thead>
</table>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/58b9d7bb-16eb-46c5-a3cb-5e1e4d8a535c/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/6d8ad70d-f75c-43c7-ab53-75faa1fd86c5/image.png" alt=""></th>
</tr>
</thead>
</table>
<h3 id="메세지의-주요-유형">메세지의 주요 유형</h3>
<p>메세지는 객체 간 서비스를 호출하는 리퀘스트를 의미하며, 화살표의 모양에 따라 실행 방식이 다르다.</p>
<p><strong>Asynchronous message</strong>는 선으로만 된 화살표로, 상대의 처리 완료를 기다리지 않고 바로 다음 작업을 병렬로 진행한다.</p>
<p><strong>Call message</strong>는 꽉찬 화살표로, 호출한 객체는 수신한 객체의 작업이 끝나고 리턴될 때까지 기다린다.</p>
<p><strong>Reply message</strong>는 점선 화살표로 표기하며 처리가 끝나면 제어권과 결과값을 원래 객체에 돌려주는 메세지다.</p>
<p><strong>Lost message</strong>는 외부 알 수 없는 곳으로 날아가는 예외적인 이벤트의 흐름을 나타낸다</p>
<p><strong>Found message</strong>는 외부 알 수 없는 곳에서 날아오는 예외적인 이벤트의 흐름을 나타낸다</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/f2604023-fd9e-4cba-a600-c988e46173d1/image.png" alt=""></p>
<h3 id="combinded-fragments">Combinded Fragments</h3>
<p>기존의 시퀀스 다이어그램에서 if문이나 반복문을 표현하기 어려웠으나 UML 2.0부터 <strong>복합 프레그먼트</strong>를 도입하여 로직을 표현한다. </p>
<p><strong><code>alt</code>는 if-else 조건문</strong>을 나타내고, <strong><code>opt</code>는 조건이 참일 때만 실행되는 단일 if문</strong>이다. <strong><code>loop</code>는 특정 조건을 만족하는 동안 메세지 교환을 반복</strong>하며 <strong><code>par</code>은 여러 흐름이 동시에 수행</strong>됨을 의미한다. </p>
<p><strong><code>neg</code>는 절대 발생해서는 안되는 시나리오</strong>를 나타내고, <strong><code>assert</code>는 반드시 발생해야하는 올바른 흐름</strong>을 나타낸다. 마지막으로 <strong><code>critical</code>은 임계 영역(병렬 상황에서 한번에 실행을 보장)</strong>을 나타낸다.</p>
<p>추가로 <strong><code>ref</code></strong>도 존재하는데, <strong>외부의 시퀀스 다이어그램을 참조하기 위해 가져다 쓰는 것</strong>을 의미한다.</p>
<h3 id="pitfalls-in-sequence-diagram">Pitfalls in Sequence Diagram</h3>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/d6edc894-3355-427b-af8d-710db0540897/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/fe010a58-e5a7-46a7-8758-4265e2afa5cd/image.png" alt=""></th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/woong_crouch/post/3071eac4-e246-404f-92a3-35100fb2c553/image.png" alt=""></td>
<td><img src="https://velog.velcdn.com/images/woong_crouch/post/50f24090-2dfd-432c-9a5d-13fa131e001d/image.png" alt=""></td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[SW Engineering & Testing (6) - Structural Modeling]]></title>
            <link>https://velog.io/@woong_crouch/SW-Engineering-Testing-5</link>
            <guid>https://velog.io/@woong_crouch/SW-Engineering-Testing-5</guid>
            <pubDate>Mon, 06 Apr 2026 13:11:18 GMT</pubDate>
            <description><![CDATA[<h1 id="structural-models">Structural Models</h1>
<p>구조적 모델은 &quot;무엇이 상호작용하는가&quot;에 초점을 맞춰서 시스템의 정적인 구조와 뼈대를 모델링하는 것이 주의 핵심이다. </p>
<h3 id="구조적-모델의-목적">구조적 모델의 목적</h3>
<p>객체는 <strong>Application Domain에서 핵심이 되는 사물, 아이디어, 개념 등을 나타내는 것</strong>이다. 클래스 다이어그램, 오브젝트 다이어그램을 작성하기 위한 규칙이나 스타일 지침 그리고 구조 모델간의 관계를 이해하는 것을 목적으로 한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/4803eb16-90f8-46b1-b266-6c24f72b9118/image.png" alt="">
Structural 모델의 가장 주요한 목표는 <strong>문제 영역에 포함된 핵심 데이터를 발견하고 객체의 구조적 모델을 구축</strong>하는 것이다. </p>
<h3 id="구조적-viewpoint">구조적 ViewPoint</h3>
<p><strong>ViewPoint를 표현하기 위해서 다양한 다이어그램을 제공</strong>하고, 컴포넌트 다이어그램부터 클래스 다이어그램, 객체 다이어그램 등이 대표적으로 활용된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/19d11cbd-afb8-4f21-9d35-dc680cf0cb17/image.png" alt=""></p>
<h2 id="class-diagram">Class Diagram</h2>
<p>클래스 다이어그램에서는 시스템의 정적인 구조를 구성하는 핵심 단위인 <strong><code>클래스</code>는 사각형 박스</strong>로 그려지고, 내부적으로 크게 3가지의 엘리먼트로 나누어 표현된다. </p>
<h3 id="class-name">Class Name</h3>
<p>말 그대로 <strong>클래스의 이름</strong>을 보이며, 가장 위칸에 위치하고 문제 도메인에서 식별된 해당 객체의 이름을 나타낸다.</p>
<h3 id="attributes">Attributes</h3>
<p>이름 다음에 오는 중간 칸을 이용하며, 클래스가 <strong>내부적으로 관리하고 유지하는 데이터</strong>를 의미한다. </p>
<p>표기법은 아래와 같다.
<strong>[visible] name : type-expression [=initial-value]</strong></p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/cf922c23-1717-41f0-9b87-458c7d3b0033/image.png" alt=""></p>
<h4 id="가시성visibility">가시성(Visibility)</h4>
<p>이 때, Visibility는 총 3가지로 표기할 수 있는데, 우선 <strong><code>+</code>는 public을 의미하며 외부의 누구나 접근 가능</strong>하고, <strong><code>-</code>는 반대로 private를 의미해 해당 클래스 내부에서만 접근 가능</strong>하다. 마지막으로 <strong><code>#</code>은 protected를 의미해 자식 클래스에게만 접근을 허용</strong>한다.</p>
<h4 id="정적-인스턴스">정적 인스턴스</h4>
<p>속성 밑에 밑줄이 그어서 표기하며, 클래스 차원에서 메모리에 유일하게 하나만 존재하여 공유되는 정적(Static) 변수를 의미한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/52e3a7ed-431e-44f2-bc55-b481e0bcc90b/image.png" alt=""></p>
<h3 id="operation">Operation</h3>
<p>가장 아랫쪽 칸을 차지하며, 클래스가 외부 클라이언트에게 제공하는 서비스를 정의한다. </p>
<p>표기법은 아래와 같다.
<strong>[visibility] name([parameter-list]) [: return-type]</strong></p>
<p>속성과 마찬가지로 오퍼레이션에 밑줄이 그어져 있으면 Static Method를 뜻한다.</p>
<h2 id="클래스-간의-주요-관계">클래스 간의 주요 관계</h2>
<h3 id="generalizationinheritance">Generalization(Inheritance)</h3>
<p>is-a가 성립하는 부모-자식 간의 관계를 나타낸다. 여러 클래스를 분석하다 공통적인 부분(Attribute or Operation)이 발견되면, 이를 <strong>부모 클래스로 뽑아 올려 중복을 없애고 코드를 재사용하기 위해 사용되는 관계</strong>이다. <strong>속이 빈 삼각형 화살표와 실선</strong>으로 표기한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/5d0ccea3-26e0-462b-990e-725d3a461e5e/image.png" alt=""></p>
<h3 id="aggregationcomposition">Aggregation(Composition)</h3>
<p>전체와 부분을 나타내는 part-of 관계를 가진다. 두 클래스의 결합 강도에 따라서 다음의 두 관계로 세분화할 수 있다. </p>
<h4 id="strong-aggregationcomposition">Strong Aggregation(Composition)</h4>
<p>전체와 부분의 생명주기가 동일한 매우 강한 결합의 형태이다. 전체 객체가 소멸하거나 생성될 때, <strong>부품 component도 동시에 생성되고 소멸한다.</strong> 표기법으로는 <strong>속이 찬 다이아몬드</strong>로 표현된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/8f618e5c-9049-4338-86ad-2ecd1ed8c4db/image.png" alt=""></p>
<h4 id="weak-aggregation">Weak Aggregation</h4>
<p>부품이 하나의 전체에만 전담되지 않고 <strong>여러 다른 객체에서 공유될 수 있는</strong> 결합으로 속이 <strong>빈 다이아몬드로 표기</strong>한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/da1cc4a0-b023-4ca3-80a3-0aac930c062d/image.png" alt=""></p>
<h3 id="association">Association</h3>
<p><strong>상속이나 전체-부분 관계에 속하지 않는 클래스 간의 일반적인 연결 및 사용 관계</strong>를 의미한다. <strong>선으로 연결</strong>해 표현하고, 관계를 명확히 하기 위해 <strong>방향성 화살표나 역할 이름을 덧붙일 수 있다.</strong> </p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/48afb5e0-42cd-4e4f-be29-a14d3d58e4ca/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/13ffbef8-3651-4505-8117-dfbc46cd24e1/image.png" alt=""></th>
</tr>
</thead>
</table>
<p>가장 중요한 특징은 선 끝에 다중성을 명시해 하나의 객체가 상대방 객체와 몇 개의 관계를 맺는지를 나타낸다.</p>
<h3 id="dependency">Dependency</h3>
<p>Associate보다 훨씬 약한 연결로 <strong>한 클래스의 변경이 다른 클래스에 영향을 미치는 관계</strong>이다. 특정 메서드를 실행할 때, 파라미터로 전달받거나 리턴 타입으로 일시적으로만 사용할 때 주로 형성된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/3ab5fe16-4275-410e-a238-8e85636c2307/image.png" alt="">
일반 실선이 아닌 <strong>점선 화살표로 표기</strong>하여 적용한다.</p>
<h2 id="인터페이스와-스테레오-타입">인터페이스와 스테레오 타입</h2>
<h3 id="인터페이스interface">인터페이스(interface)</h3>
<p>실제 동작하는 <strong>구현 부분 없이 외부에 제공할 Operation의 시그니처만 모아둔 집합</strong>이다.
<code>&lt;&lt;interface&gt;&gt;</code>
<img src="https://velog.velcdn.com/images/woong_crouch/post/46856203-550b-4045-9355-8e55b80a4b45/image.png" alt="">
클래스들이 직접 통신하면 서로 떼어낼 수 없는 Strong Coupling이 발생한다. 인터페이스를 둠으로서 결합의 강도가 줄어들어 Weak Coupling을 유도할 수 있다.</p>
<h3 id="스테레오-타입stereotype">스테레오 타입(Stereotype)</h3>
<p>기존에 존재하는 UML의 기본 구성 요소를 확장해 <strong>새로운 의미나 종류의 모델 요소를 만들어내는 표기</strong>법이다.</p>
<p>아래와 같은 표기법으로 나타낸다.
<code>&lt;&lt;&gt;&gt;</code>
다이어그램을 보는 사람이 해당 요소의 용도와 성격을 명확히 이해할 수 있도록 돕는 역할을 한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/a571f33e-b97e-4bf4-b7b1-f79a061e69f0/image.png" alt=""></p>
<h3 id="클래스-다이어그램-vs-객체-다이어그램">클래스 다이어그램 vs 객체 다이어그램</h3>
<p>같은 내용을 정리해도 다이어그램의 종류에 따라서 서로 다른 형태를 띈다. 아래와 같이 클래스 다이어그램과 객체 다이어그램은 서로 다른 모습을 보인다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/9d343c46-918d-4688-ad3b-b865d80bcf83/image.png" alt=""></p>
<h2 id="객체-식별-및-모델링-프로세스">객체 식별 및 모델링 프로세스</h2>
<h3 id="object-identification">Object Identification</h3>
<p>문제 도메인에 있는 어떤 아이디어나 개념을 소프트웨어 내의 클래스로 뽑아낼 것인가&quot;를 결정하는 단계이다. 총 3가지의 기법으로 클래스 후보군을 추린다.</p>
<h4 id="텍스트-분석">텍스트 분석</h4>
<p>기계적으로 분석하는 방법으로, 문장에서 명사는 클래스나 속성의 후보로, 동사는 오퍼레이션 후보로 추출한다.</p>
<h4 id="브레인-스토밍">브레인 스토밍</h4>
<p>팀원들이 한자리에 앉아 시스템에 필요할 듯한 클래스나 속성 등을 토론하며 식별하는 방식이다.</p>
<h4 id="common-object-list">Common object list</h4>
<p>비즈니스 도메인에서 보편적으로 클래스로 추출되는 대표적 유형리스트를 참고해 누락된 객체를 찾아내는 방법이다.</p>
<p>역할, 물리적 사물, 사건, 상호작용을 중심으로 알아보게 된다.</p>
<h3 id="crc-카드">CRC 카드</h3>
<p>CRC 카드는 <strong>다이어그램을 그리기 전, 설계의 결함을 조기에 찾아내고자 작성</strong>된다. 주로 Object Identification을 수행하고 작성된다.</p>
<p>Use Case 기반으로 분석을 통해서 초안을 작성하고 브레인 스토밍을 통해 토의한 이후 <strong>롤플레잉을 통해서 검증</strong>한다. 그리고 이에 대한 결함을 보완하면서 CRC 카드를 기반으로 클래스 다이어그램을 그린다.</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/8eb1b99e-3911-43c2-8053-0e3e4fc1f432/image.png" alt=""> CRC카드 앞</th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/d48918ff-980e-4740-834d-ffbd7216aa78/image.png" alt=""> CRC 카드 뒤</th>
</tr>
</thead>
</table>
<h3 id="클래스-유형">클래스 유형</h3>
<p>Unified Process는 3가지로 클래스를 유형을 나눠 분류한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/d124fecc-094c-4f36-a815-a5c108d563f8/image.png" alt=""></p>
<p>이 전체는 <strong>stereotype</strong>이며, UML을 정의하면 시스템을 정확히 모델링하는 데 필요한 추가 구성요소를 정의할 수 있다.</p>
<h4 id="entity-class">Entity Class</h4>
<p><strong>영구적으로 DB에 저장되고 유지되어야 하는 데이터 정보들을 기록</strong>한다. 예를 들어 계좌나, 학생, 강좌 등 프로젝트에서 중심을 가지는 데이터들 다루는 Class를 말한다.</p>
<h4 id="boundary-class">Boundary Class</h4>
<p><strong>시스템과 외부 Actor 간의 상호 작용 및 입출력을 담당</strong>한다. 위의 설명처럼 주로 input과 output과 연관된 작동을 주로 이 클래스에 분류한다.</p>
<h4 id="control-class">Control Class</h4>
<p><strong>복잡한 비즈니스 로직을 연산하거나 알고리즘을 제어하는 것</strong>을 주로 담당하는 클래스로 무언가 계산을 해야하는 로직의 경우 이 클래스로 분류된다. </p>
<h1 id="case-study">Case Study</h1>
<p>Osbert Oglesby 미술품 시스템을 중심으로 앞서 정리한 내용들을 돌아보는 과정을 거친다.</p>
<h2 id="1-system-request--use-case">1. System Request &amp; Use Case</h2>
<p>Osbert가 그림을 구매할 때 최대 지불 가능 가격을 산정하고, 미술 시장의 새로운 트렌드를 파악해 세금 계산 등을 위해 <strong>모든 판매/구매 기록을 유지하고 보고서를 출력</strong>하는 시스템을 개발하고자 한다. </p>
<p>이때, Use Case는 아래와같이 4개의 주요 Use Case로 구성된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/e640116e-6a3f-425a-9474-3fba38a85e24/image.png" alt="">
정보 시스템을 한 단락으로 묘사해보면, <strong>&quot;예술 작품 구매 의사 결정 과정의 효과를 향상시키기 위해 보고서를 생성할 것이다. 보고서에는 걸작, 명작 및 기타 그림으로 분류되는 그림에 대한 매매 정보가 포함되어있다.&quot;</strong>로 표현할 수 있다.</p>
<h2 id="2-엔티티-식별-및-구조-고도화">2. 엔티티 식별 및 구조 고도화</h2>
<p>엔티티를 명사를 추출함으로서 식별하고, 구조를 개선하여 클래스 다이어그램을 명확하게 만들어낸다.</p>
<h3 id="명사-추출">명사 추출</h3>
<p>1) 위의 단락에서 명사만을 표기한다.
<strong>&quot;<U>예술 작품</U> <U>구매</U> 의사 결정 <U>과정</U>의 <U>효과</U>를 향상시키기 위해 <U>보고서</U>를 생성할 것이다. <U>보고서</U>에는 <U>걸작</U>, <U>명작</U> 및 <U>기타 그림</U>으로 분류되는 <U>그림</U>에 대한 <U>매매</U> <U>정보</U>가 포함되어있다.&quot;</strong></p>
<p>2) 추출 결과물을 보면 아래와 같다. 
<strong>{ 예술 작품, 구매, 과정, 효과, 보고서, 걸작, 명작, 기타 그림, 그림, 정보 }</strong></p>
<p>3) Entity Class를 추출한다.
추상명사와 동명사 등을 제외하고, 오래 지속되지 않는 것들도 제외한 뒤, 동의어를 제거하면 아래만 남는다.
<strong>{ 걸작, 명작, 기타 그림, 그림 }</strong></p>
<p>고로 이렇게 4개가 Entity Class로 선택된다.</p>
<h3 id="1차-diagram-구조-개선">1차 Diagram 구조 개선</h3>
<p>우선 <strong>각 엔티티 클래스 후보군들을 두고, 클래스 간의 상호관계를 고려</strong>한다. 관계를 보면 그림을 기준으로 나머지 클래스들과 포함 관계를 가진다. 따라서 <strong>그림(painting) 클래스를 Base Class로, 나머지를 Sub Class</strong>로 한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/866a2185-a116-46c0-8b3c-deebfcba6662/image.png" alt=""></p>
<h3 id="2차-diagram-구조-개선">2차 Diagram 구조 개선</h3>
<p>지금까지의 클래스 다이어그램을 기준으로 Pricing Algorithm을 반영하지 않았기에 이제 이 부분을 고려해야한다.</p>
<p>걸작(masterwork)을 다룰 때, 정보 시스템은 우선 같은 화가의 명작(masterpiece)인 것처럼 최대 지불 금액을 계산한다. 고로 걸작(masterwork)은 명작(masterpiece)의 모든 attribute를 가져야한다. 또한 자신의 속성도 가져야한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/a212aed6-0a6a-43f9-a27b-e3ad56c4bb88/image.png" alt=""></p>
<h3 id="3차-diagram-구조-개선">3차 Diagram 구조 개선</h3>
<p>위의 클래스에서 고려하지 못한 pricing algorithm은 경매 기록이 있는 그림과 구매를 고려중인 그림 사이의 유사도 계수를 계산한다는 것이다. </p>
<p>그렇게 되면 경매 기록이 있는 그림 클래스가 필요하다. 이는 Painting class의subclass여야 하며, 현재 전시된 그림과는 관련성이 없어서 표현하면 아래와 같이 표현한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/16166e0b-d0c8-4605-ad02-be7823e572f9/image.png" alt=""></p>
<h3 id="4차-diagram-구조-개선">4차 Diagram 구조 개선</h3>
<p>3번째까지도 <strong>fashionability 모델링이 아직이며 F*A 공식으로 상품의 최대 지불가격을 정해야한다</strong>. (F = 작가 유명도 상수, A = 그림 크기) 또한 Fashionability Class가 필요하다. 이러한 고려사항을 적용하면 아래와 같아진다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/6007c597-14fe-4283-89eb-e2b6d4f2a0d1/image.png" alt=""></p>
<h3 id="상세-클래스-다이어그램">상세 클래스 다이어그램</h3>
<p>클래스 다이어그램에 필요한 요소를 상세히 다 넣으면 아래와 같은 그림으로 그릴 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/292512fc-bbcb-413c-9860-f5773e58b0be/image.png" alt=""></p>
<h2 id="3-바운더리-클래스-식별">3. 바운더리 클래스 식별</h2>
<p>시스템과 유저간의 <strong>입력/출력을 담당하는 UI 요소를 도출</strong>한다. 4개의 Use Case 스크린을 포괄적으로 처리할 클래스를 둔다. 이후 보고서들의 내용은 각기 다르므로 <strong>3개의 독립적 보고서 클래스를 분리</strong>해 바운더리 클래스를 도출한다.</p>
<p><strong>Purchase Report, Sales Report, Future Trends Report, User Interface Class</strong></p>
<h2 id="4-컨트롤-클래스-식별-및-최종-완성">4. 컨트롤 클래스 식별 및 최종 완성</h2>
<p><strong>데이터를 가공하고 계산하는 복잡한 로직을 별도의 클래스</strong>로 도출한다. 가격을 계산하는 알고리즘을 처리하기 위해 클래스를 만들고 새로운 트렌드를 분석하는 Compute Future Trends 클래스를 추가해 4개의 컨트롤 클래스를 식별한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/727411df-5bd1-4c06-bd94-414babbb6498/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SW 공학 및 테스팅(5) - OOC(Object-Oriented Concepts)]]></title>
            <link>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%855</link>
            <guid>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%855</guid>
            <pubDate>Wed, 25 Mar 2026 01:21:21 GMT</pubDate>
            <description><![CDATA[<h1 id="object-oriented-concept">Object-Oriented Concept</h1>
<h2 id="class-concept">Class Concept</h2>
<p>클래스는 캡슐화 되어 구성되며, Interface와 Body로 나눠져있다.</p>
<ul>
<li><strong>Interface</strong>
Interface는 보여지는 영역으로 서비스를 제공하는 다소 추상적인 영역이다. </li>
<li><strong>Body</strong>
Body는 Interface와 달리 숨겨져있으며 object의 기능을 구현해둔 요소를 말한다.</li>
</ul>
<p>이 때, <strong>캡슐화(Encapsulation)는 interface와 body를 구분해서 불필요한 정보를 외부에 노출하지 않는 것</strong>을 말한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/b4d56a1c-fc31-4870-80d4-bfdf3ee4a0a4/image.png" alt=""></p>
<h2 id="default-constructor">Default Constructor</h2>
<p><strong>arguments를 가지지 않는 Constructor</strong>를 말한다.</p>
<p>만약에 <strong>Class가 Constructor를 가지지 않는다면 시스템은 자동적으로 Default Constructor를 제공</strong>한다. C++에서 Class의 다른 Constructor가 존재한다면 자동적으로 만들어주지 않기 때문에, Array를 재정의할 때 에러가 발생한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/52b8a02b-a834-4b8d-bb94-0b00deab8484/image.png" alt=""></p>
<p>명시적 선언이 필수적인 이유는 만약 개발자가 특정 값을 넣기 위해 파라미터가 있는 <strong>Constructor를 만들게 되면, 시스템은 더 이상 Default Constructor를 만들어주지 않는다.</strong></p>
<h2 id="inheritance-concept">Inheritance Concept</h2>
<p>상속은 클래스 간의 관계를 정의할 때, 가장 핵심이 되는 개념이다. 상속은 기존 브모 클래스의 특성을 자식 클래스가 그대로 물려받아 새로운 클래스를 만드는 매커니즘이다. </p>
<p>상속의 가장 큰 목적은 코드의 중복을 피하고 재사용성을 극대화하여 효율적인 코드 관리를 하기 위함입니다. </p>
<h3 id="클래스-중복-관리-및-재사용">클래스 중복 관리 및 재사용</h3>
<p><code>부모 클래스</code>는 Base Class, Parents, Super Class 등으로 불리고, <code>자식 클래스</code>는 Derived Class, Child, Sub class로 불린다. </p>
<p>새로운 클래스는 이미 존재하는 클래스의 모든 <strong>정보를 재사용</strong>하면서 <strong>새로운 정보를 추가하거나 이미 존재하는 정보를 수정</strong>할 수 있다.</p>
<h3 id="서브-클래스의-생성">서브 클래스의 생성</h3>
<p>서브 클래스의 객체가 생성될 때, 부모 클래스의 데이터도 함께 초기화 되어야하므로, <strong>생성자에서 부모 클래스의 초기화(super)를 호출하는 과정</strong>을 말한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/badcc01b-5be8-4c6f-a64e-8cd9c533697e/image.png" alt="">
절차에 대해서 알아보면, <strong>1) 부모와 자식 클래스 모두에 데이터를 입력</strong>한다. 그 다음 <strong>2) 생성자를 호출하여 객체를 생성해 부모/자식 클래스를 모두 초기화</strong>한다. 또한 자식 클래스의 생성자의 초기화 목록에서 부모 클래스의 생성자를 호출한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/e67c915e-2c9b-41b9-911c-68231fa01392/image.png" alt=""></p>
<h3 id="타입-변환">타입 변환</h3>
<p>상속에서 파생되는 아주 중요한 요소인 <code>Polymorphism</code>을 곧 배우게 될텐데, 그 바탕이 되는 규칙으로 <strong>부모 클래스가 요구되는 변수 자리에 자식 클래스의 객체가 대신 들어갈 수 있다는 것</strong>이다.</p>
<p>말 그대로 자식은 부모 대신 자식 클래스가 적용되는 것은 가능하지만, 부모는 자식 대신 적용될 수 없다는 것이다.</p>
<h2 id="overriding--polymorphism">Overriding &amp; Polymorphism</h2>
<h3 id="overriding">Overriding</h3>
<p>오버라이딩은 <strong>부모 클래스로부터 상속받은 메서드를 자식 클래스의 목적에 맞게 재정의하는 기법</strong>이다. 총 3가지 목적으로 오버라이딩을 진행할 수 있는데, 각각 확장, 적응, 최적화이다.</p>
<h4 id="확장extension">확장(Extension)</h4>
<p><strong>부모 클래스의 기존 행위를 그대로 유지하면서, 자식 클래스만의 추가적인 동작을 덧붙일 때 사용</strong>한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/e9150ee3-96aa-4499-9560-b07ab1878f4a/image.png" alt=""></p>
<p>부모 클래스가 가지는 메서드를 이용하면서 그 메서드에 자식 클래스의 정보를 이용해 추가적인 기능을 확장할 수 있다.</p>
<h4 id="적응adaptation">적응(Adaptation)</h4>
<p>Sub Class의 행동을 명시적으로 나타내기 위해 Super Class의 행동을 재정의한다. 다시 말하면 <strong>부모 클래스의 행위를 자식 클래스의 상황에 맞게 명시적으로 변경해 적용</strong>할 때 사용한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/971246ed-f407-438a-b83e-6a0ea39cf7f1/image.png" alt=""></p>
<h4 id="최적화optimization">최적화(Optimization)</h4>
<p><strong>특정 자식 클래스에 맞춰 퍼포먼스(계산 속도 등)를 극대화하는 알고리즘으로 대체</strong>할 때 사용한다. 성능을 위해 오버라이딩하는 역할이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/ae311346-997c-4f03-8350-54ca04a37288/image.png" alt="">
다소 추상적인 개념이라 이해가 안될 수 있지만, 예를 들어 다각형 면적을 구할 때, 삼각형은 공식이 존재할 때, 이를 overriding해서 성능을 향상시킬 수 있다.</p>
<h3 id="동적-바인딩">동적 바인딩</h3>
<p>동적 바인딩은 <strong>실행 시점에 변수에 할당된 객체를 파악해 객체에 맞는 함수를 동적으로 실행하는 매커니즘</strong>이다. 클래스에 대한 동적 바인딩이 일어나기에, 오버라이딩 된 메소드가 클래스에 맞게 자동으로 선정된다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/e968aeac-0f89-4a23-aa3e-34fa872c5ae9/image.png" alt=""></p>
<p>정적 바인딩과는 시점이 다른데, 동적 바인딩은 <code>Run Time</code> 시점이지만 정적 바인딩은 <code>Compile Time</code>에 할당된다.</p>
<h3 id="다형성polymorphism">다형성(Polymorphism)</h3>
<p>Extend, Implement 관계인 다른 클래스의 객체를 부모 클래스나 인터페이스 형식을 변수에 담을 수 있고, Overriding 된 이름이 같은 메소드가 해당 클래스에 맞게 실행되는 것이다. 즉, <strong>코드는 한 줄이지만 상황에 따라 다양한 형태로 해석되고 동작한다</strong>는 뜻이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/782e1560-842f-43bf-a2d6-f37ea0f4a944/image.png" alt=""></p>
<p>여러 종류의 자식 객체들을 각각의 타입으로 관리하지 않고, 부모 타입의 배열로 하나로 묶어 관리한다.</p>
<h2 id="abstract-class--interface">Abstract Class &amp; Interface</h2>
<h3 id="abstract-class">Abstract Class</h3>
<p>하나 이상의 추상 메서드를 가진 클래스이다. 이때 <strong>추상 메서드란 선언만 하고 구현을 안한 메서드</strong>를 말한다.</p>
<p>추상클래스가 존재하는 이유는 <strong>다형성 코드를 만들기 위해서이다.</strong> 여러 자식 클래스를 하나로 묶어 효율적으로 관리하려면 부모클래스의 배열을 만들어야 한다.</p>
<h4 id="concrete-class">Concrete Class</h4>
<p><strong>모든 동작을 구현한 클래스로 객체</strong>를 가진다. 실질적으로 Abstract와 완전히 반대되는 개념이다.</p>
<h3 id="인터페이스의-개념">인터페이스의 개념</h3>
<p>Interface는 <strong>포함된 모든 메서드가 구현부가 없는 추상 메서드로 이뤄진 극단적인 추상 클래스</strong>를 말한다. 일반적인 변수는 가지지 않는다. Interface는 항상 public, abstract이므로 별도로 public, abstract로 선언할 필요 없다.
<img src="blob:https://velog.io/c2e4eb85-526b-459d-a00a-94a34f844ee0" alt="업로드중.."></p>
<p>Java에서 <strong>다중 상속(부모가 여러명인 경우)은 금지</strong>하지만, 클래스가 하나의 부모를 상속받으며 <strong>여러 인터페이스를 동시에 다중으로 구현하는 것은 허용</strong>된다.</p>
<p>둘 이상의 인터페이스를 구현하려면 클래스 선언에서 implements 키워드 뒤에 쉼표로 구분된 인터페이스 이름 목록을 사용한다.
<img src="blob:https://velog.io/3b5bf871-b155-4b0f-a1bd-52a74e37a682" alt="업로드중.."></p>
<h3 id="인터페이스-사용">인터페이스 사용</h3>
<p>다른 클래스간 Communication 과정에서 사용되고, 오직 추상적 명령으로만 이루어지고 컴포넌트를 연결할 때 사용된다. </p>
<p><img src="blob:https://velog.io/6deaf7fc-13a7-4faa-85db-dd66212ff780" alt="업로드중.."></p>
<p><strong>Strong Coupling은 Concrete Class를 가르키는 연결</strong>을 말하고, <strong>Weak Coupling은 Abstract Class나 Interface를 가르키는 연결</strong>을 말한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SW 공학 및 테스팅 (4) - Architecture Design]]></title>
            <link>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%85</link>
            <guid>https://velog.io/@woong_crouch/SW-%EA%B3%B5%ED%95%99-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8C%85</guid>
            <pubDate>Wed, 25 Mar 2026 00:21:40 GMT</pubDate>
            <description><![CDATA[<h1 id="architectural-design">Architectural Design</h1>
<h2 id="introduction">Introduction</h2>
<p>요구사항 명세가 완벽하게 정의되었다면, 이후에는 무엇을 해야할까?</p>
<p>Use Case는 입력에 따른 반응을 기반으로 한 기술이다. 시스템의 내부는 요구사항 명세가 명확해져도 <strong>블랙박스</strong>의 형태를 가진다. 고로 개발자인 <strong>우리는 블랙박스를 화이트박스로 바꾸는 절차</strong>를 거쳐야 하고, 이를 위해 설계(architecture)를 해야한다.</p>
<h3 id="architectural-design이란">Architectural Design이란?</h3>
<p>아키텍쳐 디자인은 <strong>Software System이 어떻게 구성되는지 이해하고 그 System의 구조를 전체적으로 디자인하는 것</strong>을 말한다. 개발 요구사항과 디자인 사이에서 중요한 역할을 하며, 시스템의 <strong>주요 구조적 구성요소와 관계 사이에서 정의</strong>한다. </p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/5b1514af-5c8d-4d53-b302-99f2947ad624/image.png" alt=""></p>
<p>시스템의 세가지 핵심은 <strong>1) 기능 (요구 분석에서 결정)</strong>, <strong>2) 구조 (아키텍처 디자인, 클래스 다이어그램)</strong> , <strong>3) 행위 (시퀀스 다이어그램, State 다이어그램)</strong> 으로 정의할 수 있다.</p>
<p>설계는 <strong>Top-Down 방식</strong>으로 진행되고, 점점 세분화되게 설계한다. 컴포넌트를 구성하면서 구조가 짜이면 각 컴포넌트 간의 행위를 정의한다. 아키텍처 디자인은 <strong>디자인과 요구 엔지니어링 사이를 연결하는 &#39;링크&#39;</strong>이고, 아키텍처 디자인의 장점은 <strong>이해 당사자 사이의 소통을 쉽게</strong>해주고 <strong>큰 규모의 재사용</strong>이 가능하며, <strong>시스템 분석이 쉬워지는 장점</strong>을 가진다.</p>
<h2 id="architectural-patterns">Architectural Patterns</h2>
<p>시스템이 서로 통신하는 구성 요소들의 집합으로 어떻게 구성되는지 설명한다. 이러한 아키텍처를 명시적으로 설계함에 있어서 장점은 아래와 같다. <strong>아키텍처 패턴은 지식을 표현하고 공유하고 재사용하는 일종의 수단</strong>이다. 다양한 환경에서 시도되며 <strong>디자인 관행을 양식화해서 설명</strong>한 것으로 볼 수 있다. 주로 이런 <strong>Pattern은 표나 그래프의 형식</strong>으로 표현한다.</p>
<h3 id="mvc">MVC</h3>
<p>MVC 패턴은 Software 디자인 패턴의 일종으로 <strong>Model, View, Controller</strong>로 분리하여 유지보수성과 확장성을 높이는 방식을 말한다.</p>
<p>간단한 구조 형태로 정의된 이 패턴의 로직은 User가 Controller를 통해서 조작을 하면 Model을 통해서 데이터를 가지요고 View가 그 정보를 바탕으로 시각적인 요소로 User에게 전달한다. 간결하게 보자면 아래와 같은 구조로 형성된다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/d0af7187-85d7-43e5-b432-c608b9a002c3/image.png" alt=""></p>
<p>MVC 패턴은 시스템 데이터의 상호작용과 presentation을 분리한다. MVC의 장점은 데이터와 표현 방식 간의 독립적인 변화를 허용하고 그 반대의 경우도 가능하다는 것이다. 모델의 <strong>데이터가 변화하면 여러 뷰에 동시에 업데이트가 가능</strong>해 GUI 기반 시스템이나 웹 애플리케이션에서는 거의 표준처럼 사용된다.</p>
<h3 id="layered-architecture">Layered Architecture</h3>
<p><strong>시스템을 여러 계층으로 구성</strong>하고, <strong>하위 계층이 바로 위 상위 계층에 코어 서비스를 제공하는 구조</strong>이다. 시스템은 최하위 계층부터 서비스를 제공하는 구조까지 계층이 구성되어있다. 계층적인 구조답게 <strong>interface가 변경되면 인접 계층에만 영향</strong>을 미친다. interface에서 여러 계층을 통해 최하위 계층에 존재하는 OS, DataBase까지 계층을 구성해서 운영한다
<img src="https://velog.velcdn.com/images/woong_crouch/post/fab0ae95-f387-474a-8099-850de3e0cbd4/image.png" alt=""></p>
<p><strong>기존 시스템 위에 새로운 기능을 구축</strong>하거나 여러 팀에 개발이 분산되고 <strong>각 팀이 하나의 계층을 책임지는 경우에 주로 사용</strong>하며, 장점으로 <strong>인터페이스가 유지되면 전체 계층의 교체가 가능</strong>하고 <strong>각 계층에 중복 기능을 제공</strong>할 수 있다.</p>
<p>가장 단순한 방식인 만큼 단점도 명확히 존재하는데, <strong>첫번째로 층간분리가 명확하게 발생하지 않는다</strong>는 점이다. 이에 대한 구현의 난이도 또한 높다. 둘째로 <strong>서비스의 요청에 따라 해석 단계가 여러 차례 존재하기에 성능 문제가 발생</strong>할 수 있다. 이로 인해 불필요한 계층간 이동이 발생하여 성능저하가 발생하게 된다.</p>
<h3 id="repository-architecture">Repository Architecture</h3>
<p>모든 데이터가 중앙 저장소에 관리되며, 시스템의 서브 컴포넌트들은 서로 직접 통신하지 않고 <strong>오직 중앙 저장소를 거쳐 데이터를 주고 받는다.</strong></p>
<p>데이터를 교환하는 일종의 보조 시스템의 역할을 담당한다. Repository는 2가지 일을 수행하는데 그 일들은 아래와 같다. 첫째로 <strong>공유 데이터는 중앙 DB 또는 repository에 저장</strong>되며, <strong>모든 하위 시스템에서 접근</strong>할 수 있습니다. 둘째로 <strong>각 하위 시스템은 자체 데이터베이스를 유지</strong>하고 데이터를 다른 하위 시스템에 전달한다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/e76a0690-68de-402d-bac0-32d6c125e1ee/image.png" alt=""></p>
<p><strong>장기간 대량 정보가 생성되는 시스템에서 주로 사용</strong>하고, <strong>컴포넌트가 모두 독립적이어서 개발하기 편하고 데이터를 일관성 있게 관리할 수 있다</strong>는 장점이 있지만, <strong>저장소가 문제가 생기면 전체 시스템에 문제가 생긴다는 점</strong>과 <strong>모든 통신을 저장소를 통해 구성하는 것이 비효율적인</strong> 단점이 존재하기도 한다.</p>
<h3 id="client-server-architecture">Client-Server Architecture</h3>
<p>독립적인 특정 서비스를 제공하는 <strong>&#39;서버&#39;의 집합과 네트워크를 통해 서버들에 접속하는 서비스</strong>를 이용하는 &#39;클라이언트&#39; 집합으로 분산된 모델이다. 서버 1개와 다수 클라이언트가 소통하는 구조로, 여러 컴포넌트에 걸쳐 분산을 보이는 분산시스템의 모델이다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/6be6a95e-7352-49c9-b599-04130599f6ed/image.png" alt=""></p>
<p>주로 <strong>공유 DB의 데이터를 다양한 위치에서 접근할 때 사용</strong>하고, 시스템의 <strong>부하가 가변적일 때에도 적용</strong>할 수 있다. 서버를 네트워크 상에 분산시키거나 복제해 부하를 조절할 수 있다. 하지만 시스템의 성능이 네트워크 상태에 의존하기에 예측이 어렵고 특정 <strong>서버가 다운되거나 DoS공격을 받게되면, 서비스가 중단될 위험</strong>이 있다.</p>
<h3 id="pipe-and-filter-architecture">Pipe And Filter Architecture</h3>
<p>우리가 흔히 아는 <strong>Unix Shell</strong>이 이 Pipe and filter 구조로 만들어졌다. <strong>입력 데이터를 각 컴포넌트(필터)가 한가지 형태의 데이터 변환으로 처리한 이후 Pipe를 통해 다음 컴포넌트로 넘겨주는 구조</strong>이다. interactive한 시스템에는 적합하지 않지만 순차적으로 처리하는 경우에는 주로 사용할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/e262fe19-cb91-44e1-addd-7ad3adc2e024/image.png" alt=""></p>
<p>하나의 컴포넌트에서 다른 컴포넌트로의 데이터 흐름을 말한다. 주로 흔히 <strong>데이터 처리 기반 애플리케이션에서 사용</strong>된다. 하지만 데이터 전송 형식은 통신하는 변환 간에 합의되야한다는 점이 필요하다.(우리는 이것을 프로토콜이라고 부른다)</p>
<p>워크플로우 비즈니스 프로세스에 적합하며, 변환 단계들이 <strong>병렬 처리(Parallelism)가 가능해 효율을 크게 높일</strong> 수 있다. 다만 컴포넌트 간에 호환되는 <strong>데이터 포맷을 맞춰야하는 오버헤드가 발생</strong>한다.</p>
<h2 id="application-architecture">Application Architecture</h2>
<p>도메인마다 사용하는 어플리케이션 구조가 비슷해 이를 정리한 구조이다. 주로 조직의 요구사항을 충족하도록 설계한다. 비슷한 구조를 중심으로 <strong>특정 요구사항을 충족하는 시스템을 구축하기 위해 구성 및 적용할 수 있는 SW System 유형의 아키텍처</strong>이다. 크게 두가지의 종류로 표현된다.</p>
<h3 id="transaction-processing-systems">Transaction processing systems</h3>
<p>우리가 흔히 아는 웹 정보 시스템(전자상거래, 예약 시스템, ATM 등)으로, 주로 <strong>데이터베이스와의 상호작용</strong>을 다룬다.</p>
<p>가장 밑에 DB가 깔리고, 그 위에 비즈니스 로직, UI가 올라가는 형태를 취한다. 데이터베이스에서 정보를 검색하거나 데이터베이스를 업데이트하려는 <strong>사용자의 비동기적 요청을 처리</strong>한다.</p>
<p><strong>Information System Architecture</strong>
정보 시스템은 <strong>계층형 아키텍처로 구성될 수 있는 보편적인 아키텍처</strong>이다. 계층에는 사용자 인터페이스, 사용자 통신, 정보 검색, 시스템 데이터베이스를 포함한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/f919c1ea-305e-4e10-9462-87e5e5403013/image.png" alt=""></p>
<h3 id="language-processing-system">Language processing system</h3>
<p><strong>기계어나 자연어를 입력받아 다른 표현으로 변환하는 시스템</strong>을 말한다. 우리가 흔히 생각하는 <strong>컴파일러, 인터프리터</strong>가 이 시스템에 포함된다. </p>
<p>컴파일러의 경우 아키텍처가 방식에 따라 여러개로 나뉘고, 이전에 Architecture Pattern에서 보였던 기법들을 주로 사용한다. (pipe-and-filter , repository 등)</p>
<p>오늘은 Architecture Pattern에 대해서 알아보았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WebSocket 통신 방식에 대해서]]></title>
            <link>https://velog.io/@woong_crouch/WebSocket-%ED%86%B5%EC%8B%A0-%EB%B0%A9%EC%8B%9D%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C</link>
            <guid>https://velog.io/@woong_crouch/WebSocket-%ED%86%B5%EC%8B%A0-%EB%B0%A9%EC%8B%9D%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C</guid>
            <pubDate>Mon, 23 Mar 2026 15:58:10 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며..</h2>
<p>주식 예측 프로그램을 동기들과 제작해보는 프로젝트를 진행 중에, 주식 그래프를 구현하면서 몇 가지 이슈에 부딪혔다. 초기엔 BackEnd에서 구현해본 것이 REST API가 대부분이라 당연히 방향성을 그렇게 잡고 움직였다.</p>
<p>하지만 프론트를 조금 구현하던 중 정보를 받아오는 것이 REST API로 진행하면 매끄럽지 않다는 것을 인지했다. 이러한 문제를 해결하고자 방법을 찾다가 <code>WebSocket</code>을 찾았고, 우리는 공부를 위해 REST와 <code>Websocket</code>을 모두 구현해보고자 한다.</p>
<p>그러기 위해서는 <code>WebSocket</code>에 대한 공부가 필요했고, 공부한 내용을 이렇게 블로그에 정리해보았다.</p>
<h2 id="rest-api-와-websocket">REST API 와 WebSocket</h2>
<p><code>REST API</code>와 <code>WebSocket</code>의 차이를 알아보려면 REST API가 가지는 한계를 알아봐야한다. REST API는 아래와 같은 한계를 가진다.</p>
<ul>
<li><strong>요청이 반드시 필요하다.</strong></li>
<li><strong>응답을 받으면 바로 연결을 끊어버려서 다시 요청을 보내야 통신이 가능하다.</strong></li>
<li><strong>정보를 전송할때마다 HandShake를 진행한다.</strong></li>
</ul>
<p>이러한 한계들은 결국 데이터를 빠르게 받아오고 빠르게 처리하는 과정이 필요한 서비스에는 너무도 비효율적인 방식이 되었고, 결국 <code>WebSocket</code>이 탄생하여 오늘날 사용되게 되었다.</p>
<h2 id="code로-보는-websocket">Code로 보는 WebSocket</h2>
<p>그렇다면 코드로는 어떻게 구현해볼 수 있을까. 내가 자주 사용하는 Spring Boot를 이용해서 이 WebSocket 기술을 구현해보자.</p>
<h3 id="controller">Controller</h3>
<pre><code>@Controller
public class StockController {

    private final StockService stockService;
    private final SimpMessagingTemplate messagingTemplate; 

    public StockController(StockService stockService, SimpMessagingTemplate messagingTemplate) {
        this.stockService = stockService;
        this.messagingTemplate = messagingTemplate;
    }

    // React에서 &#39;/app/subscribe&#39; 로 메시지를 보낼 때 실행됨
    @MessageMapping(&quot;/subscribe&quot;) 
    public void handleSubscribe(@Payload Map&lt;String, String&gt; payload) {
        String symbol = payload.get(&quot;symbol&quot;);
        Object currentStockData = stockService.getCurrentPrice(symbol); 
        messagingTemplate.convertAndSend(&quot;/topic/stock/&quot; + symbol, currentStockData);
    }
}</code></pre><p>위 코드는 개략적인 코드를 가져왔다.</p>
<p><code>WebSocket</code>을 본격적으로 작업하려면 <strong>Topic(Room)</strong>이라는 개념을 이해해야한다. 웹소캣을 통해 주식 데이터를 받아오면 API를 통해 모든 주식 정보를 다 받아오게 된다. 만약 방이 없다면 이러한 정보들을 처리하지 못하고 받아내면서 브라우저에 강한 무리를 주게 된다.</p>
<p>이를 방지하기 위해 우리는 각 주식에 맞게 &quot;Room&quot;을 나누어서 처리한다. 그러면 사용자(User)는 방을 골라서 본인이 원하는 정보를 담은 Room에 대한 정보를 얻는 것이다. 이 과정을 우리는 <strong>Subscribe(구독)</strong>이라고 한다.</p>
<p>그리고 여기서 우리는 <strong>SimpMessagingTemplate</strong>을 주요하게 봐야한다. 이 항목은 이 <code>WebSocket</code>에서 정보를 알려주는 확성기의 역할을 한다. 이 확성기는 모두를 향해 제공되지만 이를 Room을 나누고 구독을 함으로서 각각의 방에, 각각의 User에게 원하는 데이터를 전송해주는 것이다.</p>
<p>이 코드는 아주 예시이기에 현재 가격을 가져오고, Room을 나눠서 특정 Room의 사용자들에게 값이 전달되는 기능만을 가지는 Controller이다.</p>
<h3 id="service">Service</h3>
<pre><code>@Service
public class StockService {

    private final Random random = new Random();
    private double lastClose = 75000;

    public StockPrice getLatestPrice(String symbol) {
        double open  = lastClose + (random.nextDouble() * 400 - 200);
        double close = open      + (random.nextDouble() * 1000 - 500);
        double high  = Math.max(open, close) + random.nextDouble() * 300;
        double low   = Math.min(open, close) - random.nextDouble() * 300;
        lastClose = close;

        return new StockPrice(
                symbol,
                (long) open,
                (long) high,
                (long) low,
                (long) close,
                Instant.now().getEpochSecond()
        );
    }
}</code></pre><p>Service는 받아내는 정보에 맞게 수정해야한다. 지금은 임시로 시가, 종가, 고가, 저가를 중심으로 나누어서 작업을 하도록 구성해두었다.</p>
<p><del>사실 WebSocket 구현 자체와는 크게 중요한 내용이라고 보이진 않는다. 차후 기능이 추가되면 더 자주 사용될 것이다.</del></p>
<h3 id="scheduler">Scheduler</h3>
<pre><code>@Component
public class StockScheduler {

    private final SimpMessagingTemplate messagingTemplate;
    private final StockService stockService;

    public StockScheduler(SimpMessagingTemplate messagingTemplate, StockService stockService) {
        this.messagingTemplate = messagingTemplate;
        this.stockService = stockService;
    }

    @Scheduled(fixedDelay = 1000)
    public void pushStockPrices() {
        StockPrice price = stockService.getLatestPrice(&quot;005930&quot;);
        messagingTemplate.convertAndSend(&quot;/topic/stock/005930&quot;, price);
    }
}</code></pre><p>우리는 여기서 특정 종목에 대한 dto를 받아와서 messagingTemplate로 정의된 확성기를 통해 /topic/stock/{stockId} 라는 Room으로 내용을 쏴주는 절차를 밟는다. 1000ms로 작업을 해두었기에 1초마다 새로운 봉차트를 그리는 방향으로 디자인된다. Scheduler가 가지는 가장 중요한 요소는 <strong>1초마다 정보를 보내준다는 것</strong>이다.</p>
<p>사실상 front-End로 가기위해서는 <code>Scheduler</code>는 필수적인 요소이라고 볼 수 있다.</p>
<h2 id="summary">Summary</h2>
<p>전체적인 플로우는 위의 사진과 같이 이해하면 될 것 같다. 전체적인 플로우를 이해하고 코드를 들여다 보면 더 쉽게 느껴지지 않을까 싶다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/249c9f52-8c34-4287-a3fd-20cd8c120c12/image.png" alt=""></p>
<p>물론 기능적으로 앞으로 더 맞춰나갈 것이 많으리라 보지만, 당장 처음 배운 개념과 기술에 대해서 너무 많은 것을 한번에 하기보다는, 하나씩 배워나가며 개념을 정립하고 이를 확장해서 더 좋은 기능들을 추가해 나가는 방향의 작업도 좋지 않을까.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[PM으로서의 첫걸음]]></title>
            <link>https://velog.io/@woong_crouch/PM%EC%9C%BC%EB%A1%9C%EC%84%9C%EC%9D%98-%EC%B2%AB%EA%B1%B8%EC%9D%8C</link>
            <guid>https://velog.io/@woong_crouch/PM%EC%9C%BC%EB%A1%9C%EC%84%9C%EC%9D%98-%EC%B2%AB%EA%B1%B8%EC%9D%8C</guid>
            <pubDate>Mon, 23 Mar 2026 14:24:55 GMT</pubDate>
            <description><![CDATA[<p>대학교를 들어와서부터 나는 창업에 관심이 많았고, 자연스레 동기들과 프로젝트에서 팀리더의 역할을 맡아왔다.</p>
<p>내가 이끄는 것을 좋아해서인지 이끌다보니 좋아진 것인지는 모르지만, 어렸을 때부터 이러한 리더의 역할을 동경하고 지향해 왔다는 것에는 이유가 있지 않을까.
3학년이 된 지금, 나는 많은 프로젝트를 해보고 이끌어보고자 한다. 지금 진행 중인 프로젝트들도 많고 이 프로젝트에서 나의 역할을 다양하다. Front-end, Back-end 등 여러 파티션에서 경험을 쌓아가는 중이다. 그리고 이러한 경험이 충분한 밑거름이 된다고 생각하고 나는 천천히 이끌어 나갈 것이다.</p>
<p>IT 업계에서 PM으로의 길을 조금씩 나아가보고자 한다.</p>
<h2 id="product-manager">Product Manager</h2>
<p>우선 Product Manager이란, Product(제품)을 Manage(관리)한다는 아주 간단한 뜻풀이로 접근할 수 있다. 
그렇다면 그냥 아이디어 내는 기획자랑 비슷한가? 그렇게 묻는다면 크나큰 오산이다. 보편적으로 PM은 <strong>제품을 출시하고 유지보수하기까지의 전반을 운영 하는 것</strong>에 중심을 둔다. 아무래도 운영을 한다는 지점에서 이 직군은 경력이 있어야 주로 도달한다는 특징을 가지기도 한다. 왜 경력이 있어야 PM을 할 수 있는 것인가? 그래야만 이 시스템 전반에 대해서 알 수 있기 때문이다.</p>
<p>자연스레 대학생인 내가 왜 <code>PM</code>을 꿈꾸는지를 궁금해할 수 있다. 그건 다음에 또 다른 포스트로 적어보겠다.</p>
<p><code>PM</code>의 가장 주요한 역할은 &quot;기획문서 작성&quot;이다. 그렇다면 기획 문서는 무엇일까.</p>
<h2 id="기획문서">기획문서</h2>
<p>기획문서는 하나의 서비스를 만들 때, 필요한 내용을 정리하고 효율적인 소통을 위해 정의해두는 명세서와 같은 문서들의 집합이라고 볼 수 있다.</p>
<p>그렇다면 어떤 기획문서를 작성해야할까?</p>
<h3 id="ia">IA</h3>
<p>IA, <code>Information Architecture</code>의 줄임말인 IA는 서비스의 정보와 계층적 구조에 대해서 보여준다. 서비스가 어떻게 구성되는지를 기준으로 하는 네비게이션 체계를 설계하는 것이 중심이다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/0f7b7ea3-905c-4ee1-9419-f8442197e4a0/image.png" alt=""></p>
<h3 id="api-명세서">API 명세서</h3>
<p>사실상 개발자와의 협업에 가장 깊게 중심을 둔 지점이다. 개발에 있어서 API 명세서는 필수적이다. 명세서를 디자인하지 않고 진행하게 되면 협업 자체가 굉장히 버거워진다. 그래서 최대한 명확하게 필요한 정보를 작성하는 것이 중요하다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/9c4f497f-0ef1-4d7b-b3df-406c1535e3ba/image.png" alt=""></p>
<h3 id="erd">ERD</h3>
<p>API 명세서와 더불어 백엔드 개발자의 중추와도 같은 요소로, 데이터베이스 구조를 작성하는 것이다. 데이터가 많이 필요한 서비스일수록 이 ERD의 구조에 따라 프로그램의 성능이 격하게 차이난다. 고로 ERD 작성을 하는 것에 힘을 많이 들여야한다.
<img src="blob:https://velog.io/c32e39fd-bf5f-4b7d-a9e6-8146eca6e97f" alt="업로드중.."></p>
<h3 id="prd">PRD</h3>
<p>사실상 이 모든 내용의 개요가 될 문서이다. 요구사항 정의서라고 불리는 이 문서의 작업을 통해 프로젝트의 방향성을 명확하게 드러낸다. 개요서나 계획서와도 같은 결을 가지고 있다고 볼 수 있는 문서로, PM으로서 작성해야하는 중요 문서 중 하나이다.</p>
<h2 id="마치며">마치며..</h2>
<p>프로젝트를 진행하면서 이외에도 다양한 기획 문서를 적용할 수 있고, 그런 다양한 기획문서를 이용해서 더 좋은 설계를 할 수 있다. 
여러 프로젝트를 거치며 PM의 역할이 중요하고 선제적인 문서작업, 기획 단계가 탄탄할수록 프로젝트가 순항한다는 것을 알게 되었고 이를 위해서 꾸준히 공부하고 다져나가고자 한다.</p>
<p>첫 포스트는 이정도로 마무리 하고자한다. 앞으로는 더 좋은 글을 써나갈 수 있기를 바라며..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Software Engineering & Testing(3) - 방법론 & 요구사항 분석]]></title>
            <link>https://velog.io/@woong_crouch/Software-Engineering-Testing</link>
            <guid>https://velog.io/@woong_crouch/Software-Engineering-Testing</guid>
            <pubDate>Wed, 18 Mar 2026 00:27:22 GMT</pubDate>
            <description><![CDATA[<h1 id="sw-개발-방법론">SW 개발 방법론</h1>
<h2 id="sw-개발-방법론-개요">SW 개발 방법론 개요</h2>
<h3 id="sw-개발-방법론이란">SW 개발 방법론이란?</h3>
<p>소프트웨어 시스템을 개발하는데 필요한 일련의 활동을 우리는 <strong>&quot;소프트웨어 프로세스&quot;</strong> 라고 부른다. 이는 아래와 같은 요소로 구성된다.</p>
<ul>
<li><strong>명세</strong> : 시스템이 무엇을 해야하는지 정의한다.</li>
<li><strong>설계 및 구현</strong> : 시스템의 조직을 정의하고 시스템을 구현한다.</li>
<li><strong>테스팅</strong> : 고객이 원하는 것을 수행하는지 확인한다.</li>
<li><strong>유지보수</strong> : 변화하는 고객 요구에 대응해서 시스템을 변화시킨다.</li>
</ul>
<p>소프트웨어 프로세스 모델. 즉, <strong>개발방법론은 프로세스의 추상적인 표현</strong>이다. 특정 관점에서 프로세스에 대한 설명을 제공하는 것을 말한다.</p>
<h3 id="sw-개발-방법론의-비교-포인트">SW 개발 방법론의 비교 포인트</h3>
<p>현재 SW 산업에서는 여러 개발 방법론이 존재한다. 우리는 이 방법론들을 비교해보고 적절한 방법론을 사용해야하는데, 아래의 기준을 통해 비교를 할 수 있다.</p>
<ul>
<li><strong>주요 활동의 반복성</strong> : 주요 활동을 반복하는지, 그리고 얼마나 자주 하는지를 고려해야한다.</li>
<li><strong>수행가능 버전(MVP)의 출시 기간</strong> : 수행가능한 버전인 MVP가 언제 나오는가에 대해 고려해야한다.</li>
<li><strong>요구변경 수용</strong> : 요구사항 변경이 들어오면 이를 얼마나 대응할 수 있는가를 고려해야한다.</li>
<li><strong>개발 스케줄 관리 수월성</strong> : 개발 일정을 얼마나 가시적으로 드러내는지 고려해야한다.</li>
</ul>
<p>요즘과 같은 시대에는 AI의 역할이 크게 대두되는 추세인데, AI에게 일을 잘 시키기 위해서는 프롬프트를 잘 전달해줘야 한다. 이러한 AI 시대에 어떤 식으로 필요한 인력이 되어 스토리를 풀어나갈 것인지 생각해봐야 한다.</p>
<h2 id="sw-개발-방법론의-종류">SW 개발 방법론의 종류</h2>
<h3 id="1waterfall-모델">1.Waterfall 모델</h3>
<p>Waterfall 모델은 위 그림처럼, 명확하고 순차적인 단계를 지닌다. 프로젝트가 시작해서 문제분석, 요구사항 명세 등을 거쳐 <strong>구현까지의 로직이 순차적으로 존재한다는 것</strong>이 특징이다. </p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/eab86be7-6f37-4030-806d-92a15701fa4b/image.png" alt=""> waterfall 모델의 로직</th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/fd5d8df4-7c6d-41bd-bed8-bfa75c94fb8c/image.png" alt=""> waterfall의 비유연성</th>
</tr>
</thead>
</table>
<p>이러한 순차적 구조는 가장 치명적인 문제를 가지는데, 바로 <strong>비유연성</strong> 이다. 중간 절차에 대한 변경사항이 존재할 때, 이를 수행하는 것이 어렵다는 것이다. 이러한 점이 문제를 크게 발생시킨다.</p>
<p>이러한 Waterfall 모델은 <strong>요구사항이 명확한 경우</strong>에만 적용하기에 적합하다. 그래서 보통 Critical Project, <strong>즉 국방과 같은 분야에서는 문서화와 인증이 필수적이므로 장기 프로젝트</strong>에서는 필연적으로 이 방법론을 선택하게 된다.</p>
<h3 id="2병렬적-개발-방법론">2.병렬적 개발 방법론</h3>
<p>Waterfall 모델이 조금 변형된 스타일로, 같은 구조적 개발 방법론의 축에 들어간다. <strong>계획, 문제 분석, 요구사항 명세는 순차적으로 진행</strong>하고, <strong>이후의 개발은 subproject를 여러개를 동시에 실행시켜서 Prototype을 형성하는 방법론</strong>이다. 이 또한 요구사항이 명확한 경우에만 사용하는 것이 좋다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/f9ba539b-5db0-40cc-a2c1-7853573b6885/image.png" alt=""></p>
<h3 id="3prototyping">3.Prototyping</h3>
<h4 id="진화적-프로토타이핑">진화적 프로토타이핑</h4>
<p><strong>빠르게 prototype을 만드는 것에 중심을 두고 개발하는 방식</strong>이다. 초기 개발 사양을 구성하고 이를 최종 시스템으로 수정 및 보완해서 확장하고 이를 통해 시스템을 개발하는 방식을 말한다. 요구사항이 명확하게 설정되지 않은 경우에 요구사항을 명확하게 하기 위해 사용하는 방법이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/4e898e6d-8ca2-4088-827e-c6a6ae690967/image.png" alt="">
하지만 프로토타이핑 또한 단점이 분명하게 존재하는데, 초기 프로토타입에 래핑을 하는 것이기에 프로젝트가 다소 지저분해질 수 있고, 이 과정에서 복잡성이 증대한다는 것을 볼 수 있다.</p>
<h4 id="throwaway-프로토타이핑">Throwaway 프로토타이핑</h4>
<p>위와 같은 문제를 해결하기 위해, <strong>Waterfall 모델을 적절히 섞은 프로토타이핑</strong>이라고 보면된다. 엄밀히 말하면 프로토타이핑의 목표는 시스템 요구사항을 이해하는 것이라고 볼 수 있다. 우리가 Waterfall 모델을 알아볼 때, 이 방법론은 요구사항이 명확해야한다고 했으니 둘을 잘 섞어본 것이다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/dc9595b8-5996-44e8-b7bd-e2ee0c03d01b/image.png" alt=""></p>
<p>그래서 요구사항이 명확해질때까지 프로토타이핑을 사용하고 이후 Waterfall 모델을 이용해 개발하는 방식을 진행한다. 이를 통해 복잡성이 과도히 증대되는 것을 막을 수 있다.</p>
<p>이러한 <strong>prototyping 방식은 속도에 의미</strong>를 가진다. 대부분의 경우 갑과 을의 관계에서 개발을 진행하고 그러다보니 프로토타입이 빠르게 나올수록 갑의 이해도가 정립되면서 요구사항의 품질이 올라가는 효과를 볼 수 있다.</p>
<h3 id="incremental점진적-개발">Incremental(점진적) 개발</h3>
<p>기능에 대한 increment(증분)을 미리 나누어 두고 개발을 하는 방식을 말하고, 사용자 요구사항에 우선순위를 부여해서 그 순위에 맞춰서 작업하는 방식이다. 해당 요구사항은 고정하고 이후 증분에서 요구사항을 계속 발전시키는 방식이다. 한마디로 <strong>전체 시스템을 필요한 여러 개의 기능 단위인 &#39;증분(Increment)&#39;으로 나누어 순차적으로 개발하는 방식</strong>이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/d7314a6d-5ba3-40ec-99f4-74c95a466b97/image.png" alt=""></p>
<p>기능을 빠르게 제공하고, 실패 위험을 감소시키며 우선순위에 따라 테스트가 많이 발생할 수 있다는 점에서 장점을 가지지만 개발이 빠르게 진행되어 매 버전마다 문서를 수정하는 것이 비효율적일 수 있고, <strong>증분이 추가될 때 구조가 점점 지저분해지는 프로토타이핑의 특성이 단점으로 작용한다.</strong></p>
<p>prototype과 거의 유사하지만 조금 더 체계적인 방식으로 이뤄진다. 그러다보니 위에서 말한 것처럼 prototype의 문제점도 똑같이 가진다. incremental 개발 방법은 객체 지향 개발 방법이고, 그에 따라서 적용되는 분야도 상황에 따라 바뀐다.</p>
<h3 id="unified-process">Unified Process</h3>
<p>Unified Process(UP)는 기존의 구조적 방법론들과 다르게 <strong>객체 지향 방법론의 일종</strong>이다.</p>
<p>Booch Method, Jacobson&#39;s Objectory, OMT라는 방법론을 하나로 합친 방법론이 발표된다. UP는 적응가능한(adaptable) 방법론이다. 즉, <strong>특정 정보 시스템의 특성에 맞게 수정해서 적용하는 방식</strong>이라는 것이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/70cda42b-a4b8-452b-85e5-9bbe7f08dcdf/image.png" alt=""></p>
<h3 id="애자일-방법론">애자일 방법론</h3>
<p>애자일 방법론은 사실상 오늘날 가장 주로 쓰이는 방법론으로 불린다. <strong>단순하고 반복적인 개발을 강조</strong>하며, 아래의 표를 통해 애자일 개발의 원리를 확인할 수 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/97486569-2633-42dd-871a-a1a70016f163/image.png" alt=""></p>
<p>애자일 방법론의 가장 핵심은 &quot;타임 투 마켓&quot;이다. 어떤 프로그램이나 서비스를 출시하고자할 때, <strong>그 서비스의 완성도보다는 출시 시기가 더욱 중요한 요소</strong>이다. 품질이나 완성도를 후순위로 차치한 이후 빠르게 시장에 서비스나 제품을 출시하는 것을 최우선으로 스프린트를 컴팩트하게 가져가는 방법이다. </p>
<h3 id="xpextreme-programming">XP(Extreme Programming)</h3>
<p>XP 방법은 반복적 및 점진적 방법을 이용해 정보 시스템 개발에서 이슈가 되는 새로운 접근법이다.</p>
<p>프로그래머는 먼저 Task에 대한 Test case를 생성해서 자동 테스트 환경을 구성하고 하나의 컴퓨터에서 파트너와 함께 동시 작업한다. 이 모든 테스트 케이스를 올바르게 작동할 때까지 구현하고 이가 마무리되면 끝내는 방식을 택한다. 이때 <strong>한 컴퓨터로 동시에 작업한다는 의미는 한명이 코딩하고 한명은 뒤에서 같이 보면서 작업하는 것</strong>을 말한다.</p>
<p>XP의 방식을 택하려면 기본적으로 <strong>중급 이상의 시니어급 프로그래머</strong>가 되어야한다. 그리고 Customer를 한명 넣어서 운영된다. 로직을 보면 하루 단위로 개발 버전을 수정하고 업데이트를 해 나가고, Customer가 개발 버전을 검증하고 피드백을 주는 방식으로 운영된다. </p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/0d6cb30c-a77d-4bd6-bd9b-d22ef89c2032/image.png" alt=""></p>
<h4 id="ms의-사례">MS의 사례</h4>
<p>우리는 MS를 한번 주목할 필요가 있다. MS는 에러가 발생함에 크게 개이치 않는다. <strong>애자일 방법론의 기조에 맞게 제품을 만들고 시장이 필요로 하는 시점에 완성도가 낮아도 일단 출시</strong>하여 이후 제품을 보강해 나가는 것이다. 이러다보니 MS가 독특한 점이 있는데, 보통은 갑과 을이 존재하는 프로젝트가 대부분이지만 MS의 경우에는 갑이 명확하게 존재하지 않는다. 어찌보면 대중이 그 갑의 위치로 들어갈 수도 있다고 본다. 결론적으로 MS가 가지는 포인트는 <strong>&quot;time to market&quot;</strong>이다.</p>
<p>애자일 방법론은 기존의 방법론들이 절차를 중시하며 흐름을 이어간 것과 다르게 사람을 중심으로 개인의 업무 프로세스를 보장해주는 방법론이다. 에러가 발생하면 수정하고 다시 테스팅하는 과정을 거치며 스프린트를 아주 잘게 쪼개서 업무를 이어간다. 이렇게 이어가다보면 코드가 스파게티 코드가 되고, 이를 정리해주는 것이 <strong>&#39;리팩토링&#39;</strong>이다. 리팩토링을 통해서 기존의 코드를 수정한다. 다만 리팩토링의 특징은 기능을 추가하거나 더 새로운 기술을 넣는 것이 아니라, 서비스 자체는 큰 변화가 없다는 것이다.</p>
<p>나아가 테스팅을 하는 관점에서는 이 방식을 TDD라는 이름으로 이해할 수 있는데 <strong>TDD란 Test-Driven Development</strong>로, 실제 코드를 작성하기 전에 실패하는 단위 테스트를 먼저 작성하고, 이를 통과한 최소한의 코드를 구현해 리팩토링을 반복하는 과정을 말한다.</p>
<h3 id="plan-driven-vs-agile-specification">Plan-driven vs agile specification</h3>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/b879cc87-2cb0-4fc0-b529-79eea5155ee8/image.png" alt=""></p>
<hr>
<br>

<h1 id="요구사항-분석">요구사항 분석</h1>
<h2 id="요구사항-분석의-목표">요구사항 분석의 목표</h2>
<p>요구사항 분석은 제안된 시스템이 무엇을 수행하는지를 정의한 것이며, 어떻게를 정의하는 것은 아니다. 명확히 말하면 <strong>&quot;What&quot;을 정의하는 것</strong>이라 볼 수 있다. <del>어떻게는 설계 단계에서 정의 한다.</del></p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/65549e80-1afa-453e-8399-d167b6210b10/image.png" alt=""> </p>
<h2 id="요구사항-명세의-구성요소">요구사항 명세의 구성요소</h2>
<p>요구사항 명세의 구성요소로는 아래의 3가지로 나뉘는데, 앞의 2개는 우리가 흔히 생각하는 요구사항의 명세이다. 무엇을 수행하는지, 어떤 특성을 가지는지 이것은 <strong>프로젝트에서 반드시 다루어야하는 내용</strong>이라고 볼 수 있다. </p>
<p>하지만 그보다 선행되게 생각해야하는 부분이 있는데, 그것이 <strong>도메인의 기본적인 상식</strong>이다. 내가 하고자하는 프로젝트가 포함된 도메인에 대해서 기본적인 지식을 가지지 않으면 큰 어려움을 가질 수 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/b4867a1f-6fa8-4b2c-a2fd-32958cff0ec7/image.png" alt=""></p>
<h3 id="기능적--비기능적-요구사항">기능적 &amp; 비기능적 요구사항</h3>
<p>요구사항은 크게 두가지로 나뉘는데, 기능적 요구사항, 비기능적 요구사항으로 나뉜다.</p>
<h4 id="기능적-요구사항">기능적 요구사항</h4>
<p>기능적 요구사항은 시스템이 제공해야하는 서비스 명세서로 특정 입력이 발생하면 이에 대한 반응을 어떻게 할 것이고, 특정 상황에서 시스템이 어떻게 작동하는지 등의 <strong>서비스의 기능적인 요소를 포함하는 내용</strong>이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/b391f45b-b6f7-42a2-9abc-4e34ea90d076/image.png" alt=""></p>
<h4 id="비기능적-요구사항">비기능적 요구사항</h4>
<p>비기능적 요구사항은 서비스의 기능이 아닌 개발 프로세스의 제약, 표준 등의 시스템이 제공하는 서비스나 기능의 제약사항들을 말하고, 개별 기능이나 특정 컴포넌트가 아닌 <strong>전체 시스템에 적용되는 속성들</strong>을 기술한다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/0c57ee08-0d56-4a8f-897e-5fdec05f39a0/image.png" alt=""></p>
<h2 id="요구사항-명세서-작성법">요구사항 명세서 작성법</h2>
<p>요구사항 명세서는 다음과 같은 방법으로 작성할 수 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/8fba97ee-64db-4527-a23a-3279ea4665f1/image.png" alt=""></p>
<h3 id="자연어-명세">자연어 명세</h3>
<p><strong>자연어 문장으로 명세를 작성하는 방식</strong>을 이야기한다. <strong>가장 직관적이고 표현하기가 용이</strong>하기 때문에 보편적으로 사용하고 고객 또한 요구사항을 쉽게 이해할 수 있다. 하지만 이 표기법은 몇가지 문제점이 존재한다.</p>
<ul>
<li><strong>명확성 부족</strong> : 정확도를 높이면 문서를 읽거나 이해하기가 어려워진다.</li>
<li><strong>요구사항 혼동</strong> : 기능적, 비기능적 요구상항이 혼재되는 경향이 있다.</li>
<li><strong>요구사항 합병</strong> : 여러가지 요구사항을 함께 묶어 하나로 표현할 수 있다.</li>
</ul>
<h3 id="구조적-명세">구조적 명세</h3>
<p>작성자의 표현 자유가 제한되고 요구사항을 표준방식으로 작성하도록 하고 <strong>임베디드 제어 시스템에 대한 요구사항에는 적합</strong>하나 <strong>정보 시스템의 요구사항 작성에는 매우 엄격</strong>하다.</p>
<h3 id="uml-based-system-modeling">UML-based System Modeling</h3>
<p>UML 방식의 장점은 <strong>Customer가 딱 보고 무슨 이야기인지 이해할 수 있다는 점</strong>이다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/91c2cf06-54c5-4866-bf56-e62e939fe59a/image.png" alt=""></p>
<h4 id="use-case-분석">Use Case 분석</h4>
<p><strong>고객 요구사항에 대한 분석, 개발 시스템의 범위를 정의</strong>한 것으로, 요구사항을 그래픽 다이어그램 및 시나리오 방식으로 기술하는 형태다. 시스템 관점에서 외부 상호작용의 적절정을 검증하고 수행 시나리오로서 acceptance test에 활용된다.</p>
<ul>
<li><strong>Use Case</strong>
use case는 actor 관점에서 <strong>관찰 가능한 연속적인 행위의 집합을 기술</strong>한 것이다.</li>
<li><strong>Actor</strong></li>
<li><em>시스템과 상호작용하는 외부 에이전트가 수행하는 역할*</em>을 말하고, 하나의 외부 에이전트가 여러 역할을 수행할 수 있다.</li>
</ul>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/6089780f-8296-4ebc-8c3f-d0563ab80586/image.png" alt=""> Use Case 예시</th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/1261d39b-165b-49d3-9734-81f43fdefadb/image.png" alt=""> Use Case 설명 기술</th>
</tr>
</thead>
</table>
<h4 id="use-case-간의-관계">Use Case 간의 관계</h4>
<p>Use Case 간에는 관계가 존재한다.</p>
<ul>
<li><strong>포함 관계 &lt;&lt; include &gt;&gt;</strong>
여러 Use Case들이 공통적인 행위를 하는 경우, <strong>공통 행위를 따로 나타내고 이를 포함하도록 하는 것</strong>이다.</li>
<li><strong>확장 관계 &lt;&lt; extend &gt;&gt;</strong>
하나의 Use Case의 확장점에서 추가적인 <strong>행위를 추가해 다른 Use Case로 변형한 것</strong>이다.</li>
</ul>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/e79cf752-7331-47cf-a1cf-c7cad6255d6c/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/b2f224a1-9864-4eef-9b14-c60b9c6a4427/image.png" alt=""></th>
</tr>
</thead>
</table>
<h3 id="요구사항-명세서와-테스팅">요구사항 명세서와 테스팅</h3>
<p>요구분석 단계에서 요구사항 명세서에 명시된 <strong>기능적 및 비기능적 요구사항에 대한 Test Plan을 수립</strong>한다. Test Case 작성 과정을 통해 요구사항의 일관성 및 완전성을 검사한다.</p>
<br>
<br>

<p>이번 포스트에서는 여러 방법론들과 요구사항 명세에 대한 부분을 알아보았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Software Engineering & Testing (2) - Project 식별 및 선택]]></title>
            <link>https://velog.io/@woong_crouch/Software-Engineering-Testing-2-Project-%EC%8B%9D%EB%B3%84-%EB%B0%8F-%EC%84%A0%ED%83%9D</link>
            <guid>https://velog.io/@woong_crouch/Software-Engineering-Testing-2-Project-%EC%8B%9D%EB%B3%84-%EB%B0%8F-%EC%84%A0%ED%83%9D</guid>
            <pubDate>Wed, 18 Mar 2026 00:26:11 GMT</pubDate>
            <description><![CDATA[<h2 id="프로젝트는-어떻게-시작하는가">프로젝트는 어떻게 시작하는가?</h2>
<p>프로젝트는 비즈니스 요구사항을 중심으로 진행한다. <strong>프로젝트를 제의한 사람(Sponsor)는 요구사항을 인지하고 구현을 요청</strong>해야한다. 결론적으로 프로젝트에서 <strong><em>비즈니스 요구사항이 가장 중요한 뼈대가 되는 것</em></strong>이다. 이러한 비즈니스 요구사항은 시스템의 기능을 결정하고 이때의 비즈니스 가치가 명확하게 드러나야 한다.</p>
<h2 id="시스템-요구사항system-request">시스템 요구사항(System Request)</h2>
<p>시스템 요구사항(System Request)은 _<strong>프로젝트를 공식적으로 제안하기 위해 작성하는 1~2장 분량의 요약 문서</strong>_이며, 프로젝트에서 가장 중요한 것 중 하나이다. 요구사항에는 아래 5가지 요소를 필수적으로 포함시켜야한다.</p>
<ul>
<li><strong>Project Sponsor</strong>
프로젝트를 구상한 사람이자, 비즈니스적 측면에서 프로젝트의 주요 포인트를 짚어주는 사람이다.</li>
<li><strong>Business need</strong>
시스템을 구상할 때의 비즈니스와 관련된 이유를 나열한 것이다.</li>
<li><strong>Business requirements</strong>
시스템이 제공되었을 때, 비즈니스가 가지는 가능성을 말한다.</li>
<li><strong>Business value</strong>
시스템이 조직에 생성되어 도입되면, 이로 인해 발생하는 이점(이익)을 말한다.</li>
<li><strong>Special issues or constraints</strong>
시스템을 구현과 관련된 문제나 상위 관리자가 내린 결정들을 말한다.</li>
</ul>
<h2 id="예비-프로젝트-승인">예비 프로젝트 승인</h2>
<p>시스템 요구는 상위 관리자의 승인에 따라 작성된다. 제공된 정보를 기반으로 이 프로젝트를 진행하는 것이 메리트가 있는지를 평가한다. *<em>가치있는 프로젝트는 승인(1차)되고, 결과적으로 타당성 분석을 통한 추가적인 검증을 거친다. *</em>이를 통해 정말 실현 가능한지에 대해 파악하게 된다.</p>
<h2 id="타당성-분석-feasibility-analysis">타당성 분석 (Feasibility Analysis)</h2>
<p>제안된 프로젝트에 대한 <strong>기회와 한계를 이해할 수 있는 요소</strong>이다. <strong>프로젝트의 디테일한 비즈니스 케이스를 검증하며 프로젝트가 진행되는 내내 평가</strong>된다. 타당성 분석은 아래의 몇가지 방식으로 분류할 수 있는데, 기술적, 경제적, 조직적 관점에서 살펴볼 수 있다.</p>
<h3 id="기술적-타당성">기술적 타당성</h3>
<p>사용자와 분석가는 비즈니스 애플리케이션 영역에 대한 이해도를 말한다. <strong>현재 보유한 기술력과 경험으로 이 프로젝트의 성공을 기대할 수 있는지를 평가</strong>하는 영역이다.</p>
<p><strong>평가 요소</strong> : 해당 기술에 대해 얼마나 경험이 있는지, 프로젝트 규모가 우리가 감당할 수 있는 수준인지, 그리고 기존의 시스템과 호환이 가능한지 등을 확인한다.</p>
<p>이를 평가할 때는 만약 이전에 사용한 프로젝트가 있으면 <strong>해당 프로젝트와 비교</strong>를 해보고, 처음이라면 <strong>IT 전문가의 조언</strong>을 받아 리스크를 분석한다.</p>
<h3 id="경제적-타당성">경제적 타당성</h3>
<p>경제적 타당성은 <strong>투입되는 전체 비용 대비 회사가 얼마나 이득을 취할 수 있는지를 확인하는 평가</strong>이다. 크게는 4가지의 과정으로 이루어진다.</p>
<p>우선 <strong>1) 비용과 이익을 계산</strong>하고, <strong>2) 가치에 대한 비용과 이익을 부여</strong>한다. (이부분이 추상적이라 어려울 수 있으나 가장 중요하고, 무형 자산의 경우에도 수치화시켜 포함해야한다.) 그리고 이를 바탕으로 <strong>3) 현금 흐름을 결정</strong>하고 결론적으로 <strong>4) 재정적 타당성을 평가</strong>한다.</p>
<p>타당성 평가에는 몇가지 지표를 이용할 수 있는데, NPV, ROI, BEP가 있다.</p>
<h4 id="npv">NPV</h4>
<p>가장 명확한 지표 중 하나이며, 단순히 <strong>유출 대비 유입의 양이 얼마나 많은지를 확인</strong>할 수 있는 지표이다. 이 때, PV(present Value)는 현금 흐름의 양을 말하고 &nbsp; $PV = (1+금리)^{n(년)}$&nbsp;으로 표현한다.</p>
<p>NPV 공식은 이러한 PV를 기반으로 $$PV 이익 - PV 비용$$&nbsp;으로 표현된다.</p>
<p>NPV가 0보다 크거나 같으면 프로젝트가 진행되어도 좋은 신호이며, 만약 0보다 작은 경우에는 적합하지 않다고 이해할 수 있다.</p>
<h4 id="roi">ROI</h4>
<p><strong>ROI(Return on Investment)는 NPV를 기반으로 계산</strong>되며, $\frac{NPV}{\sum PV(Cash ,,,outflows)}$ 으로 표현할 수 있다.</p>
<h4 id="bep">BEP</h4>
<p><strong>BEP(Break Even Point)는 손익분기점까지의 시간</strong>을 의미하고, 손익분기점을 맞기까지의 시간을 계산해 구한다. 당연하게도 이 값이 크면 프로젝트가 가지는 리스크는 정비례하게 커진다.</p>
<h4 id="tangible-cost-vs-intangible-cost">Tangible Cost vs Intangible Cost</h4>
<p>각각 유형 비용, 무형 비용을 말하며, <strong>유형 비용은 시스템을 통해 조직이 얻는 이익(수익)을 모두 포함하는 비용</strong>을 말하고, <strong>무형 비용은 숫자에 기반하기보다는 직관과 믿음에 기반을 두는 비용</strong>을 말한다.</p>
<h3 id="조직적-타당성">조직적 타당성</h3>
<p>시스템이 사용자들에게 얼마나 <strong>잘 수용되고 조직의 지속적인 운영에 얼마나 잘 통합될 것인가</strong>를 나타내는 지표이다.</p>
<p>평가 요소 : 시스템의 도입이 현재 조직에 목표와 부합하는지, 그리고 <strong>Project Champion, 관리자, 최종 사용자 등의 이해관계자(Stakeholder)를 분석</strong>한다.</p>
<p>공장의 생산 라인에 로봇 시스템이 도입되는 것을 반발하는 것과 비슷한 의미를 가지며, <strong>시스템의 도입으로 조직의 변화가 잘 이끌고 잘 수용되는지를 평가</strong>하는 것이 이 평가의 주 목적이다.</p>
<p>타당성 평가의 맹점은, 한번의 평가로 끝나는 것이 아니라 <strong>프로젝트가 이뤄지는 내내 진행되는 평가</strong>로, 지속적으로 재평가를 통해 프로젝트가 잘 순항하고 있는지를 확인해야한다.</p>
<h2 id="project-selection-issue">Project Selection Issue</h2>
<p>승인 위원회는 시스템 요구사항과 타당성 평가를 바탕으로 업무를 진행한다. <strong>비즈니스 요구사항과 시스템 구축의 위험성을 검토하여 프로젝트를 신중하게 선택</strong>한다.</p>
<h3 id="포트폴리오-관리">포트폴리오 관리</h3>
<p>동시에 포트폴리오 관리도 이어지는데, 여기서 <strong>포트폴리오란 조직이 전체적으로 가져가고자하는 프로젝트가 있는 큰 물줄기</strong>를 말한다. 전체 프로젝트의 포트폴리오에서 해당 프로젝트가 어느정도 위치에 자리하고 있는지를 확인하고, 균형 잡힌 프로젝트 포트폴리오를 구성하기 위해서는 이에 대한 절충이 필요하다. 설령 <strong>실행이 가능한 프로젝트 일지라도 포트폴리오의 문제로 인해 거부되거나 연기되는 결정이 내려질 수 있다.</strong></p>
<h1 id="project-management">Project Management</h1>
<h3 id="프로젝트-관리의-4가지-주요-절차">프로젝트 관리의 4가지 주요 절차</h3>
<p>프로젝트를 관리할 때 우리가 주요하게 거쳐야할 4가지의 절차가 있는데, <strong>1) 프로젝트의 규모를 식별</strong>하고, 팀원과 조직의 상황에 맞게 <strong>2) 업무 일정을 구성하고 관리</strong>한다. 그리고 일정에 맞게 <strong>3) 인력을 배치</strong>하고 마지막으로 <strong>4) 프로젝트의 활동을 조정</strong>한다.</p>
<p>프로젝트 관리는 서로 연관관계를 가지기에 하나를 수정하면 다른 것도 같이 수정해야한다.</p>
<h3 id="프로젝트-견적">프로젝트 견적</h3>
<p><strong>시간과 노력의 가치에 값을 매겨 예상 값어치를 산정하는 과정</strong>이다. 프로젝트에서 사용한 방법론, 경험이 있는 개발자, 실제 이전 프로젝트를 측정하며, 이를 통해서 예상 값어치를 산정한다. 처음에는 단순 범위의 수준으로 러프하게 매겨지다 <strong>프로젝트가 진행되고 구체화함에 따라 견적 또한 더욱 상세하고 두터워진다.</strong></p>
<h3 id="기능-점수function-point">기능 점수(Function Point)</h3>
<p>프로젝트가 승인되고 본격적인 계획을 들어가면 PM은 프로젝트의 규모, 비용, 개발 소요기간을 최대한 정확하게 예측해야한다. 이전에는 개발자의 경험에 의존해 되는대로 예측하기도 하였으나, 1979년 IBM의 Allen Albrecht가 Function Point라는 기능을 고안한 이후에는 이 방법을 적극 사용하여 객체적이고 정량적인 방식으로 산정한다.</p>
<p>이 기법은 5가지의 핵심 기능을 분해해 개수와 복잡도를 측정한다.</p>
<ul>
<li><strong>Input</strong> : 사용자가 시스템으로 데이터를 집어넣는 기능을 말한다.</li>
<li><strong>Output</strong> : 시스템이 데이터를 가공해 사용자에게 결과물로 보여주는 기능을 말한다.</li>
<li><strong>Query</strong> : DB의 정보를 검색과 조회를 통해 화면에 Display한다.</li>
<li><strong>File</strong> : 시스템 내부에서 자체적으로 유지, 관리하는 논리적 데이터 집합이다.</li>
<li><strong>Program Interface</strong> : 외부 다른 시스템과의 통신을 위해 필요한 게이트를 말한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/06668dd9-d6bc-4d5f-b9ff-8ef693461c71/image.png" alt=""></p>
<p>Function Point를 계산하는 데 몇 가지 절차가 존재하는데, 아래의 그림들을 중심으로 그. 흐름을 파악해 볼 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/1f224168-10b5-4581-93a7-2b995ebe9bdc/image.png" alt="">Function Point 측정</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/6097fa25-310d-4d33-8525-800867e094a2/image.png" alt="">1. Function Point 계산</th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/a6e0fdd1-a889-4590-8b5f-72b1ab39e07a/image.png" alt=""> 1-(1). Function Point 적용</th>
</tr>
</thead>
</table>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/7b3f8ae1-784d-4504-b3e0-de604a06bb04/image.png" alt=""> 2. 소요 인력 산정</th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/9a4f99c6-8027-487e-9c3f-bc76a8b76224/image.png" alt=""> 3.Schedule Time 계산</th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/woong_crouch/post/c973e22a-23b5-48fb-a6cc-eec73181fa23/image.png" alt=""></td>
<td></td>
</tr>
</tbody></table>
<h2 id="use-case">Use Case</h2>
<h3 id="use-case-diagram">Use Case Diagram</h3>
<p>Use Case는 여러 시나리오를 포함하는 기능을 말하고, Actor는 외부 에이전트가 수행하는 역할이다. 인간이나 하드웨어 등의 내용이 수행하며, 이러한 Actor와 Use Case 사이의 흐름을 작성한 문서로 보면 된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/16c40fac-55cd-4e10-9ead-afc1463c6e44/image.png" alt=""></p>
<h3 id="use-case-estimation">Use Case Estimation</h3>
<p>Use Case를 측정하는 과정을 가진다.</p>
<ul>
<li><p><strong>Unadjusted Use-Case Points(UUCP)</strong>
Actor 가중치 (1~3) / Use Case 가중치 (5,10,15)
<img src="https://velog.velcdn.com/images/woong_crouch/post/a79187e1-bb5d-4029-b826-202cc1d1b9ca/image.png" alt=""></p>
</li>
<li><p><strong>Technical Complexity Factor(TCF) : 13 factors</strong>
TCF = 0.6 + (0.01 * TFactor)
<img src="https://velog.velcdn.com/images/woong_crouch/post/7011a9a1-4a1e-4613-b7b9-8361415d04bf/image.png" alt=""></p>
</li>
<li><p><strong>Environmental Factors(EF) : 8 factors</strong>
EF = 1.4 + (-0.03 * EFactor)</p>
</li>
<li><p><strong>Adjusted Use Case Point(UCP)</strong>
UCP = UUCP * TCF * EF</p>
</li>
<li><p><strong>Effort in Person-hours = UCP * 계수(20 or 28)</strong></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/ef538f98-6c6e-4e28-bbe7-27585d07fed1/image.png" alt=""></p>
<h1 id="creating-and-managing-the-work-plan">Creating And Managing The Work Plan</h1>
<h3 id="업무-식별">업무 식별</h3>
<p>프로젝트에 필요한 업무를 식별할 때는, 주로 방법론에서 제공하는 표준 업무 목록을 참고하거나 &quot;하향식 접근법(Top-Down)&quot;을 사용한다. 높은 레벨의 업무를 식별하고 그것을 더 작은 단위로 나눈 뒤에, 이렇게 쪼개진 업무들을 계층적으로 구조화한 것을 작업 분할 구조도(Work Breakdown Structure, WBS)라고 한다.</p>
<p>업무 식별 단계에서 업무를 누락하게 되면, 이후에 특정 팀원들에게 갑작스럽게 과중한 업무가 배정되어 불만이 쌓이고, 최악의 경우 인력 이탈이나 프로젝트의 실패로 이어질 수 있다. 고로 PM은 업무를 빠짐없이 도출하고, 공정하게 로드 밸런싱(Load Balancing) 해주는 것이 매우 중요하다.</p>
<h3 id="project-workplan">Project Workplan</h3>
<p>WBS를 바탕으로 도출된 모든 업무 목록을 모아 전체적인 작업 계획을 작성하는 것을 말하고, 아래의 내용들이 명시되어야 한다.
– 작업명
– 작업 기간
– 현재 작업 상태
– 작업 간 종속 관계
– 마일스톤 (날짜)</p>
<h3 id="tracking-project-tasks">Tracking Project Tasks</h3>
<p>작업 계획이 수립되면, PM은 일정이 계획대로 진행되는지 시각적으로 모니터링하고 관리해야한다. 이때 주로 2가지의 차트를 사용하는데, 각각 Gantt Chart, PERT Chart이다.</p>
<ul>
<li><strong>Gantt Chart</strong> : 막대 차트 형식으로, 프로젝트 진행상황을 언제든 파악하기에 용이하다.</li>
<li><strong>PERT Chart</strong> : 플로우 차트 형식으로, 주요 경로와 작업 의존도를 그리고 순서와 관계에 집중한 순서도이다,</li>
</ul>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/d06cf897-15d2-4e93-a5d0-061cdb74031f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/d06cf897-15d2-4e93-a5d0-061cdb74031f/image.png" alt=""></p>
<h2 id="refining-estimates">Refining Estimates</h2>
<h3 id="hurricane-model">Hurricane Model</h3>
<p>불확실성의 원뿔을 <strong>허리케인 모델로 시각화한 그래프</strong>로, <strong>가로축은 프로젝트의 진행 단계를 순차로 배치</strong>하고 <strong>세로축에는 소요 시간을 중심으로 구성</strong>한다. 이 때, <strong>점선은 오차범위</strong>를 의미하고 <strong>원의 크기는 해당 시점에 예상되는 프로젝트 cost</strong>를 말한다.</p>
<p>프로젝트의 진행 순서는 아래와 같이 정의하고, 각각의 레벨은 특징과 상태를 지닌다. </p>
<p><strong>Level 1 : 초기</strong>
초기에는 표준화된 프로세스가 거의 존재하지 않으며, 성공이 개발자 1~2명의 역량에 달린다. 그 사람이 나가면 프로젝트가 무너질 가능성이 급격히 높아진다.</p>
<p><strong>Level 2 : 관리</strong>
프로젝트 단위로 일정한 규칙을 마련하는 시점이고, 계획을 세우고 일정과 비용을 관리하기 시작한다. 예전과 비슷한 프로젝트를 해낼 수 있는 지점이기도 하다.</p>
<p><strong>Level 3 : 정의</strong>
회사(조직) 전체의 표준 프로세스가 확립된다. 이 시기를 기점으로 정확한 공통 가이드라인이 적용되고, 모든 팀이 메뉴얼에 따라 행동한다.</p>
<p><strong>Level 4 : 정량적 관리</strong>
데이터와 숫자로 프로세스를 관리하며, 수치를 중심으로한 대화를 주고 받는다. 이로 인해 명확한 수치를 향상시키는 것을 목표로 하기에 결과 예측의 정확도가 향상한다.</p>
<p><strong>Level 5 : 최적화</strong>
지속적인 개선과 혁신을 하는 시기로, 완성된 제품이 이미 완벽에 가까울 정도로 궤도에 올랐으나, 신기술을 도입하거나 데이터를 분석해 끊임없이 업그레이드를 하는 시기이다.</p>
<h2 id="managing-scope">Managing Scope</h2>
<h3 id="scope-creep">Scope creep</h3>
<p>Scope Creep은 프로젝트가 진행되는 도중에 새로운 요구사항이 계속해서 추가되면서, 결과적으로처음에 정했던 프로젝트의 범위(Scope)가 점점 늘어나는 현상이다. 이는 두 가지 관점을 가지는데, 일정 지연(Schedule overrun)과 예산 초과(Cose overrun)가 발생한다.</p>
<p>또한 주로 사용자가 요구사항을 늘리면 발생하게 되고, 초기예측의 불완전성을 인정하고 관리해야한다. 실제로 System Request에 비해 실제 비용은 4배(400%)까지도 차이가 발생할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/woong_crouch/post/16a8a36f-c13f-4d8b-b5dd-c348e28a7ebc/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SW Engineering & Testing (1) - Introduction]]></title>
            <link>https://velog.io/@woong_crouch/SW-Engineering-Testing-1</link>
            <guid>https://velog.io/@woong_crouch/SW-Engineering-Testing-1</guid>
            <pubDate>Wed, 18 Mar 2026 00:25:21 GMT</pubDate>
            <description><![CDATA[<h1 id="introduction">Introduction</h1>
<p>SW Engineering을 알아보기 전에, Software에 대해서 알아보자. </p>
<p>우리가 건물을 바라볼 때, 여러 관점의 사람들과 이해관계자들이 접근하게 된다. 시공자, 거주자, 설계사, 인부 등에 따라 그 건물을 바라보는 시야가 달라진다. SW도 마찬가지다. 디자이너, 개발자, 사용자, 매니저 등 여러 이해관계자의 상황에 따라 다른 관점을 가지게 된다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/8c26b0df-5f1c-487c-8298-829f1fd797d6/image.png" alt=""></p>
<p>SW란 무엇일까. 소프트웨어란 사전적 의미로 <strong>접근하면 프로그램과 프로그램의 개발, 운용, 수정 및 기능 확정을 위해 필요한 모든 정보</strong>를 말한다. 소프트웨어는 어찌보면 프로그램의 동적인 의미로 볼 수 있다. 운영체제 관점에서는 Process와도 상통하는 개념이라고 볼 수 있다.</p>
<p>이러한 SW가 가지는 특성으로는 첫째로 <em><strong>비가시성</strong>_을 가진다. 비가시성이란 무형적인 특성을 가지고 구조가 코드 속에 내제된 상태로 구현된다. 둘째로 _<strong>복잡성</strong>_을 가진다. 복잡성이란 개념을 코드로 구현한 것 자체는 복잡하고 난해한 상태를 말한다. 추가로 요구나 환경 변화에 대한 **_변경 가능성, 복제 가능성, 테스팅의 어려움 등</em>**의 특성을 가진다.</p>
<h2 id="소프트웨어-유형">소프트웨어 유형</h2>
<h3 id="소프트웨어의-분류-체계">소프트웨어의 분류 체계</h3>
<p>SW는 아래와 같은 분류 체계를 가진다.</p>
<ul>
<li><strong>기능</strong><ul>
<li>시스템 소프트웨어 : <strong>하드웨어를 직접 관리하고 원활하게 실행하는 기반을 제공</strong>한다.</li>
<li>응용 소프트웨어 : <strong>특정 목적을 위해 직접 사용하는 프로그램</strong>을 말한다.<br></li>
</ul>
</li>
<li><strong>개발 과정</strong> : reusable, newly-built, modification, porting 등이 존재한다.<br></li>
<li><strong>신뢰도</strong><ul>
<li>critical : 오류 발생 시, <strong>심각한 문제를 초래할 수 있어</strong> 신뢰성을 요하는 시스템을 말한다.</li>
<li>non-critical : 오류 발생시 불편할 수 있으나 <strong>심각한 문제가 발생하지 않는</strong> 시스템이다.<br></li>
</ul>
</li>
<li><strong>소프트웨어 크기</strong> : 규모에 따라 두 가지로 나뉜다.<ul>
<li>programming-in-the-small : <strong>규모가 작아 소수의 개발자가 단기간에 완성</strong>할 수 있는 것을 이야기하며, 개발자의 역량이 큰 영향을 준다.</li>
<li>programming-in-the-large : <strong>장기간 개발하는 대규모 프로젝트</strong>이다. 이 때는 방법론을 적절하게 적용해야한다.<br></li>
</ul>
</li>
<li>*<em>데이터 특성 *</em>: 그래픽이나 이미지, 텍스트 등의 특성을 이야기한다.</li>
</ul>
<h3 id="정보-시스템-information-system">정보 시스템 (Information System)</h3>
<p><strong>대량의 데이터의 분류, 저장, 검색에 관심을 두는 시스템</strong>으로 GUI 기반의 서비스 인터페이스를 제공한다.</p>
<p>정보 시스템의 특성을 몇 가지 알아보자면 이 시스템의 경우 문서가 중요한 요소로 작용하고, 개발이나 유지보수가 많은 노력과 비용이 발생한다. <strong>데이터 설계는 비중이 큰 반면 제어구조는 비교적 간단하다</strong>는 특징도 가지고 있다.</p>
<p>우리가 흔히 볼 수 있는 쇼핑몰 사이트나 이런 대형 사이트들이 이런 정보 시스템의 예시가 될 수 있다.</p>
<h3 id="내포-시스템-embedded-system">내포 시스템 (Embedded System)</h3>
<p>임베디드 시스템은 컴퓨터의 연산이 주 목적이 아니라 더 큰 기계나 시스템의 내부에 포함되어 제어 기능을 수행하는 소프트웨어를 말한다. 우리가 요즘에는 흔히 자동차나 냉장고 등의 전자 기기 내에 들어가는 형태로 주로 볼 수 있다.</p>
<p>특징으로는 시스템의 규모가 크고 수명이 긴 편이며, <strong>실시간 응답성</strong>이 필수적으로 접목되어야한다. 또한 오류나 장애가 발생해도 치명적인 사고를 방지할 수 있어야 한다. 마지막으로 <strong>비동기성</strong>이 특징인데 여기서 비동기성이란 작업의 완료를 기다리지 않고 바로 다음 작업을 실행하는 것을 말한다.</p>
<h2 id="소프트웨어와-관련된-사담">소프트웨어와 관련된 사담</h2>
<h4 id="질문-1-소프트웨어-시스템을-개발하는-데-드는-비용-중-프로그래밍에-드는-비용은-어느정도일까">질문 1. 소프트웨어 시스템을 개발하는 데 드는 비용 중 프로그래밍에 드는 비용은 어느정도일까?</h4>
<p>소프트웨어 시스템을 개발하는 데 드는 비용 중에 <strong>프로그래밍에 드는 비용은 20% 정도</strong>이다. 이외의 비용은 테스팅과 요구분석 및 설계가 각각 40%씩 나눠 가진다. <del>물론 모든 프로젝트가 이 추이를 따라가는 것은 아니고 전반적인 이야기이다.</del></p>
<h4 id="질문-2-사용자에게-배달되는-소프트웨어의-실행코드-1000줄-당-예상-오류의-개수는-몇-개일까">질문 2. 사용자에게 배달되는 소프트웨어의 실행코드 1000줄 당 예상 오류의 개수는 몇 개일까?</h4>
<p>보편적으로 <strong>4개 미만</strong>이라고 한다. 이는 개발 과정에서 50~60개의 오류가 발생하고 이를 보완해 사용자에게 제공되기에 현저히 떨어진 수치로 보여진다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/34f1e544-e236-4e6f-81a7-9cbdb01df1de/image.png" alt=""></p>
<h4 id="질문-3-사용자가-발견하는-시스템의-오류-중-가장-발견하기-어려운-것은-어느것일까">질문 3. 사용자가 발견하는 시스템의 오류 중 가장 발견하기 어려운 것은 어느것일까?</h4>
<p>이 질문에 대한 답은 <strong>&quot;제안서와 사용자 요구사항에 대한 잘못된 이해&quot;</strong>이다. 오류가 빠르게 발견되어 요구사항 분석 시점에 가까이 발견될수록 비용이 저렴하고 유지보수 이후로 넘어갈수록 비용이 급격하게 올라간다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/12a30382-629d-49cc-8eaf-549a261d5468/image.png" alt=""></p>
<h4 id="질문-4-소프트웨어-시스템을-유지-보수하는-데-드는-비용이-개발-비용의-몇배일까">질문 4. 소프트웨어 시스템을 유지 보수하는 데 드는 비용이 개발 비용의 몇배일까?</h4>
<p>소프트웨어 시스템을 유지 보수하는데 드는 비용은 <strong>개발 비용의 2배 가량</strong> 드는 것을 알 수 있다. 이는 제품이 얼마나 체계적으로 만들어졌는지에 따라 반비례적인 추세를 가진다. 또한 처음에 다룬 질문 1번의 내용인 비용 문제에 대한 내용과도 일부 상통하는 내용이라고 볼 수 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/dc65fe3c-7570-4897-b73f-490885f49dca/image.png" alt=""></p>
<h2 id="소프트웨어에-대한-오해">소프트웨어에 대한 오해</h2>
<p>소프트웨어에 대한 오해는 관점에 따라서 관리자, 그리고 고객과 엔지니어의 오해로 나눌 수 있다. <strong>&quot;이정도는 해줄 수 있는거 아닌가?&quot;</strong>라는 이해관계의 문제가 중심이다. 그로 인해 이해관계자들의 상황에 맞게 서로 오해의 상황이 발생한다.</p>
<h3 id="관리자의-오해">관리자의 오해</h3>
<p>관리자들은 주로 _<strong>도구, 인력, 표준화된 프로세스만 갖춰지면 프로젝트가 기계적으로 통제될 수 있다는 착각을 하는 경향</strong>_이 있다. 쉽게 말해서 자원과 틀만 제공이 되면 프로젝트가 잘 이루어질 것이라는 일종의 믿음을 가진다는 의미이다.</p>
<p>&quot;우리가 이정도 자원을 제공했으니 그들은 충분히 우리가 원하는 결과물을 만들 것이다&quot;라거나 &quot;엔지니어라면 엔지니어링에 중심을 둬야지 요구분석을 하는 것은 좋지 않다&quot;, &quot;공정이 지연되면 인력을 투입하는 방식으로 해결할 수 있다&quot; 등의 생각들이 그들이 쉽게 생각하는 오해이다.</p>
<p>자원을 제공했을 때 그에 상응하는 output이 나오기를 바라고 그러리라 믿는 경향이 있는 것이 관리자의 특징이다. 이에 따라 위와 같이 상호간의 오해가 생기기도 한다.</p>
<h3 id="고객의-오해">고객의 오해</h3>
<p>고객은 _<strong>소프트웨어의 유연성을 과대평가하여 초기에 요구사항을 명확히 하지 않아도 나중에 고칠 수 있을 것</strong>_이라 생각한다. 하지만 이 생각은 착각이고, 이후에 수정을 하는 것이 더 힘든 상황이 발생하고 설령 가능하더라도 코드가 난잡해지는 등의 문제가 발생할 가능성이 높다.</p>
<p>흔히 고객이 생각하는 방향을 예로 들자면 &quot;목표에 대한 기술만 대충 적어두면 SW를 만드는데 충분하고 세부적인건 나중에 채우면 된다&quot; 나, &quot;요구사항은 계속 변하고 이를 소프트웨어는 쉽게 수용할 수 있어야한다.&quot;는 생각을 하기 쉽다.</p>
<h3 id="엔지니어의-오해">엔지니어의 오해</h3>
<p>그럼 마지막으로 엔지니어의 오해를 알아보자. <em><strong>개발자는 코딩과 실행결과에 치중되게 생각을 하는 경향이 있다.</strong></em> 그래서 기능을 만들고 생성하는 것을 중점을 두고 유지보수를 위한 문서화나 설계에서의 품질 검증이 쉽게 넘어가곤 한다.</p>
<p>예를 들자면 &quot;프로그램이 만들어지고 작동하면 할 일을 다 한 것이다&quot; 또는 &quot;시스템을 작동시켜 보기 전까지는 품질을 평가할 방법이 없다&quot;, &quot;프로젝트의 결과는 작동하는 프로그램일 뿐이다&quot; 등의 오해를 할 수 있다.</p>
<h1 id="소프트웨어-공학">소프트웨어 공학</h1>
<h2 id="소프트웨어의-위기">소프트웨어의 위기</h2>
<p>소프트웨어를 개발할 때는 많은 문제들이 발생할 수 있다.</p>
<ul>
<li>예산 초과</li>
<li>개발 일정 지연</li>
<li>불충분한 성능</li>
<li>신뢰하기 어려운 품질</li>
<li>유지 보수의 어려움</li>
<li>막대한 유지보수 비용</li>
</ul>
<p>등이 있다. 물론 이보다 훨씬 많은 문제들이 개발이나 설계, 유지보수 과정에서 발생한다. 이 때 우리가 주의깊게 볼 위기는 <strong>하드웨어의 급속한 발전과 컴퓨터의 대중화로 SW의 수요가 급증한다</strong>는 배경을 두고 심화된다.</p>
<p>현재 대부분의 빅테크가 SW 기업인 것을 감안하면 이 사실에 대해 짐작할 수 있다. 하지만 문제는 여기서 발생한다. 소프트웨어 생산성과 생산 기술은 그에 미치지 못하는 상황이 발생한다.</p>
<h2 id="소프트웨어-공학이란-">소프트웨어 공학이란 ?</h2>
<p>소프트웨어 공학이란 <strong>품질 좋은 소프트웨어를 최소의 비용으로 계획된 일정에 맞추어 개발하기 위하여 여러가지 공학적 원리와 방법을 체계적으로 적용하는 것</strong>을 말한다. 한마디로 &quot;일정에 맞게 개발하기 위해 방법론을 적용하여 좋은 퀄리티의 소프트웨어를 제작하는 공정&quot;이다.</p>
<h2 id="소프트웨어-공학의-역사">소프트웨어 공학의 역사</h2>
<p>소프트웨어의 위기로부터 이어진 소프트웨어 공학의 역사에 대해서 알아보자. 우선 이 이야기를 하려면 1970년대부터 시작해야한다.</p>
<h3 id="1970">~1970</h3>
<p>이 시기까지 소프트웨어의 위기가 인식되기 시작하고 이를 해결하기 위해 소프트웨어 공학이 탄생한다. <strong>고급 언어가 발생하고, interactive한 프로그래밍</strong>이 생기기 시작한다. 이 때 goto 논쟁이라는 것도 발생하는데, 이는 스파게티 코드를 지양하고 논리적 흐름을 강조하는 &quot;구조적 프로그래밍&quot;이 중요하다는 것이 대두되는 기점이 된다.</p>
<h3 id="1980">~1980</h3>
<p>이제 본격적으로 소프트웨어 위기로부터의 해결책을 모색하기 시작한다. <strong>소프트웨어 공학이라는 분야가 학문적으로 정착하기 시작했고, 하드웨어로부터 독립된 개념의 소프트웨어가 점점 발생</strong>하기 시작한다. 이 때 아래와 같은 개념들이 생기기 시작했다.</p>
<ul>
<li>소프트웨어 생명주기</li>
<li>대규모 프로그래밍</li>
<li>방법론 및 도구</li>
<li>정보 은닉</li>
<li>구조적 설계</li>
</ul>
<h3 id="present">~Present</h3>
<p>80년대에 본격적으로 거론되기 시작한 해결책들은 오늘날까지 여러 방식으로 진화와 발전을 거듭해왔다. 기존의 구조적 프로그래밍의 중심을 벗어나 <strong>객체 지향 프로그래밍(방법론)이 흐름의 중심</strong>으로 다가서고, 그로인해서 재사용, 디자인 패턴, 소프트웨어 컴포넌트/설계 등의 개념들이 추가적으로 도입되기 시작한다.</p>
<h2 id="소프트웨어-공학의-크기-체계">소프트웨어 공학의 크기 체계</h2>
<p>일전에 소프트웨어 공학의 분류 체계를 하면서 나온 개념이긴 하지만 더 세세하게 개념에 대해서 알아보도록 하자.</p>
<h3 id="1-programming-in-the-small">1. Programming-in-the-Small</h3>
<p>규모가 작은 프로그램을 말하며 프로그램의 규모 자체가 작기 때문에 <strong>명확하게 정의가 가능하고 그 문제들을 집중적으로 해결하는 방식</strong>이다. 이러한 경우엔 정확하게 개발하는 것이 중요하고, 명세가 잘 변경되지 않는 특성을 가진다.</p>
<h3 id="2-programming-in-the-large">2. Programming-in-the-Large</h3>
<p>우리가 주로 마주하는 프로그램의 크기는 이 형태를 가진다. 규모가 커지게 되면서 개인의 코딩 실력이 중요한 것이 아니라 <strong>시스템 전체의 구조와 관리가 중요한 방식</strong>이다. 규모가 큰 만큼 해결할 문제를 정확하게 정의해야하고, 아무래도 크기가 크다보니 요구사항을 초기에 정한대로 흘러가지 않는 경우가 많다. 이런 경우를 고려한 상태로 대응책을 마련해야한다.</p>
<p>또한 시스템을 구성하는 컴포넌트들 사이의 인터페이스를 명확하게 설계해야하고 시스템 통합과 테스팅 과정이 필요하다. <strong>규모가 크다보니 협업이 여기서부터는 매우 중요하게 여겨지는데</strong>, 변경사항을 체계적으로 관리하는 git과 같은 툴이 적용되어야하고 지속적으로 문서, 유지보수 등을 수정하고 작업하며 탄탄히 나아가야한다.</p>
<h3 id="3-programming-in-the-many">3. Programming-in-the-Many</h3>
<p>프로그램의 크기도 크기지만 인원에 중심을 둔 프로그래밍이다. 팀 단위로 무언가를 구축할 때, 주로 마주하는 문제들을 다루고 팀원 간의 정보 교환 등의 커뮤니케이션을 진행해야한다. <strong>작업을 적당하게 할당해야하고, 표준화를 통해서 팀원들간의 문서 및 개발 성향을 조정할 필요가 있다.</strong> 결국 이 시점에 PM(Project Management)의 역량이 중요해진다.</p>
<p>사실상 Many의 경우는 Large인 프로그램에서는 필연적으로 필요한 상황이 발생하고, 규모가 크면 사람이 많아야하고 그에 따라서 2번과 3번은 유기적으로 이어질 가능성이 매우 높다.</p>
<h2 id="소프트웨어-테스팅">소프트웨어 테스팅</h2>
<h3 id="구현과-테스팅">구현과 테스팅</h3>
<p>그림 1을 통해서 <strong>프로젝트의 규모가 클수록 구현과 테스트의 비중이 줄어든다는 사실</strong>을 알 수 있고, 프로젝트에서의 구현 오류의 비중이 높은 경우를 그림2를 통해 확인할 수 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/e12b189a-c244-4d0f-ba56-e2ff2f28ea7d/image.png" alt="">
<strong>SW 코드 검증 방법과 소스코드 검증 기법</strong>은 아래와 같다.</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/a423542b-7ace-4709-8cab-870b972bf082/image.png" alt=""><fiction>SW 코드 검증 방법</fiction></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/ae6e3e3d-2249-4084-8ca7-4082ea1ae792/image.png" alt=""><fiction>소스코드 검증 방법</fiction></th>
</tr>
</thead>
</table>
<h3 id="다양한-테스트-기법들의-오류-감지율">다양한 테스트 기법들의 오류 감지율</h3>
<p>오류 감지를 위한 여러 테스트 기법들이 존재하는데, 그 리스트를 보면 아래와 같다. 하나의 방법이 평균 75%를 넘는 경우가 없고, 그로 인해 다양한 방법을 병행으로 사용해야 효과를 볼 수 있다는 특징이 있다.
<img src="https://velog.velcdn.com/images/woong_crouch/post/a5894e16-a9bc-4239-97bf-177a6936abab/image.png" alt=""></p>
<h3 id="v-model">V-Model</h3>
<p>테스팅을 할 때, 우리는 V 모델을 자주 사용한다. <strong>V 모델은 확인 절차가 왼쪽과 오른쪽 두 개로 나뉘고, V자 모양으로 움직일 때 아래의 순차적인 절차를 따라 움직인다.</strong></p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/e3c9ac6e-70ac-4c58-8c62-f52f716fa5d2/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/woong_crouch/post/e5e7493f-c8e7-41e0-990c-cccc3d433e9a/image.png" alt=""></th>
</tr>
</thead>
<tbody><tr>
<td><strong>왼쪽(Architecture Design)</strong></td>
<td></td>
</tr>
<tr>
<td>1. 요구사항 분석 : 고객이 무엇을 원하는지 요구사항을 정리한다.</td>
<td></td>
</tr>
<tr>
<td>2. 시스템 셀계: 전체 시스템의 하드웨어, 소프트웨어 구조를 기획하는 과정이다.</td>
<td></td>
</tr>
<tr>
<td>3. 아키텍처 설계 : 시스템을 구성하는 여러 모듈(기능) 간의 관계와 구조를 설계한다.</td>
<td></td>
</tr>
<tr>
<td>4. 모듈 상세 설계 : 각 모듈 내부의 구체적인 로직이나 알고리즘, 데이터 구조 등을 상세히 설계한다.</td>
<td></td>
</tr>
</tbody></table>
<p><strong>중간(Coding)</strong>
5. 코딩 : 말 그대로 프로그램을 구현하는 절차를 말한다.</p>
<p><strong>오른쪽(Testing)</strong>
6. 단위 테스트 : 개발자가 작성한 개별 함수나 클래스가 의도대로 작동하는지 테스트한다.
7. 통합 테스트 : 각각 만들어진 모듈을 연결하면 데이터가 잘 넘어가고 충돌 없이 작동하는지 테스트한다.
8. 시스템 테스트 : 완성된 전체 시스템이 정상적으로 작동하는지, 성능은 잘 나오는지 테스트한다.
9. 인수 테스트 : 최종 고객이 요구사항대로 완성되었는지 직접 사용해보며 승인하는 테스트이다.
10. 설치 테스트 : 최종 사용자의 실제 운영 환경에 소프트웨어가 문제없이 설치 및 구동되는지 테스트한다.</p>
<br>

<p>이번 포스트에서는 <strong>SW Engineering 과 Testing을 위한 개요</strong>를 알아보았다. </p>
]]></description>
        </item>
    </channel>
</rss>