목차
설계
소프트웨어 : 설계서를 만든 후 이를 기반으로 구현 작업에 착수
- 좋은 설계가 되기위한 조건
- 설계서는 요구분석 명세선의 내용을 모두 포함
- 유지보수가 용이하도록 추적이 가능해야함
- 변화에 쉽게 적응
- 국지적이어야함
- 쉽게 작성
주요 원칙
- 모듈화: 설계는 작은 부분들로 나눠져야 합니다. 이것을 모듈이라고 부르며, 각 모듈은 독립적으로 작동하고 다른 모듈과 상호작용합니다.
- 추상화: 복잡한 시스템을 간단하게 표현하는 방법입니다. 이를 통해 개발자는 전체적인 구조를 이해하고, 세부적인 문제에만 집중할 수 있습니다.
- 정보 은닉: 각 모듈은 자신의 세부 정보를 숨기고, 필요한 기능만을 외부에 노출합니다. 이를 통해 다른 모듈이 내부 구현에 의존하지 않도록 합니다. 독립적인 성격
- 함수적 분해: 큰 문제를 작은 문제로 나누는 방법입니다. 각 작은 문제는 독립적으로 해결하고, 이를 결합하여 큰 문제를 해결합니다.
분할: 세분화
분산시스템 → 클라이언트 서버
시스템 → 여러 서브시스템
서브시스템 → 하나 이상의 패키지
패키지 → 유스케이스 or 여러 클래스
주의사항: 너무 많이 분리하면 복잡도 증가 ⇒ 응집도(강하게) 결합도(느슨)
정복: 말단에 있는 것부터 하니씩 개발
추상화: 유사한 특성을 가진 것끼리 그룹화한 뒤 공통점을 뽑아 이름을 붙임
- 과정(프로세스) 추상화: 상세부분 생략, 전체 흐름만 파악할 수 있는 알고리즘 형태로 작성
복잡한 시스템의 동작을 간단한 인터페이스로 표현하는 방법. 사용자는 이 인터페이스를 통해 시스템을 조작할 수 있으며, 시스템의 내부 동작 방식을 몰라도 됨.
구체적인 방법을 언급하지 않고, 정렬한다 라고만 표현
- 데이터 추상화: 데이터와 데이터구조를 감춤. 데이터와 메서드를 클래스 형태로 캡슐화, 사용자는 꼭 필요한 기능만 사용함
- 제어 추상화: 제어 구조를 추상화. 조건문 if문, for문, 루프, 함수 프로그램의 흐름을 제어하는 방식을 단순화하는 과정
캡슐화: 기능과 사용법. 내부는 변경 불가능 ⇒ 블랙박스 테스트
- 블랙박스 테스트: sw 내부 구조나 작동 원리는 모르는 상태에서 동작을 검사하는 방식
- 동등분할, 경계값 분석, 원인-결과, 오류예측
- 화이트박스 테스트: 모듈의 코드를 오픈시킨 상태에서 논리적인 모든 경로를 테스트
- 커버리지 - 제어흐름, 데이터흐름, 분기, 경로
- 장점제공자와 이용자 분리객체 사이의 독립성이 구조적으로 보장됨
- 기능만 알면 객체를 쉽게 사용함, 이해하기 쉬움
- 개념화(데이터+메서드)
- 정보 은닉: 캡술화를 통해 외부에서 객체의 내부 데이터를 직접 접근하는 것을 제한하고, 이를 조작하는 메서드만을 외부에 노출함으로써, 객체의 내부 구조를 숨길 수 있습니다.
- 유지보수 용이: 객체의 내부 데이터와 메서드가 한 곳에 묶여 있기 때문에, 코드의 수정 및 유지보수가 쉽습니다.
- 코드 재사용성 향상: 캡술화된 객체는 독립적으로 동작하므로, 다른 프로그램에서도 그대로 사용할 수 있어 재사용성이 높아집니다.
- 데이터 보호: 캡술화를 통해 데이터를 직접적으로 접근하거나 변경하는 것을 제한함으로써, 데이터의 무결성을 유지할 수 있습니다.
- 유연성과 확장성 향상: 캡술화는 클래스의 인터페이스를 변경하지 않고도 내부 구현을 변경할 수 있게 해주므로, 소프트웨어의 유연성과 확장성을 향상시킵니다.
- + (공개) public: 모든 클래스가 접근 가능
- - (은닉) private: 해당 클래스의 메서드를 통해서만 접근가능. 기본속성
- # (부분공개) protected: 상속받은 하위 클래스만 접근
- 상속
- 상위(부모)클래스의 모든 것을 하위(자식)클래스가 물려받아 내것처럼 사용
- 속이 빈 화살표
- 장점: 구조파악 용이, 관계에 속한 클래스 데이터 메서드 추가하기 쉬움, 상위클래스 수정하면 하위클래스도 수정됨
- 다형성: 한 가지 형태가 여러 형태로 나타날 수 있는 능력
- 오버로딩(중복정의): 메소드 이름만 같고, 파라미터(매개변수)는 자료형이나 개수가 달라야한다. 리턴형 무관. 같은 클래스의 블록 안에서 사용
- 오버라이딩(재정의): 상위 클래스에서 정의한 메서드는 무시하고, 하위 클래스에서 다시 정의해 사용. 이름, 파라미터 개수와 데이터의 자료형, 리턴형 같아야 한다.
- 상위 메소드와 동일하거나 더 구체적인 exeption을 발생시켜야 한다.
- 상위 메소드와 동일하거나 접근 범위가 넓은 접근 제한자를 사용해야 한다.
- 차이점: 오버로딩은 컴파일 타임에 바인딩, 오버라이딩은 런타임에 바인딩
바인딩: 이름을 값에 연결하는 과정. 호출하는 함수의 주소를 메모리에서 찾아서 찾은 메모리 주소를 컴파일러에게 알려주는 것정적 바인딩: 함수 호출 코드가 고정된 메모리 주소로 변환되는 것(오버라이딩 Default)동적 바인딩: 함수가 실행될 때 결정되는 것
오버라이딩에서 부모 클래스의 메소드를 호출하려고 했지만, 실제로는 자식 클래스의 메소드가 호출되는 경우 → 정적 바인딩 ⇒ 가상함수를 사용해 동적바인딩 사용가상 함수: 부모 클래스에서 선언되며, 자식 클래스에서 재정의. 런타임에 동적 바인딩을 통해 적절한 함수가 호출될 수 있도록 함. 부모 클래스의 포인터나 참조를 통해 자식 클래스의 메소드를 호출할 수 있다.시험범위 아닌데 궁금해서 찾아보았다.. 시험범위는 아님
- 모듈화: 구조를 이루는 기본 단위, 조각. 독립프로그램이나 함수
- 특징 : 유일한 이름, 독립적인 기능, 다른모듈 호출가능, 프로그램에서도 모듈 호출 가능
- 원칙: 결합 느슨하게 응집 강하게
- 장점: 복잡도 감소, 유지보수성 용이, 코드 재사용, 가독성 향상
- 모듈화의 적정 수준
- 관계: 호출관계, 데이터 전달, 제어
모듈화 평가 기준: 응집도 우논시절통순기
모듈 내부의 처리 요소간의 기능적 연관성을 측정하는 척도
응집도가 높을수록 필요한 구성요소만 모여있고, 낮을수록 관련성이 적은 구성요소들의 모임
낮음 ---------------------------------------------------------------------- 높음
우연적응집 논리적 시간적 절차적 통신적 순차적 기능적
기능적: 단일 기능의 요소가 하나의 모듈을 구성
순차적: 한 요소의 출력이 다음 요소의 입력으로 사용
통신적 교환적: 정보적 응집. 동일한 속성을 사용하는 기능. 순서 중요X
절차적: 순서대로 수행. 순차적과 달리 자료가 아닌 제어로 전달됨
시간적: 같은 시간대에 함께 실행
논리적: 논리적으로 유사하지만, 관계는 없음(printf, scanf 결합 등)
우연적: 뚜렷한 관계 없이 존재
결합도 데스제외공내 (테스형제외저래공유랑내가닮았대 - by 흥달쌤)
구조 내에서 모듈간의 관련성을 측정하는 척도 → 외부 모듈과의 연관도
결합도가 낮을수록 상호의존성이 줄어 모듈의 독립성이 높아지고, 독립성이 높으면 모듈 간에 영향이 적음
낮음 --------------------------------------- 높음
데이터결합 스탬프 제어 공통 내용
데이터(내용): 가장 좋음. 매개변수를 통해 데이터만 주고받음
스탬프: 모듈간에 통신할때 전체데이터를 주고받음. (ex. 구조체, 배열, 객체)
제어: 한 모듈이 다른 모듈의 내부 논리를 제어하기 위한 목적. 다른모듈의 내부에 관여(ex. 제어 플래그)
외부: 외부 변수로 선언된 데이터를 2개 이상의 모듈이 서로 참조
공통: 전역변수, 오류전파와 무결성 문제 발생 ⇒ 지역변수로 선언하여 해결
내용: 한 모듈이 다른 모듈 내부를 직접 참조하거나 수정함. 서로 종속되어 독립적으로 설계 불가능하다.
모듈간의 결합도는 낮게, 응집도는 높게
사용자 인터페이스: CUI(텍스트), CLI(cmd), GUI(그래픽), NUI(홍채)
- 사용자 중심: 사용자의 요구와 편의를 우선시하여 설계. 사용자의 행동 패턴, 선호, 필요성을 이해하고 이를 반영.
- 직관성: 인터페이스는 사용자가 별도의 설명이나 교육 없이도 이해하고 사용.
- 일관성: 일관된 디자인과 흐름
- 피드백 제공: 사용자의 액션에 대해 적절한 피드백을 제공 → 로딩중
- 단순성: 간결하고 명확한 디자인이 사용자 경험을 향상
- 사용자 오류 예방 및 처리: 오류를 범할 가능성을 최소화하고, 오류가 발생했을 때 쉽게 이해하도록 돕는 메커니즘
- 접근성: 다양한 사용자들을 위해 접근성을 고려
아키텍처 설계
아키텍처: 시스템의 추상화된 전체 구조와 주요 구성 요소, 그리고 이들 간의 상호작용을 정의
- 복합성 문제 해결
- 동작 예측, 변경에 유연하게 대처 가능
모든 이해관계자의 품질 요구사항을 반영해 우선순위에 따라 시스템 품질 속성을 결정해야함
- 성능, 사용성, 보안성, 안정성, 검증 가능성, 변경 용이성
구성요소 표준화, 패턴화하여 재사용할 수 있도록 설계
기본골격이 만들어져 개발에 참여하는 사람들의 이해의 폭이 넓어지며 구현상의 문제점을 도출할 수 있음
블랙박스로 명시
- 품질 속성: 요구사항과 관심사를 반영한 것
- 시스템
- 가용성: 장애없이 서비스를 제공할 수 있는 능력. 하드웨어는 이중화 설계를 함
- 변경 용이성: 새로운 요구사항에 대해 쉽게 변경할 수 있는지
- 성능: 요청 등 이벤트 발생 시, 빠르고 효율적으로 기능을 수행할 수 있는가
- 보안성: 승인되지 않은 사용차단. 중요하다면 계층구조 아키텍처의 안쪽에 저장한다
- 사용성, 테스트 용이성(비용), 시장 적시성
- 비즈니스
- 비용과 이익, 예상 시스템 수명, 목표 시장, 공개일정, 기존 시스템과의 통합
- 아키텍처
- 개념적 무결성(전체시스템으로 통합하더라도, 일관성이 유지되어야함), 정확성과 완전성, 개발 용이성(구축 가능성)
4+1 관점 view
시스템을 이루는 요소의 집합, 연관관계 추상적으로 표현
해법영역 4개 관점 + 문제영역 1개 관점
- 시나리오 (유스케이스) 관점
- 기능 하나하나 유스케이스로 표현됨
- 정적표현: 유스케이스 다이어그램
- 동적표현: 상태, 순차, 통신, 활동 다이어그램
- 논리 (디자인) 관점
- 시스템 내부, 클래스나 컴포넌트 및 관계에 초점
- 시스템의 기능
- 정적: 클래스, 객체 다이어그램
- 동적: 상태(동작표현), 순차 통신(상호작용), 활동(연산동작)
- 개발 (구현) 관점
- 모듈 연관관계, 설계, 연결관계
- 정적: 컴포넌트 다이어그램
- 동적: 상태, 순차 통신, 활동
- 프로세스 관점
- 시스템의 동작과 성능 중점
- 물리적 (배치) 관점
- 처리장치 간의 물리적인 배치에 초점
- 정적: 배치 다이어그램
- 동적: 상태, 순차 통신, 활동
아키텍처 스타일
- 데이터 중심형 스타일: 공동으로 활용하는 주요 데이터가 리포지토리(큰 공유데이터 저장소)에서 중앙 관리됨. 서브시스템과 리포지토리의 결합도가 높음. 데이터 관리가 목적(ex.학교)
- 클라이언트-서버 스타일: 네트워크를 이용하는 분산 시스템 형태. 서브시스템(컴포넌트)이 서비스를 서로 요청하면서 상호작용
- 서버: 클라이언트의 요청을 처리하기 위해 대기. 결과를 회신(ex.프린트 서버, 메일 서버, DNS 서버 등)
- 클라이언트: 서버가 제공하는 서비스를 요청하는 서브시스템(ex.웹 브라우저)
- 씬 클라이언트 스타일: 데이터 관리가 서버에서 수행. 클라이언트는 프레젠테이션 계층만 구현. 서버와 네트워크에 걸리는 부하가 큰 것이 단점
- 팻 클라이언트 스타일: 서버에서 데이터 관리만 관여. 클라이언트는 애플리케이션 로직, 프레젠테이션의 많은 부분 구현, 클라이언트에 부하가 큼. 관리와 배포 복잡함
- 계층 스타일: 대부분의 운영체제와 통신 시스템이 이용함. 기능을 몇개의 계층으로 나누어 배치. 계층 내의 응집도 높고 계층간의 결합도 낮아 재사용 및 유지보수에 유용하다.
- 프레젠테이션 계층: 프론트엔드, 사용자 인터페이스
- 비즈니스 로직 계층: 기능 요구사항 구현하는 곳, 미들웨어, 애플리케이션
- 데이터 계층: 백엔드, DBMS
- 데이터 흐름 스타일: 서브시스템이 하나의 데이터를 입력으로 받아서 처리한 후 결과를 다음 서브 시스템으로 넘겨주는 과정을 반복. 파이프와 필터를 조합해 만드는 아키텍처에 적합
- 데이터를 변환하는 시스템에서 주로 사용. 전체변환작업은 독립적인 단계이다
- 필터: 데이터 스트림을 하나 이상 입력받아 변환한 후, 데이터 스트림 하나를 출력. 하나의 필터는 여러 포트로 데이터를 보낼 수 있다
- 파이프: 필터를 거쳐 생성된 데이터 스트림 하나를 다른 필터의 입력에 연결
- MVC 스타일: 모델, 뷰, 제어. 뷰와 모델을 독립적으로 분리해 무결성 유지. 약한 결합
- 사용자가 자료를 요청함
- 제어 Control은 모델 Model을 호출
- 모델은 DBMS를 이용해 자료를 수정하고, 결과를 제어에게 반환(응답)
- 제어는 결과를 모델로부터 가져와 뷰를 호출하고, 결과를 전달
- 뷰는 결과를 여러형태(테이블, 그래프, 엑셀)로 공개(응답)
장점: 검증된 아키텍처, 구축 전 시뮬레이션 가능, 기존 시스템에 대한 빠른 이해
클래스 간의 관계 - 연의일실포집
- 연관 관계: 1...3 서로를 알고 있는 상태
- 양방향 연관관계
- 역할이 부여된 연관관계
- 다중 연관 관계: 일 대 다. 선 위에 다중성을 표기해 나타냄. 다대다 관계는 실제로 구현하기 어려움
- 단방향 연관 관계: 한쪽만 아는 관계. 직선 실선 화살표
- 연관 클래스: 연관관계를 더 구체적으로 나타내고 싶을때 클래스를 추가해 사용. 점선으로 일반 클래스를 연결해 나타냄. 다른 클래스와도 연관관계를 맺을 수 있다.
- 의존 관계: 하나의 클래스가 또 다른 클래스를 짧은 시간 동안 사용(참조)
- 느슨한 결합(연관관계는 강한 결합)
- 상대의 메서드를 가지고 있음(연관관계는 멤버변수를 가진다)
- 일반화 관계: 하나의 사물이 다른 사물에 비해 더 일반적인지, 구체적인지, 공통점 가진것끼리 묶음
- 부모자식 상속. 상위에서 하위로 추상화(일반화), 하위에서 상위로 구체화(특수화)
- is a kinde of 관계
- 실체화 관계: 추상 메서드. <<abstract>> ◁----- extends / <<interface>> ◁----- implements
- 포함 관계: 복합 합성 관계, 영구적, 강한 결합 관계 whole ◆ㅡ part
- 전체 객체에 완전히 종속되어 독립된 객체로 존재할 수 없다
- 집합 관계: 하나의 객체에 여러 개의 독립적인 객체들이 구성 whole ◇ㅡ part
- is composed of 관계: 이루어졌다.
- 약한 결합 관계
클래스 설계 원칙 SOLID
- SRP 단일 책임 원칙: 한 클래스는 하나의 책임만 가져야한다.
- 클래스를 설계할 때 변경하는 이유가 하나가 되도록 해야 한다는 것
- 두개의 책임이 있다면, 분리해야한다
- OCP 개방-폐쇄 원칙: 확장에는 열려있으나, 변경에는 닫혀있어야한다.
- 지원가능한 파일 형식을 반복되는 것을 모아 상속 구조로 클래스를 수정
- LSP 리스코프 치환 원칙: 상위 클래스의 객체는 언제나 자신의 하위 클래스의 객체로 교체(재정의)할 수 있어야 한다.
- ISP 인터페이스 분리 원칙: 자신이 사용하지 않는 메서드와 의존 관계를 맺으면 안된다.
- 클라이언트 인터페이스 → N:1 보다 1:N으로 분리해 사용
- 사용하지 않는 메서드와 연관관계를 맺고있을 경우 → 원칙 위반
- SRP와 헷갈리면 안됨
- DIP 의존관계 역전 원칙: 클라이언트는 구체 클래스가 아닌, 추상 클래스(인터페이스)에 의존해야 한다.
- 고수준 구성요소가 저수준 구성요소에 의존하면 안된다