본문 바로가기
Computer Architecture

컴퓨터 시스템 개론 : 7장 : SW 공학

by 12312121 2024. 5. 14.

이제 SW 공학을 배워 볼건데

이게 필요한 이유는 다음과 같다.

 

대규모화에 따른 비용 증가, 개발자 교체, 요구사항 변경의 이슈가 생길 수 있기 때문이다.

 

이걸 해결 안하면 품질, 생산성이 하락되고 개발도 지연된다.

 

먼저 이를 해결하기 위한 이론적인 것을 살펴보기 전에 방향성 먼저 잡아 보겠다.

 

3가지 관점이 있다.

발주자.

사용자.

유지보수자.

 

발주자는 최소비용 최대 생산성을 중시한다.

사용자는 기능의 정확성, 사용&이해의 용이성을 중시한다.

유지 보수자는 유지보수성, 이식성, 재사용성을 중시한다.

 

총체적인 관점도 있다.

SW 생명 주기가 있다.

SW 개발 과정을 단계별로 나눈 거다.

SW 개발 과정은 개발→사용↔유지보수 이렇게 이루어 진다.

 

Sw Life Cycle이라 해서 SLC라고도 한다.

 

SDLC, Sw Develop Life Cycle도 있는데

이건 개발과정을 나눈게 아니라, 어떻게 개발할 것인가에 대한 흐름이다.

요구사항 분석 →설계 →구현 →테스트 를 거친다.

 

그리고 해당 단계를 실제로 할때 드는 비용은 어떻게 분포 되어 있는가?

의외로 구현은 20%밖에 안든다.

물론 하루에 4줄, 1년에 2500줄 밖에 못만들지만.

 

분석, 설계에서 40%, 테스트에서 40%나 든다.

그리고 단계의 뒤로 갈수록 비용이 점점 증가한다.

그래서 유지보수때가 제일 비용이 많이 든다.

 


이제 관점이 아니라 진짜 개발 방법론을 보겠다.

폭포수, 반복형, 애자일, 점진적이 있다.

 

폭포수는 단계적으로 개발하는 방법이다.

특징으로는 이전 단계로 갈 수 없다는 것이다.

높은 추상화 단계에서 낮은 추상화 단계로 가는 거다.

 

따라서 이전 단계에서 오류가 발생됐다면 다음 단계에서 무조건 발생한다.

그리고 이전 단계가 완료 되기전에는 앞 단계를 못 진행 시켜서 잉여 인력이 많아진다.

그리고 완성 전에는 결과를 못봐서 만족도 검증을 할 수도 없다.

그리고 결과를 못보기 때문에 현실적으로 모든 요구사항을 기초 단계에서 미리 다 생각하기가 어렵다.

이는 오류를 더 가중시킨다.

따라서 각 단계마다 완벽하게 심혈을 기울여야한다.

 

물론 장점도 있다.

관리자 입장에서 현재 상황을 파악하고 관리하기 쉽다.

이전에 비슷한 SW를 개발한 경험이 있다면 단점은 상쇄되고 유리하다.

또한, 그냥 이전 단계에서 만들어 놓은대로 앞 단계에서 만들면 되기 때문에 명세서와 산출물이 명확해서 좋다.

 

점진적 & 반복형은 폭포수를 개선한거다.

굵게 빡 빡 빡 각 단계를 한번에 처리하는게 아니라, 모든 각 단계를 순환하면서 조금씩 여러번 처리하면서 완성도를 높여가는 방식이다. 보통 초기 단계일 수록 중요한 기능을 만들고 후기 단계일 수록 추가적인 기능을 만든다.

SDLC를 반복한다.

 

점진적
반복형

폭포수의 산출 결과를 볼 수 없다는 단점이 개선되서 좋고, 잉여 인력의 발생이 줄어서 좋다.

두 개의 차이점으로 점진적은 기능단위로 SDLC를 반복하고 반복형은 모든 기능 혹은 전체 프로그램을 단위로 SDLC를 반복한다

 

반복형의 종류로 몇가지 있다.

RUP, 폐기형 프로토타이핑, 진화형 프로토타이핑, 공개 소스 개발, 점진적/반복형 모델

 

RUP rational unified process는

4개의 주요 단계(Phases)와 6개의 핵심 워크플로우(Workflows)로 구성됩니다.

4단계의 목적은 개발 과정의 시각적 구분이며 워크플로우는 해당 워크플로우를 직접 수행하려는 목적입니다.


1. 시작 단계(Inception Phase) :
   - 프로젝트의 필요성, 범위, 비용, 일정을 확립합니다.
   - 초안 비전 문서, 초기 사업 사례, 주요 위험 평가를 포함합니다.
   - 프로젝트가 진행될 가치가 있는지 결정하는 과정입니다.

2. 정교화 단계(Elaboration Phase) :
   - 시스템의 아키텍처를 확립하고 주요 리스크를 해소합니다.
   - 상세한 요구 사항 분석, 아키텍처 설계 및 아키텍처 기반의 구현을 시작합니다.
   - 이 단계의 끝에서는 개발의 기반 구조가 견고하게 구축됩니다.

3. 구축 단계(Construction Phase) :
   - 소프트웨어 제품의 나머지를 구축합니다.
   - 이 단계에서 대부분의 개발 작업이 수행되며, 기능 개발, 테스팅 및 버그 수정이 주를 이룹니다.
   - 시스템이 사용자에게 제공될 준비가 됩니다.

4. 전환 단계(Transition Phase) :
   - 시스템을 사용자에게 전달하고 실제 운영 환경에서 적용합니다.
   - 최종 사용자 훈련, 시스템 배포 및 지원이 포함됩니다.
   - 사용자 피드백을 기반으로 소프트웨어를 정제하고 유지보수합니다.

RUP의 6개 워크플로우:

1. **비즈니스 모델링(Business Modeling)**:
   - 비즈니스 프로세스를 이해하고 모델링하며, 이를 통해 소프트웨어가 지원해야 할 비즈니스 목표를 명확히 합니다.

2. **요구사항(Requirements)**:
   - 사용자의 요구사항을 수집하고 분석하여 시스템이 충족해야 할 기능적 및 비기능적 요구사항을 정의합니다.

3. **분석 및 설계(Analysis & Design)**:
   - 요구사항을 기반으로 시스템 아키텍처를 설계하고, 문제 영역을 모델링합니다.
   - 설계 워크플로우에는 데이터, 아키텍처, 인터페이스 및 컴포넌트 설정이 포함됩니다.

4. **구현(Implementation)**:
   - 설계된 아키텍처를 기반으로 구현 작업을 진행합니다.
   - 단위 테스트를 수행하고, 소프트웨어 컴포넌트를 통합합니다.

5. **테스트(Test)**:
   - 구현된 시스템이 요구사항을 만족하는지 확인합니다.
   - 단위 테스팅, 통합 테스팅, 시스템 테스팅 및 인수 테스팅이 수행됩니다.

6. **배포(Deployment)**:
   - 최종 소프트웨어를 배포하고, 사용자 훈련 및 지원을 제공합니다.
   - 문제 발생 시 해결책을 제공하며, 시스템 유지보수를 계속 진행합니다.

RUP는 복잡한 프로젝트와 대규모 소프트웨어 개발에 특히 유용하며, 단계별로 접근하여 프로젝트의 리스크를 관리하고 효율적인 소프트웨어 개발을 목표로 합니다.

도입 정제 구축 전달로 이루어져있다

도입은 기획 및 평가다

정제는 기획의 세부화다

구축은 기획의 구현이다

전달은 구현을 소비자에게 전달하는 것이다

 

 

 

폐기형 프로토타이핑 방식은 실험 삼하 하나 만들어 보고 난 뒤에 진심으로 만드는 것이다.

이런 식으로 SDLC를 프로토 타입 단계에서 여러번 거치다가 테스트를 통과하면 폐기 한 뒤에

깔끔하게 최종 SDLC를 다시 만드는 방식이다.

 

근데 폐기 안하고 그대로 쓰면 진화형 프로토타이핑 방식이다.

공개 소스 개발 방식은 개발자와 사용자 모두가 다같이 개발하는 방식이다.

 

일단 사용자로부터 버그와 건의를 받고

고급 사용자가 버그 수정 및 새로운 기능을 추가하고

개발자, 인증 받은 사용자가 최종 검토 결과를 공개하는 방식이다.

 

근데 이런 것들이 장점만 있는건 아니다.

개발 목표와 종료 시점이 불명확하다는 단점이 있다.

 

애자일은 이것보다 더 자유롭게 변화하는 요구사항에 맞춰서 빠르게 출시하는 것을 사이클 형식으로 반복하면서 점진적으로 완성도를 높여가는 방식이다.

 

애자일의 일종으로 XP eXtrem Programming가 있다

유저 스토리를 바탕으로 우선순위를 수립 후 일정한 주기로 소규모 배포를 하는 방식이다.

 

유저 스토리는 유저의 요구사항을 간단하게 적은 것이다.

구조적 스파이크란 점검이다. 시스템 전체 구조에 대해서 어려운 요구사항이나 기술적인 위험에 대해 조사하고 실험하는 것이다. 일반 스파이크는 전체 구조가 아니라 기능 단위에서 점검한다.

릴리즈 계획은 배포 계획을 짜는 것이다.

주기는 1~3주의 시간 텀 동안 SDLC를 하는 것이다.

승인 테스트는 고객으로부터 완성 여부를 점검 및 피드백 받는 것이다.

작은 릴리즈는 조기 출시로 완성된 기능에 대한 조기 피드백을 받는 것이다.


이제 SW 개발 단위인 모듈에 대해서 알아보겠다.

모듈은 SW 개발, 기능 할당, 프로그래머 팀 작업 할당의 단위이다.

객체지향의 클래스를 의미하기도 한다.

 

모듈로 개발할때는 분할과 정복 기법을 활용한다.

분할과 정복을 할때는 먼저 문제를 가장 작은 문제로 분할한다.

그 뒤에 가장 작은 문제들을 정복한다.

그뒤에 큰 문제로 조금씩 조합해 나가면서 원래 문제를 완성해나가는 기법이다.

 

그리고 구조도란 함수를 기반으로 한 모듈 구조를 표현하는 도구다.

 



그리고 모듈을 사용 시, 변경 용이성을 위해 세가지를 중시한다.

낮은 결합도, 높은 응집도과 독립성이다.

응집도란 다른 기능 없이 특정 기능에 관한 것만 있는 정도이다.

다시말해 한 목적을 위해 관련된 정도다.

결합도는 다른 기능에 대한 의존도다.

독립성은 다른 기능과 얼마나 안 연관되어있는지다.

 

 

모듈은 그냥 함수라고 보면된다.

예를 들자면 아래와 같다.
선수가 서브를 하는것으로 시작되므로, 선수의 특성과 확률에 기초하여 공의 초기속도와 방향을 계산 Serve()

함수

공이 네트에 걸릴지 어느 위치에 떨어질지 등과 같이 공의 경로를 계산 ComputePath() 함수

상대 선수가 공을 리턴 할 있을지를 결정하는 것이며, 리턴할경우에는 공의 새로운 속도와 방향을 계산해야Return() 함수

경기점수를계산하고 갱신 UpdateScore() 함수


객체지향프로그래밍에서 모듈을 자주 쓴다.

이것의 목표는 객체들을 파악하과 객체들 간의 상호작용을 이해하는 것이다.

 

테니스 게임을 예로 들자면 객체는 세가지다.

선수, 심판, 스코어.

 

선수는 A,B가 있고 다 같은 기능(서브, 리턴)을 가지지만, 다른 특성(기술, 힘)을 가진다.

심판은 선수의 동작이 규정에 맞는지 판단한다.

스코어는 각 선수의 점수를 기록한다.

 

선수들의 행동이 규정에 맞을 경우 경기를 속행하지만, 맞지 않다면 중단하고 심판은

스코어에게 점수에 관한 메세지를 전달한다.

 

객체의 세부사항은 아래와 같다.

 

선수의 특성은 속성으로, 행동은 메서드로 표현한다.

그리고 같은 메서드를 쓰므로 같은 클래스로 구현하고 클래스 인스턴스만 다르게 한다.

 

그리고 심판과 스코어에게도 자신에게 맞는 메서드를 준다.

 

그리고 실제로 실행해보면 아래처럼 각 선수 메서드의 작동마다 심판이 검사하고 최종적으로 스코어에게 간다.

 

 

 

 

결합도는 두가지 종류로 나뉘어 진다.

제어 결합과 데이터 결합.

제어 결합은 실 제어권을 넘기는 것이고 데이터 결합은 데이터를 공유하는 것이다.

 

결합도는 더 많은 종류가 있다.

스템프 결합도는 두 모듈이 동일한 자료 구조를 조회하는 경우의 결합도다.

 

그리고 구조도란 함수를 기반으로 한 모듈 구조를 표현하는 도구다.

 

응집도의 종류는 아래와 같다.

 

예를 들어 객체 안의 메서드 끼리는 논리적 응집도만 있어서 응집도가 낮다.


근데 여러 모듈로 시스템 구조를 만들때 사람마다 다 달라서 해석하기 어렵다는 단점이 있다.

그래서 각 프로그래밍 언어에서는 모듈 구조 표준이 있다.

그것을 컴포넌트라고 부른다.

 

컴포넌트를 사용하기 전에 먼저 개발사가 개발해야한다. 그 과정은 다음과 같다.

먼저 개발사는 도메인(여러 영역)을 분석한다.

그 다음, 핵심적인 컴포넌트를 추출한다.

그 다음, 그것들로 설계한다.

그 다음, 그것들로 구현까지 해본다.

그 다음, 인증(검사)를 해본다.

마지막으로 컴포넌트 저장소에 저장한다.

 

그러면 사용자들은 요구 분석 후, 설계 후, 검색해서 원하는 걸로 조립해서 만든다.

 

예를 들어 대표적으로 안드로이드 앱이 있다.

액티비티 컴포넌트: UI 화면을구성하기 위한 컴포넌트

서비스 컴포넌트: 오랫동안 실행되는 작업이나 원격프로세스를 위한 작업을 사용되는컴포넌트

콘텐츠 프로바이더 컴포넌트: 데이터를 관리하고 다른앱의 데이터를 쿼리하거변경하는 컴포넌트

브로드캐스트 리시버 컴포넌트: 다양한 이벤트 정보를 받고 반응하는 컴포넌트


그리고 사용자가 모듈들을 기반으로 설계 시에 다양한 도구를 사용할 수 있다.

대표적으로 명령형 패러다임객체지향형 패러다임으로 나뉜다.

명령형은 구조적 분석 기법을 쓴다.

객체 지향형은 UML, Unified Modeling Language, 객체지향 모델링 언어를 쓴다.

 

명령형의 예로 데이터 흐름도데이터 사전이 있다.

데이터 흐름도는 데이터 저장소 사이에서 오가는 데이터들의 흐름을 그래프로 기록하는 방식이다.

 

그리고 데이터 사전이라는 것도 있다.

데이터 흐름도를 만들때 쓴 모든 정보들을 명세서 형식으로 기록하는 방식이다


이제 객체지향 패러다임의 예에 대해서 알아보겠다.

용례 다이어 그램, 클래스 다이어 그램이 대표적이다.

용례 다이어 그램부터 설명을 해보겠다.

먼저 용례란 사용자 입장에서 본 SW 시스템의 행동이다.

예를 들자면 아래와 같다.

 

클래스 다이어그램은 클래스 간의 관계로 표현하는 방식이다.

뜻은 아래와 같다

연결선 : 클래스 간 연관관계를 표시함

라벨 : 역할을 나타냄

화살표 : 연결선 라벨을 읽는 방향을 나타냄

다중성 : 연관되어 있는 두 클래스 사이에서 한 클래스의 인스턴스와

관계를 가질 수 있는 다른 클래스의 인스턴스 수를 나타냄


그리고 설계 시에 참고하면 좋은 패턴에 대해서 알아보겠다.

설계 패턴이란, 실무에서 반복적으로 발견되는 SW 설계를 말한다

특징으로는 재사용 가능한 속성을 가진다.

 

모듈 패턴은 캡슐화를 집중적으로 보는 패턴이다.

 

컴포넌트-커넥터 패턴은 통신을 집중적으로 보는 패턴이다.

댓글