6장. 아키텍처 설계
설계의종류
- 아키텍처 설계(소클사알프)
- 소프트웨어를 서브시스템과 컴포넌트로 분할
- 어떻게 연결될 것인가?
- 어떻게 상호작동 할 것인가?
- 인터페이스는?
- 클래스 설계
- 클래스의 여러기능
- 사용자 인터페이스 설계
- 알고리즘 설계
- 컴퓨팅 메커니즘의 설계
- 프로토콜 설계
- 통신 프로토콜의 설계
- 소프트웨어를 서브시스템과 컴포넌트로 분할
응집력(우논시절교순기)
- 설계원리2 : 응집력을 증진
- 서브시스템이나 모듈이 서로 관련 있는 것들은 같이 있게 하고 그 외의 것은 외부에 존재하게 함
- 전체시스템을 이해하거나 변경하기 쉬워짐
- 응집력의 종류
- 기능적응집 : 단일 결과를 계산하기 위한 코드만이 모여 있고 나머지는 밖으로 추출할 때 달성 됨
- 즉 모듈이 단일 작업을 수행하여 결과를 내고 외부효과(side-effect)가 없는 것
- 수학 함수 모듈
- 화학 공정에 필요한 값을 계산하는 화학 공정 제어 모듈
- 시스템에 대한 이익
- 이해가 쉬움
- 재사용 용이
- 다른 것으로 쉽게 대치
- DB를 갱신하거나 새로운 파일을 만드는 모듈, 사용자와 상호작용하는 모듈은 기능적 응집이 아님
- 즉 모듈이 단일 작업을 수행하여 결과를 내고 외부효과(side-effect)가 없는 것
- 계층적응집 : 연관되는 서비스를 제공하는 기능들을 모아놓고 그 이외의 것은 밖으로
- 각 층은 계층을 형성하여야
- 고위층은 하위층의 서비스를 접근
- 하위층은 고위층을 접근하지 않음
- 하나의 계층에 있는 절차와 메소드를 API(Application Programming Interface)라 하고 이를 통해 서비스제공
- 하위 계층은 그보다 높은 계층에 접근하지 않기 때문에 같은 수준의 다른 층으로 교체 할 수 있음
- 단일 계층을 형성하는 서비스
- 연산을 위한 서비스
- 메시지 또는 데이터를 전송하기 위한 서비스
- 데이터를 저장하기 위한 서비스
- 각 층은 계층을 형성하여야
- 교환적응집 : 특정 데이터(클래스)를 접근하거나 조작하는 모듈은 같이 두고 그 외의 것은 밖으로
- 좋은 교환적 응집을 갖는 클래스의 조건
- 특정 자료를 저장하고 조작하는 시스템의 기능을 한 클래스 안에 포함시킨다면
- 클래스가 그 데이터를 조작하는 이외의 일은 하지 않는다면
- 데이터베이스를 갱신하는 모듈과 데이터베이스로그를 기록하는 모듈은 교환적 응집을 가진다
- 주요장점
- 데이터를 조작할 때 한곳에서 모든 코드를 찾을 수 있음
- 좋은 교환적 응집을 갖는 클래스의 조건
- 순차적응집 : 한프로시저의 출력이 다음프로시저의 입력이 될 때 이들을 함께 두고 나머지는 밖으로
- 앞에 나열한 응집이 모두 성취되었다면 다음은 순차적 응집이 되도록 노력
- 예)문서 인식 시스템
- 비트 맵을 받아 글자를 구성하는 구획으로 나눔
- 해당 글자가 결정
- 단어의 순서 결정
- 절차적 응집 : 한 프로시저 이후에 차례로 수행되는 프로시저를 모아 놓은 응집(함수의 순서)
- 한 프로시저의 결과가 다음 프로시저에 입력으로 사용되지 않더라도
- 순차적 응집보다 약함
- 대학 수강 신청 시스템
- 강좌를 신청하는 데 요구되는 모든 과정을 수행하는 모듈이 있고
- 새로운 강좌 추가 등의 분리된 작업을 하기 위한 기능이 다른 모듈에 있음
- 시간적 응집 : 프로그램 수행에서 같은 단계에 있는 오퍼레이션들이 같이 모여 있음(시간과 관련)
- 예를 들어 한 시스템의 시작이나 초기화 하는 동안 사용되는 코드들을 같이 둠
- 동일한 방법으로 시스템 종료를 위한 코드 또는 특별할 때에 사용되는 코드를 묶는 경우
- 절차적 응집보다 약함
- 실용적 응집 : 다른 응집도에는 해당되지 않고 서로 연관된 유틸리티 기능들을 함께 두는 경우
- 실용적 기능이란 다른 서브시스템들을 위하여 광범위하게 응용되는 즉 재사용을 위하여 설계된 프로시저나 클래스 ex) java.lang.Math
- 기능적응집 : 단일 결과를 계산하기 위한 코드만이 모여 있고 나머지는 밖으로 추출할 때 달성 됨
시험 문제 : 우연적 응집도 < 논리적 응집도 < 시간적 응집도 < 절차적 응집도 < 통신적 응집도 < 순차적 응집도 < 기능적 응집도(우논시절교순기)
결합력
- 설계원리3: 결합력 감소
- 결합은 두 모듈 사이에 의존관계가 있을 때 발생함
- 의존관계가 존재하면 한 부분이 변경되면 다른 부분의 변경을 유발
- 강하게 결합된 모듈일수록 시스템을 이해하고 변경하기 어려움
- 결합력의 종류 : 내공외제스자
- 내용결합 : 다른컴포넌트의 내부 데이터를 알리지 않고 수정하는 컴포넌트
- 내용결합피하기위해 모든 인스턴스 변수를 캡슐화해야함(private, get과set함수제공)
- 인스턴스 변수 안에 포함된 인스턴스 변수를 직접적으로 수정할 때 내용결합 발생
- 줄이는 방법 : 반드시 피해서 결합력을 줄임
- 공통결합 : 전역변수를 사용할 때 항상 발생
- 전역변수를 사용하는 모든 모듈은 서로 결합됨
- 줄이는 방법 : 전역변수의 사용을 최소화, 전역변수를 사용할 때는 한 모듈로 만들어야 결합력을 줄임
- 제어결합 : 프로시저가 플래그나 커맨드를 사용하여 다른 프로시저를 호출하여 제어하려 할 때 발생
- 다형성을 가진 오퍼레이션을 사용하면 제어결합을 피할 수 있음
- 줄이는 방법 :look-up테이블 이용해 제어결합 감소(명령이 구동될때 호출되어야 하는 메소드로매핑)
- 스탬프 결합 : 응용 클래스들 중의 하나가 메소드의 매개변수로 정의될 경우
- 다른 클래스를 매개변수로 사용하기 때문에 시스템의 변경이 쉽지 않음
- 줄이는 방법 : 매개변수로 인터페이스를 사용, 자료변수를 전달(자료결합)
- 자료결합 : 메소드의 매개변수 타입이 기본적이거나 단순한 라이브러리 클래스 인 경우
- 매개변수가 많을수록 결합도가 높음
- 자료결합과 스탬프 결합의 trade-off(하나를 낮추면 다른 하나는 올라감, 매개변수가 많다면 스탬프결합의 인터페이스를 사용하는 것이 효과적)
- 줄이는 방법 : 불필요한 매개변수를 줄임으로 결합도를 낮출 수 있음
- 루틴호출결합 : 하나의 루틴(메소드)이 다른 루틴을 호출할 때 결합이 발생
- 줄이는 방법 :두개의메소드를 반복하여 사용한다면 -> 이런 부분을 캡슐화하여 하나의 루틴 정의
- 타입사용결합 : 어떤 모듈이 다른 모듈에서 정의된 자료형을 사용할 때 발생
- 공통결합과 유사하지만, 자료가 공유되는 것이 아니라 자료형만 공유(미치는 영향 작음)
- 줄이는 방법 : 가능하면 단순한 형태(인터페이스,슈퍼클래스 등)사용하여 결합력을 줄임
- 포함결합 : 컴포넌트가 패키지를 import하는 경우, 컴포넌트가 다른파일 include하는 경우
- 줄이는 방법 : 불필요할 때 제거하여 결합력을 줄임
- 외부결합 : 어떤 모듈이 운영체제, 공유 라이브러리, 하드웨어 등에 의존하는 경우
- 줄이는 방법 : 코드에 의존성 갖는 부분을 줄이는 것이 최선의 방법
- 내용결합 : 다른컴포넌트의 내부 데이터를 알리지 않고 수정하는 컴포넌트
시험예상 : 자료 결합도 < 스탬프 결합도 < 제어 결합도 < 외부 결합도 < 공통 결합도 < 내용 결합도(내공외제스자)
아키텍처 패턴
- 클라이언트 서버 패턴
- 커넥션을 기다리고 처리해 주는 하나의 클라이언트가 있음
- 서비스를 제공 받으려고 커넥션을 시도하는 하나 이상의 클라이언트가 있음
- 확장된 형태는 peer-to-peer 스타일(여러 호스트에 분산되어 있는 여러 소프트웨어 컴포넌트로 구성)
- 브로커 패턴
- 여러 노드에 투명하도록 소프트웨어 시스템을 분산
- 원거리에 있는 객체의 메소드를 호출 가능
- CORBA가 잘 알려진 표준
- 여러 노드에 투명하도록 소프트웨어 시스템을 분산
- 트랜젝션 처리 패턴
- 연달아 들어오는 입력을 하나씩 읽어
- 각 입력은 트랜잭션을 명시 - 시스템에 저장되어 있는 데이터를 조작하는 명령들
- 트랜젝션을 어디서 처리할 것인지를 나타내는 트랜젝션 사령(dispatcher)컴포넌트가 필요
- 사령컴포넌트는 프로시저 호출이나 메시지를 트랜젝션을 처리할 컴포넌트에 배치
- 연달아 들어오는 입력을 하나씩 읽어
- 파이프 필터 패턴
- 비교적 단순한 데이터 스트림이 프로세스에 차례로 전달되어
- 특정한 형태로 변환,데이터는 파이프라인으로 계속 주입,프로세스는 병렬적으로 실행,아키텍처는 매우 융퉁적
- 비교적 단순한 데이터 스트림이 프로세스에 차례로 전달되어
- MVC 패턴(model-view-controller)
- 사용자 인터페이스를 시스템의 다른 부분과 분리하기 위한 스타일
- 모델 : 사용자에게 보여지고 조작될수 있는 중요한 클래스의 인터페이스를 포함
- 뷰 : 모델에 있는 데이터를 사용자 인터페이스에 보여주는 역할
- 제어부분 : 사용자가 모델과 뷰를 인터랙션하는 것을 제어하는 객체를 포함
- 사용자 인터페이스를 시스템의 다른 부분과 분리하기 위한 스타일
7장.디자인 패턴(4문제)
생성패턴(객채생성)
- 인스턴스를 만드는 절차를 추상화하는 패턴
- 객체를 생성, 합성하는 방법이나 객체의 표현 방법과 시스템을 분리
- 추상팩토리 : 구체적인 클래스를 지정하지 않고 관련성을 갖는 객체들의 집합을 생성하거나 서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공하는 패턴
- 빌더 : 복합객체의 생성 과정과 표현 방법을 분리하여 동일한 생성절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴
- 팩토리 메서드 : 객체를 생성하는 인터페이스는 미리 정의하되, 인스턴스를 만들 클래스의 결정은 서브클래스 쪽에서 내리는 패턴 (클래스의 인스턴스를 만드는 시점을 서브클래스로 미룸)
- 원형(프로토타입) : 생성할 객체의 종류를 명세화하는 데에 원형이 되는 예시물을 이용하고, 그 원형을 복사함으로써 새로운 객체를 생성하는 패턴
- 조금씩 다른 객체를 변환하여 생성(클론메소드)
- 단일체(싱글톤) : 어떤 클래스의 인스턴스는 오직 하나임을 보장하며, 이 인스턴스에 접근할 수 있는 전역적인 접촉점을 제공하는 패턴
- 클래스안에 정적인 인스턴스 변수로 자신의 타입을 가지게하고, 생성자를 외부에서 사용하지 못하도록 private로 선언
구조패턴
- 더 큰 구조를 형성하기 위해 어떻게 클래스와 객체를 합성하는가와 관련된 패턴
- 상속 기법을 이용하여 인터페이스나 구현을 복합
- 적응자(어뎁터) :클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해줌
- 원하는 인터페이스를 추상 클래스로 정의, 이를 상속하는 어뎁터 클래스를 만들고 이를 요구하는 기능을 가진클래스(adaptee)와 메시지를 교환하게 함
- 가교(Bridge) : 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴
- 복합체(Composite) : 객체들의 관계를 트리구조로 구성하여 부분-전체 계층을 표현하는 패턴, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 함
- 장식자(Decorator) : 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴, 기능 확장이 필요할때 서브클래싱 대신 쓸 수 있는 유연한 대안
- 퍼사드(Facade) : 서브시스템에 있는 인터페이스 집합에 대해서 하나의 통합된 인터페이스를 제공하는 패턴, 서브시스템을 좀더 사용하기 편하게 만드는 상위 수준의 인터페이스를 정의
- 플라이웨이트(Flyweight) : 크기가 작은 객체가 여러개 있을 때, 공유를 통해 이들을 효율적으로 지원하는 패턴,메모리절약
- 프록시(Proxy) : 어떤 다른 객체로 접근하는 것을 통제하기 위해서 그 객체의 대리자 또는 자리채움자를 제공하는 패턴
- 적응자(어뎁터) :클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해줌
행동패턴
- 응용프로그램에 따라 행동이 다른 객체로 옮겨가거나 알고리즘이 대체되어야 하는 변화를 만족할 수 있는 패턴
- 객체나 클래스에 대한 패턴을 정의하는 것이 아니라, 그들 간의 교류 방법에 대하여 정의
- 책임 연쇄(chain of responsibility) : 요청을 처리할 수 있는 기회를 하나 이상의 객체에게 부여하는 요청을 보내는 객체와 그 요청을 받은 객체 사이의 결합을 피하는 패턴, 요청을 받을 수 있는 객체를 연쇄적으로 묶고, 실제 요청을 처리할 객체를 만날 때까지 객체 고리를 따라서 요청을 전달
- 명령(command) : 요청을 객체의 형태로 캡슐화하여, 서로 다른 요청이 다른 사용자의 매개변수화, 요청 저장 또는 로깅, 그리고 연산의 취소를 지원하게 만드는 패턴
- 해석자(Interpreter) : 주어진 언어에 대해, 그 언어의 문법을 위한 표현수단을 정의하고, 이와 어울러 그 표현 수단을 사용하여 해당 언어로 작성된 문장을 해석하는 해석기를 정의하는 패턴
- 반복자(Iterator) : 내부 표현부를 노출하지 않고 어떤 객체 집합에 속한 원소들을 순차적으로 접근할 수 있는 방법을 제공하는 패턴
- 중재자(Mediator) : 한 집합에 속해있는 객체들의 상호작용을 캡슐화하여 객체를 정의하는 패턴, 객체들의 직접 서로를 참조하지 않도록 함으로써 객체들 사이의 소결합을 촉진시키며, 개발자가 객체들의 상호작용을 독립적으로 다양화시킬 수 있게 만듬
- 메멘토(Memento) : 캡슐화를 위배하지 않은 채 내부상태를 잡아내고 실체화시켜, 이후에 해당 객체가 다시 되돌아올 수 있도록 하는 패턴
- 감시자(Observer) : 객체 사이에 일 대 다의 의존 관계를 정의해 두어, 어떤 객체가 상태가 변할 때 그 객체의 의존성을 가진 다른 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 만드는 패턴
- 상태(State) : 객체의 내부 상태에 따라 스스로 행동을 변경할 수 있게끔 허가하는 패턴, 객체는 마치 자신의 클래스를 바꾸는 것처럼 보임
- 전략(Strategy) : 알고리즘
- 템플릿 메서드 : 객체의 연산에는 알고리즘의 뼈대만을 정의 각 단계에서 수행할 구체적 처리는 서브클래스로 미루는패턴
- 방문자(visitor) : 객체 구조를 이루는 원소에 대해 수행할 연산을 표현하는 패턴, 연산을 적용할 원소의 클래스를 변경하지 않고도 새로운 연산을 정의
8장. 구현
객체지향 코딩 규칙
- 단일책임 : 클래스는 오직 한 가지 이유로만 변경되어야 한다.
- 개방 폐쇄 : 모듈은 확장에는 개방되어야 하나 변경에는 폐쇄되어야한다.
- 리스코프 대체 : 서브타입은 자신의 베이스 클래스로 대체 가능해야 한다, 서브클래스를 만들 때 베이스 클래스의 동작을 바꾸면 안됨, 확장해야 함
- 인터페이스 분리 : 여러 클래스로 구성된 모듈을 클라이언트가 쉽게 사용하게 하려면 추상화된 인터페이스를 제공, 이때 관심의 대상이 되는 인터페이스만 분리하여 제공
- 의존 관계 역젼 : 자주 변경되는 구체적인 클래스에 의존하지 말아야한다, 추상 클래스와 인터페이스에 의존되어야한다
리팩토링
- 기능의 변경 없이 코드의 디자인을 개선하는 것
- 문제가 될 만한 부분을 찾아내어 수정하고 재구조화하는 작업
- 코드를 쉽게 이해할 수 있을 뿐만 아니라 확장 및 재사용할 수 있음
- 결합을 낮추고, 응집을 높여서 코드를 쉽게 변경할 수 있도록
- 소프트웨어의 디자인을 개선시킴
- 소프트웨어를 이해하기 쉽게 만듦
- 버그를 찾는 데 도움을 줌
- 프로그램을 빨리 작성할 수 있게 도와 줌
코드스멜
- 설계를 수정하기 어렵게 만드는 코드
- 중복 코드
- 긴 메소드
- 큰 클래스
9장. 테스트
테스트관련용어
- 신뢰도 : 관찰되었던 시스템의 동작과 명세에 기술된 동작이 일치하는 정도
- 오류 : 시스템을 실행하는 동안 나타나는 결함의 표시, 시스템이 정상적으로 작동하지 못하게 함
- 결함 : 소프트웨어가 이상 동작을 하게 만드는 설계 또는 코딩 상의 잘못, 버그
- 고장 : 컴포넌트의 명세와 실행 동작의 차이, 하나 이상의 오류에 의해 발생
- 테스트 대상 컴포넌트 : 분리하여 시험할 수 있는 시스템의 요소, 모듈
- 테스트 케이스 : 고장을 일으키고 결함을 발견할 목적으로 컴포넌트를 검사하기 위한 입력과 예상 결과의 집합
- 테스트 드라이버 : Bottom Up, 테스트될 컴포넌트를 호출하는 컴포넌트의 부분적인 구현(테스트 대상을 구동시키는 프로그램)
- 테스트 스터브 : Top Down , 테스트될 컴포넌트가 호출하는 컴포넌트가 부분적으로 구현된 것( 호출되는 컴포넌트를 시뮬레이션 한 프로그램, 브리지 패턴을 이용한 스터브)
테스트단계
- 단위테스트 -> 통합테스트 -> 기능테스트 -> 성능테스트 -> 인수테스트 -> 설치테스트(단합능능인설)
블랙박스테스트
- 대상을 블랙박스로 보고 그 기능이 올바른지 확인하는 작업
- 동등분할테스트 : 입력의 결과가 동등한 클래스를 분할, 대푯값
- 가능한 입력을 동치 클래스로 나누고 테스트 사례를 각 클래스에서 선택
- 대표입력값선택기준 : 표함정도, 비결합성, 표현성
- 경곗값 분석 : 오류가 많이 발생하는 경계선 상의 테스트를 집중
- 원인결과분석 : 원인과 결과의 관계를 파악하여 테스트
- 의사결정표(입력은원인, 출력은 결과)
- 동등분할테스트 : 입력의 결과가 동등한 클래스를 분할, 대푯값
화이트박스테스트
- 모듈 안의 내부구조와 실행 경로를 자세히 참조 ( 조건커버리지테스트, 경로테스트)
- 경로테스트 : 가능한 경로를 적어도 한번씩 실행
- 경로 찾기 : 원시코드의 흐름도 작성
10장. 유지보수
형상관리
- 변경에 대한 철저한 관리가 필요
- 소프트웨어 형상 관리
- 형상관리(Configuration Management)
- 소프트웨어를 이루는 부품의 baseline(변경통제시점)을 정하고 변경을 철저히 통제하는 것
- 형산 관리 요소
- 분석서, 설계서, 프로그램(원시코드, 목적코드, 명령어 화일, 자료화일, 테스트파일), 사용자 지침서
- 형상관리절차 : 소프트웨어 형상파악 -> 형상 변경 제어 -> 소프트웨어 형상 감사 -> 소프트웨어 형상 상태 보관
- 형상요소파악 : 고유식별자, 이름, 문서종류, 문서파일 등
- 형상변경제어
- 변경의 이유를 파악(결함,하드웨어변경), 변경 분석, 변경 제안 준비, 변경제안의 평가, 변경을 추가
리엔지니어링
- 지속적으로 변화하는 S/W - 구조가 나빠짐을 의미
- 리엔지니어링
- 시스템 또는 컴포넌트를 재구조화 하는 과정
- 유지보수를 넘어 개선하는 차원
- 역공학(Reverse Engineering)
- 시스템을 이루는 부품을 찾아내고 관계를 파악하며 다른 형태로 표현하기 위하여 대상 시스템을 분석하는 과정
- 경쟁 제품 분석
- 목적
- 소프트웨어 아키텍처 개선
- 소프트웨어의 복잡도 경감
- 변경에 대한 적응성 개선
- 성능,효율성,자원유용성 개선
- 소프트웨어 시스템의 유지보수 개선 <- 디자인 패턴 적용
- 작업과정 : 개선위치파악 -> 개선전략선택 -> 제안된 개선 구현 -> 목적 대비 평가
- 재문서화 : 리엔지니어링에서 같은 수준의 추상표현을 만들거나 다시 재작하는 일, 역공학에서 가장 간단하고 오래된 형태로서 다른 형태로 표현하는 것을 말한다.
12.품질보증
확인과 검증
- 검증 : 개발하고 있는 시스템이 요구사항에 맞는지(개발자관점)
- 정적테스팅, 제공된 요구사항이 실제 요구사항과 일치한다는 가정하에 요구사항대로 만들어지고 있는지
- 확인 : 개발되고 있는 시스템이 요구사항에 맞는지(사용자관점)
- 동적테스팅, 실제 고객의 요구사항의 빠진 요소 없이 모든것을 포함하는지
- 인스펙션 : 작성자 외 다른전문가가 검사하는 가장 공식적인 리뷰 기법
- 목적 : 준비하는 동안 예상되는 결함을 찾아내고 이를 확인
- 설계인스펙션 : 모듈의 전반적인 설계나 기능을 점검
- 코드인스펙션
- 과정 : 계획 -> 사전교육 -> 준비 -> 인스펙션 회의 -> 수정 -> 후속조치
- 체크리스트를 만들어 미리 배포하고 발견된 이슈를 논의, 결함 판정
- 워크스루 : 테스트케이스를 이용하여 제품을 수작업으로 수행해보는 것(검토회의전)
- 동료검토 : 동료가 제품을 검토(작성자설명, 동료 결함발견)
'공부' 카테고리의 다른 글
클라우딩 컴퓨팅 소개 (1) | 2023.10.24 |
---|---|
웹프로그래밍기초 기말 (1) | 2023.06.11 |
소프트웨어 공학 - 4.객체지향 소프트웨어공학 5.동적모델링 (0) | 2023.04.23 |
소프트웨어공학 - 1.소프트웨어 공학의 개요, 2. 객체지향 개념, 3.요구분석 (0) | 2023.04.23 |
웹 프로그래밍 기초 시험 예상 (0) | 2023.04.19 |