객체지향 분석
객체지향
특정 기능을 수행하기 위한 데이터와 데이터를 사용하는 연산을 하나로 묶어 객체로 표현하는 접근 방법
클래스와 오브젝트
클래스는 실세계의 사물을 정의하기 위한 틀을 제공한다.
클래스로부터 생성되는 인스턴스가 객체(오브젝트)이다.
객체는 클래스 하나에서 여러 개가 생성될 수 있으며, 실제 연산에 사용된다.
캡슐화와 정보 은닉
클래스는 속성과 연산으로 정의,포장된다.
이렇게 포장하는 것을 캡슐화라고 한다.
캡슐화로 인해 클래스의 속성과 연산이 감춰진다.
필요한 최소한의 정보만 외부에 공개된다.
상속
구체 클래스들의 공동 속성과 공통 연산을 뽑아내어 추상 클래스로 선언한다.
추상 클래스에 정의된 속성은 구체 클래스에서 정의하지 않고 추상 클래스로부터 상속받는다.
다형성
클래스에 정의된 요소들은 실제 클래스의 오브젝트가 사용되는 시점에 행위가 결정된다.
동일한 속성과 연산이 클래스에 중복적으로 정의될 수 있다.
어떤 시점에서 어떤 객체에 사용되는가에 따라 서로 다른 행위를 가진다.
UML (통합 모델링 언어)
다이어그램을 표현하기 위한 기본 모델 요소를 표준적으로 정의한 것이다.
소프트웨어 개발 생명주기 단계별 다이어그램
분석 단계 : 유스케이스 (다이어그램), 클래스, 프로파일, 순차, 오브젝트, 액티비티, 인터랙션, 상태기계
설계 단계 : 패키지 (다이어그램), 타이밍, 순차 (메소드 명세), 배치
기능 모델링
기능 모델링
소프트웨어 분석을 위한 첫 번째 활동이다.
사용자로부터 도출한 요구사항을 받아 소프트웨어 시스템이 해야 할 기능이 무엇인지 식별하는 과정이다.
UML의 유스케이스 다이어그램을 이용해 분석 결과를 표현한다.
요구사항에 대한 이해가 부족한 경우 비즈니스 프로세서 모델링(BPM)을 액티비티 다이어그램 이용해 수행한다.
유스케이스 다이어그램
시간에 따라 변하지 않는 시스템의 정적인 면을 보여주는 대표적인 UML 다이어그램이다.
시스템의 일부 또는 전체의 구조를 나타낼 수 있다.
의존 관계를 명확히 보게 해준다.
일반화 관계 : 한 클래스가 다른 클래스의 구조와 행위를 공유하는 관계 표현
종속성 관계 : 한 클래스가 다른 클래스를 사용하는 관계를 표현
액터
외부에 존재하는 개발 대상 시스템과 상호작용하는 모든 대상을 식별한다.
유스케이스는 최초에 액터에 의해 시작되어야 한다.
구조 모델링
구조 모델링
개발 대상 소프트웨어가 어떤 구조적 요소들로 이루어질 수 있는지 분석하는 것이다.
UML의 클래스 다이어그램으로 표현한다.
설계 단계에서 사용한다.
객체 식별
구조 모델링의 첫 번째 작업이다.
UML에서 정의하는 클래스는 클래스명, 클래스속성, 클래스연산 3요소로 구성된다.
클래스 간 어떤 상관관계가 있는가 클래스의 관계로 나타낸다.
식별 방식 : 문장 분석, 일반 객체 목록, 브레인스토밍, 패턴 적용
클래스 명세
CRC카드를 이용하여 작성한다.
CRC카드의 앞면과 뒷면에 클래스 정보를 명세한다.
앞면에는 대체로 클래스에 대한 기본 정보를 표현한다.
뒷면에는 클래스의 속성과 연산을 정의한다.
클래스 다이어그램 작성
식별된 모든 클래스를 CRC 카드에 명세한 후에 클래스 다이어그램을 작성한다.
소프트웨어의 구조를 나타내는 정적 모델이다.
각 클래스가 갖는 속성, 연산을 다시 한 번 점검하고 정제한 후에 클래스 간의 관계를 부여한다.
기본적인 관계 유형
일반화 관계 : 식별된 클래스들을 추상화하여 보다 보편적인 클래스로 나타낸다.
집합 관계 : 구성 또는 조합 관계를 나타낸다.
연관 관계 : 두 클래스 간 관계가 일반화 관계와 집합 관계에 속하지 않을 경우
클래스 다이어그램에 표현되는 추가 정보
속성 가시성 : 클래스의 속성으로 정의되는 변수가 갖는 접근 범위이다.
관계 기수성 : 서로 연관을 맺은 두 클래스 간에 몇 개의 객체가 인스턴스가 발생할 수 있는가 나타내기 위해 사용한다.
행위 모델링
행위 모델링
시스템의 내적인 동작을 표현하는 다이어그램
객체 간의 상호작용, 즉 메시지 패싱에 대한 행위를 시간 축 중심으로 나타낸다.
UML의 동적 모델에 해당한다.
순차 다이어그램, 액티비티 다이어그램, 상태기계 다이어그램 등을 이용해 시스템의 동적 행위를 모델링한다.
순차 다이어그램 구성 요소
참여객체 : 참여객체 간 상호작용이 일반적으로 왼쪽에서 오른쪽으로 진행하도록 표현한다.
액터도 참여객체의 한 유형으로 고려될 수 있다.
시간 축 : 다이어그램의 세로축이다. 객체가 활성화된 시간을 점선으로 표시하는데, 객체의 라이프라인이라고 한다.
실행 사건 : 실행 동작이 발생하는 기간을 길쭉한 사각형으로 표현한다.
메시지 전달 : 객체 간의 함수 호출을 의미한다.
제어 로직 : 선택, 반복, 병렬처리 등의 소프트웨어의 행위를 표현한다.
다이어그램의 복잡도를 감소시키며, 이해도를 높이는 역할을 한다.
순차 다이어그램 작성
기능 모델링의 결과로 식별된 유스케이스별로 작성한다.
유스케이스의 개수와 순차 다이어그램의 개수는 일반적으로 동일하다.
상태기계 다이어그램 작성
시스템이 어느 한 상태에 존재하다가 이벤트가 발생하면 다른 상태로 전이하는 동작을 표현한다.
객체의 상태 변화를 표현한다.
분석 산출물 점검
일관성 점검
설계 과정에 들어가기 전, 분석 결과물에 대한 일관성 점검을 실시한다.
기능 모델과 구조 모델
기능 모델의 유스케이스 설명서와 CRC 카드 간의 일관성 점검
모든 클래스의 이름은 반드시 유스케이스 설명서의 어딘가에 나타나야한다.
기능 모델과 행위 모델
기능 모델의 유스케이스는 각각 하나의 순차 다이어그램으로 표현한다.
유스케이스 다이어그램의 액터는 순차 다이어그램의 액터로 나타나야 한다.
구조 모델과 행위 모델
상태기계 다이어그램은 클래스의 인스턴스와 매핑한다.
순차 다이어그램에서 객체 간에 전달되는 메시지는 반드시 클래스의 연산으로 정의되어야 한다.
모듈화
모듈화 추구
독립적인 기능이 있는 논리적 묶음에 해당하는 모듈로 소프트웨어 시스템을 구성할 수 있도록 개발한다는 것이다.
모듈화 장점
이해하기 쉬워지고 팀 단위의 개발 작업이 쉬워진다.
수정사항 반영이 쉬워지고 재사용 가능성이 높아진다.
추적성이 높아진다.
좋은 설계를 수행한 소프트웨어의 특성
설계가 계층적인 구조를 나타낸다.
설계 결과가 모듈로 구성되어야 한다.
데이터와 처리 절차가 구분 가능하고 분리된 표현으로 나타난다.
설계 결과가 독립적인 특성이 있는 기능 단위로 구현된다.
모듈을 구성하는 내적 요소 (변수, 함수, 연산 등) 가 상호 관련성이 있는 것들로 묶여야 한다.
결합력의 이해
결합력
모듈간의 의존성 관계이다.
결합력이 작을수록 좋은 설계이다.
모듈이 독립적인 기능을 갖도록 설계한다.
가능한 모듈 간 상호작용을 줄여야 한다.
모듈간의 결합력을 최소화 할 때 장점
시스템의 구성 요소 간에 결합이 느슨해진다.
변경에 의한 파동 효과를 막을 수 있다.
소프트웨어에 대한 이해도를 높인다.
모듈의 인터페이스가 단순해진다.
모듈 간 결합력 정도를 표현하는 유형 및 스케일
메시지 결합력
데이터 결합력
스탬프 결합력
제어 결합력
외부 결합력
공유 결합력
내용 결합력
(위로 갈수록 좋은 결합력, 아래로 갈수록 나쁜 결합력)
메시지 결합력 : 객체 간 상호작용은 메시지 전달이라는 한가지 개념에 의해서만 이루어진다.
데이터 결합력 : 2개의 모듈이 단순한 기본 데이터 타입을 갖는 변수들해 의해 상호작용하는 경우
외부 결합력 : 2개의 모듈이 외부에 존재하는 다른 정보를 공유하고 있다면 이 모듈은 외부 결합 관계에 있다고 정의
공유 결합력 : 2개의 모듈이 광역 변수를 공유하고 있다면 이 모듈은 공유 결합력 관계에 있다.
공유 변수 사용으로 메모리 사용량 줄이고 프로그램을 간단하게 작성할 수 있지만 모듈 간 의존성을 높이게 된다.
내용 결합력 : 한 모듈에서 다른 모듈의 내부를 직접 참조한다면 내용 결합 관계에 있다고 할 수 있다.
응집력의 이해
응집력
모듈을 구성하는 내적 요소 간의 기능적 관련성의 강도를 측정하는 척도이다.
모듈을 구성하는 내적 요소 : 변수, 함수, 연산 등
모듈의 응집력을 최대화하는 것을 목표로 한다.
모듈의 내적 요소 간 응집력 정도를 표현하는 유형 및 스케일
기능 응집력
순차 응집력
교환 응집력
절차 응집력 // 여기서부턴 쉽지 않은 유지보수
시간 응집력
논리 응집력
우연 응집력
(위로 갈수록 좋은 응집력, 아래로 갈수록 나쁜 응집력)
기능 응집력 : 모듈 구성하는 모든 요소가 오직 하나의 기능을 구현하기 위해 구성되었다면
기능 응집력이 있다고 정의한다.
ex) 수학의 코사인각 계산, 문장 알파벳 오류 체크 등
순차 응집력 : 모듈을 구성하는 문장 관계에서 한 문장의 실행 결과가 다음 문장의 입력으로 사용되는 경우
절차 응집력 : 모듈을 구성하는 문장들이 의미상 서로 관련이 없지만 제어 흐름의 순서가 있는 경우
시간 응집력 : 모듈을 구성하는 문장들이 소프트웨어 실행의 특정 시간과 관련이 있는것으로만 구성된 경우
ex) 데이터 사용 전 모든 변수 초기화 등
우연 응집력 : 가장 나쁜 형태의 응집력, 절대 작성되어서는 안되는 모듈 구성
모듈을 구성하는 모든 요소가 아무런 관련성이 없는 것으로 묶인 경우이다.
좋은 설계 : 결합력이 낮고 응집력은 높은 모듈 구성으로 이루어진 설계이다.
모듈화 응용 기술
모듈 간 결합력과 에너지 소모의 상관관계 실험

비교적 공유 결합력이 전력을 적게 소모하고 있음
데이터 양의 변화와 무관하게 거의 비슷한 전력 소모 패턴을 보인다.
모듈 간 결합력보다 데이터 처리 및 암호화를 위한 수학적 연산에 많은 에너지가 소모된다.
기술 부채
소프트웨어 시스템을 개발하는 과정에서 제대로 작업하지 않으면 추후 이자까지 붙은 빚이되어 돌아오기 때문에
더 많은 작업을 통해 이전의 올바르지 못한 결과를 바로잡아야 한다는 의미이다.
기술 부채의 개념이 잘 적용되는 기술 영역
소프트웨어 설계 단계에서 초기에 개발되는 소프트웨어 아키텍처
아키텍처 개발의 모든 부분에서 모듈하의 원리가 적용되어야 한다.
모듈화의 척도 관점에서 좋은 아키텍처일수록 결합력보다는 응집력에 더 집중해야 한다.
'전공 지식 정리 > 소프트웨어 공학' 카테고리의 다른 글
#6, #7 소프트웨어 공학 - 소프트웨어 비용 산정, 요구사항 도출 (0) | 2022.12.12 |
---|---|
#5 소프트웨어 공학 - 프로젝트 관리 (0) | 2022.11.25 |
객체지향 분석
객체지향
특정 기능을 수행하기 위한 데이터와 데이터를 사용하는 연산을 하나로 묶어 객체로 표현하는 접근 방법
클래스와 오브젝트
클래스는 실세계의 사물을 정의하기 위한 틀을 제공한다.
클래스로부터 생성되는 인스턴스가 객체(오브젝트)이다.
객체는 클래스 하나에서 여러 개가 생성될 수 있으며, 실제 연산에 사용된다.
캡슐화와 정보 은닉
클래스는 속성과 연산으로 정의,포장된다.
이렇게 포장하는 것을 캡슐화라고 한다.
캡슐화로 인해 클래스의 속성과 연산이 감춰진다.
필요한 최소한의 정보만 외부에 공개된다.
상속
구체 클래스들의 공동 속성과 공통 연산을 뽑아내어 추상 클래스로 선언한다.
추상 클래스에 정의된 속성은 구체 클래스에서 정의하지 않고 추상 클래스로부터 상속받는다.
다형성
클래스에 정의된 요소들은 실제 클래스의 오브젝트가 사용되는 시점에 행위가 결정된다.
동일한 속성과 연산이 클래스에 중복적으로 정의될 수 있다.
어떤 시점에서 어떤 객체에 사용되는가에 따라 서로 다른 행위를 가진다.
UML (통합 모델링 언어)
다이어그램을 표현하기 위한 기본 모델 요소를 표준적으로 정의한 것이다.
소프트웨어 개발 생명주기 단계별 다이어그램
분석 단계 : 유스케이스 (다이어그램), 클래스, 프로파일, 순차, 오브젝트, 액티비티, 인터랙션, 상태기계
설계 단계 : 패키지 (다이어그램), 타이밍, 순차 (메소드 명세), 배치
기능 모델링
기능 모델링
소프트웨어 분석을 위한 첫 번째 활동이다.
사용자로부터 도출한 요구사항을 받아 소프트웨어 시스템이 해야 할 기능이 무엇인지 식별하는 과정이다.
UML의 유스케이스 다이어그램을 이용해 분석 결과를 표현한다.
요구사항에 대한 이해가 부족한 경우 비즈니스 프로세서 모델링(BPM)을 액티비티 다이어그램 이용해 수행한다.
유스케이스 다이어그램
시간에 따라 변하지 않는 시스템의 정적인 면을 보여주는 대표적인 UML 다이어그램이다.
시스템의 일부 또는 전체의 구조를 나타낼 수 있다.
의존 관계를 명확히 보게 해준다.
일반화 관계 : 한 클래스가 다른 클래스의 구조와 행위를 공유하는 관계 표현
종속성 관계 : 한 클래스가 다른 클래스를 사용하는 관계를 표현
액터
외부에 존재하는 개발 대상 시스템과 상호작용하는 모든 대상을 식별한다.
유스케이스는 최초에 액터에 의해 시작되어야 한다.
구조 모델링
구조 모델링
개발 대상 소프트웨어가 어떤 구조적 요소들로 이루어질 수 있는지 분석하는 것이다.
UML의 클래스 다이어그램으로 표현한다.
설계 단계에서 사용한다.
객체 식별
구조 모델링의 첫 번째 작업이다.
UML에서 정의하는 클래스는 클래스명, 클래스속성, 클래스연산 3요소로 구성된다.
클래스 간 어떤 상관관계가 있는가 클래스의 관계로 나타낸다.
식별 방식 : 문장 분석, 일반 객체 목록, 브레인스토밍, 패턴 적용
클래스 명세
CRC카드를 이용하여 작성한다.
CRC카드의 앞면과 뒷면에 클래스 정보를 명세한다.
앞면에는 대체로 클래스에 대한 기본 정보를 표현한다.
뒷면에는 클래스의 속성과 연산을 정의한다.
클래스 다이어그램 작성
식별된 모든 클래스를 CRC 카드에 명세한 후에 클래스 다이어그램을 작성한다.
소프트웨어의 구조를 나타내는 정적 모델이다.
각 클래스가 갖는 속성, 연산을 다시 한 번 점검하고 정제한 후에 클래스 간의 관계를 부여한다.
기본적인 관계 유형
일반화 관계 : 식별된 클래스들을 추상화하여 보다 보편적인 클래스로 나타낸다.
집합 관계 : 구성 또는 조합 관계를 나타낸다.
연관 관계 : 두 클래스 간 관계가 일반화 관계와 집합 관계에 속하지 않을 경우
클래스 다이어그램에 표현되는 추가 정보
속성 가시성 : 클래스의 속성으로 정의되는 변수가 갖는 접근 범위이다.
관계 기수성 : 서로 연관을 맺은 두 클래스 간에 몇 개의 객체가 인스턴스가 발생할 수 있는가 나타내기 위해 사용한다.
행위 모델링
행위 모델링
시스템의 내적인 동작을 표현하는 다이어그램
객체 간의 상호작용, 즉 메시지 패싱에 대한 행위를 시간 축 중심으로 나타낸다.
UML의 동적 모델에 해당한다.
순차 다이어그램, 액티비티 다이어그램, 상태기계 다이어그램 등을 이용해 시스템의 동적 행위를 모델링한다.
순차 다이어그램 구성 요소
참여객체 : 참여객체 간 상호작용이 일반적으로 왼쪽에서 오른쪽으로 진행하도록 표현한다.
액터도 참여객체의 한 유형으로 고려될 수 있다.
시간 축 : 다이어그램의 세로축이다. 객체가 활성화된 시간을 점선으로 표시하는데, 객체의 라이프라인이라고 한다.
실행 사건 : 실행 동작이 발생하는 기간을 길쭉한 사각형으로 표현한다.
메시지 전달 : 객체 간의 함수 호출을 의미한다.
제어 로직 : 선택, 반복, 병렬처리 등의 소프트웨어의 행위를 표현한다.
다이어그램의 복잡도를 감소시키며, 이해도를 높이는 역할을 한다.
순차 다이어그램 작성
기능 모델링의 결과로 식별된 유스케이스별로 작성한다.
유스케이스의 개수와 순차 다이어그램의 개수는 일반적으로 동일하다.
상태기계 다이어그램 작성
시스템이 어느 한 상태에 존재하다가 이벤트가 발생하면 다른 상태로 전이하는 동작을 표현한다.
객체의 상태 변화를 표현한다.
분석 산출물 점검
일관성 점검
설계 과정에 들어가기 전, 분석 결과물에 대한 일관성 점검을 실시한다.
기능 모델과 구조 모델
기능 모델의 유스케이스 설명서와 CRC 카드 간의 일관성 점검
모든 클래스의 이름은 반드시 유스케이스 설명서의 어딘가에 나타나야한다.
기능 모델과 행위 모델
기능 모델의 유스케이스는 각각 하나의 순차 다이어그램으로 표현한다.
유스케이스 다이어그램의 액터는 순차 다이어그램의 액터로 나타나야 한다.
구조 모델과 행위 모델
상태기계 다이어그램은 클래스의 인스턴스와 매핑한다.
순차 다이어그램에서 객체 간에 전달되는 메시지는 반드시 클래스의 연산으로 정의되어야 한다.
모듈화
모듈화 추구
독립적인 기능이 있는 논리적 묶음에 해당하는 모듈로 소프트웨어 시스템을 구성할 수 있도록 개발한다는 것이다.
모듈화 장점
이해하기 쉬워지고 팀 단위의 개발 작업이 쉬워진다.
수정사항 반영이 쉬워지고 재사용 가능성이 높아진다.
추적성이 높아진다.
좋은 설계를 수행한 소프트웨어의 특성
설계가 계층적인 구조를 나타낸다.
설계 결과가 모듈로 구성되어야 한다.
데이터와 처리 절차가 구분 가능하고 분리된 표현으로 나타난다.
설계 결과가 독립적인 특성이 있는 기능 단위로 구현된다.
모듈을 구성하는 내적 요소 (변수, 함수, 연산 등) 가 상호 관련성이 있는 것들로 묶여야 한다.
결합력의 이해
결합력
모듈간의 의존성 관계이다.
결합력이 작을수록 좋은 설계이다.
모듈이 독립적인 기능을 갖도록 설계한다.
가능한 모듈 간 상호작용을 줄여야 한다.
모듈간의 결합력을 최소화 할 때 장점
시스템의 구성 요소 간에 결합이 느슨해진다.
변경에 의한 파동 효과를 막을 수 있다.
소프트웨어에 대한 이해도를 높인다.
모듈의 인터페이스가 단순해진다.
모듈 간 결합력 정도를 표현하는 유형 및 스케일
메시지 결합력
데이터 결합력
스탬프 결합력
제어 결합력
외부 결합력
공유 결합력
내용 결합력
(위로 갈수록 좋은 결합력, 아래로 갈수록 나쁜 결합력)
메시지 결합력 : 객체 간 상호작용은 메시지 전달이라는 한가지 개념에 의해서만 이루어진다.
데이터 결합력 : 2개의 모듈이 단순한 기본 데이터 타입을 갖는 변수들해 의해 상호작용하는 경우
외부 결합력 : 2개의 모듈이 외부에 존재하는 다른 정보를 공유하고 있다면 이 모듈은 외부 결합 관계에 있다고 정의
공유 결합력 : 2개의 모듈이 광역 변수를 공유하고 있다면 이 모듈은 공유 결합력 관계에 있다.
공유 변수 사용으로 메모리 사용량 줄이고 프로그램을 간단하게 작성할 수 있지만 모듈 간 의존성을 높이게 된다.
내용 결합력 : 한 모듈에서 다른 모듈의 내부를 직접 참조한다면 내용 결합 관계에 있다고 할 수 있다.
응집력의 이해
응집력
모듈을 구성하는 내적 요소 간의 기능적 관련성의 강도를 측정하는 척도이다.
모듈을 구성하는 내적 요소 : 변수, 함수, 연산 등
모듈의 응집력을 최대화하는 것을 목표로 한다.
모듈의 내적 요소 간 응집력 정도를 표현하는 유형 및 스케일
기능 응집력
순차 응집력
교환 응집력
절차 응집력 // 여기서부턴 쉽지 않은 유지보수
시간 응집력
논리 응집력
우연 응집력
(위로 갈수록 좋은 응집력, 아래로 갈수록 나쁜 응집력)
기능 응집력 : 모듈 구성하는 모든 요소가 오직 하나의 기능을 구현하기 위해 구성되었다면
기능 응집력이 있다고 정의한다.
ex) 수학의 코사인각 계산, 문장 알파벳 오류 체크 등
순차 응집력 : 모듈을 구성하는 문장 관계에서 한 문장의 실행 결과가 다음 문장의 입력으로 사용되는 경우
절차 응집력 : 모듈을 구성하는 문장들이 의미상 서로 관련이 없지만 제어 흐름의 순서가 있는 경우
시간 응집력 : 모듈을 구성하는 문장들이 소프트웨어 실행의 특정 시간과 관련이 있는것으로만 구성된 경우
ex) 데이터 사용 전 모든 변수 초기화 등
우연 응집력 : 가장 나쁜 형태의 응집력, 절대 작성되어서는 안되는 모듈 구성
모듈을 구성하는 모든 요소가 아무런 관련성이 없는 것으로 묶인 경우이다.
좋은 설계 : 결합력이 낮고 응집력은 높은 모듈 구성으로 이루어진 설계이다.
모듈화 응용 기술
모듈 간 결합력과 에너지 소모의 상관관계 실험

비교적 공유 결합력이 전력을 적게 소모하고 있음
데이터 양의 변화와 무관하게 거의 비슷한 전력 소모 패턴을 보인다.
모듈 간 결합력보다 데이터 처리 및 암호화를 위한 수학적 연산에 많은 에너지가 소모된다.
기술 부채
소프트웨어 시스템을 개발하는 과정에서 제대로 작업하지 않으면 추후 이자까지 붙은 빚이되어 돌아오기 때문에
더 많은 작업을 통해 이전의 올바르지 못한 결과를 바로잡아야 한다는 의미이다.
기술 부채의 개념이 잘 적용되는 기술 영역
소프트웨어 설계 단계에서 초기에 개발되는 소프트웨어 아키텍처
아키텍처 개발의 모든 부분에서 모듈하의 원리가 적용되어야 한다.
모듈화의 척도 관점에서 좋은 아키텍처일수록 결합력보다는 응집력에 더 집중해야 한다.
'전공 지식 정리 > 소프트웨어 공학' 카테고리의 다른 글
#6, #7 소프트웨어 공학 - 소프트웨어 비용 산정, 요구사항 도출 (0) | 2022.12.12 |
---|---|
#5 소프트웨어 공학 - 프로젝트 관리 (0) | 2022.11.25 |