소프트웨어 설계 기법
- 소프트웨어 설계 기법의 종류
- 구조적 프로그래밍 Structured Programming
- 절차적 프로그래밍 Procedure Programming
- 객체지향 (Object Oriented)
- 객체지향 프로그래밍
- 개체(Entity)를 속성(Attribute)와 메소드(Method)로 결합하여 객체(Object)로 표현
- 생산성, 재사용성, 확장성, 사용 편의성, 유지 보수성 용이
객체지향 프로그래밍(Object Oriented Programming)
- 개념:
- 코드 단위로 보는 것이 아닌 객체 단위로 구분하고 객체 간의 모음으로 설계하는 것
- 객체는 서로 메시지를 주고 받음
- 특징: 캡슐화, 정보은닉, 추상화, 상속성, 다형성⭐
관계성⭐ |
뜻 |
설명 |
is member of |
연관성 Association |
참조 및 이용 관계 |
is instance of |
분류화 Classification |
동일한 형의 특성을 갖는 관계 |
is part of |
집단화 Aggregation |
객체 간의 구조적인 집약 관계 |
is a |
일반화 Generalizaion, 특수화 Specialization |
클래스 간의 개념적인 포함 관계 |
캡슐화(Encapsulation)
- 서로 관련성이 높은 데이터와 관련된 기능을 묶는 방법
- 재사용성 높아짐, 변경 발생 시 오류의 파급 효과가 적음
정보은닉(Information Hiding)
- 캡슐화의 결과물 중 하나
- 객체의 내부 구현 세부 사향을 외부로부터 숨기는 것
- 객체의 사용자는 객체의 인터페이스(메서드, 속성)만 알고 있으면 됨
추상화(Abstraction)
- 공통된 성질은 추상 클래스로 설정
- 종류: 기능 추상화, 제어 추상화, 자료 추상화
상속성(Inheritance)
- 상위 클래스의 모든 속성, 연산을 하위 클래스가 재정의 없이 물려 받아 사용하는 것
- 다중상속: 다수 상위 클래스에서 상속
다형성(Polymorphism)
- 객체가 다양한 모양을 가지는 성질
- 오버로딩(같은 이름 순서 재사용), 오버라이딩(재정의)
🔎오버로딩 VS 오버라이딩
- 오버로딩 Overloading
- “과적”
- 한 클래스 내에서 같은 이름의 메소드 사용
- 매개 변수의 유형과 개수가 달라지도록 함
- 가독성과 유지 보수성 높임
- 매개 변수 유용하게 사용
- 메소드의 접근 제한자, 예외는 같아야 함
- 오버라이딩 Overriding
- “덮어쓰기”
- 상속 관계에서 상위 클래스에서 정의한 메소드를 하위 클래스에서 재정의하는 것
- Java 에서는 static 메소드의 오버라이딩 허용X
- 하위 객체의 매개 변수 개수와 타입은 상위객체와 같아야 함
구분 |
오버로딩 |
오버라이딩 |
메소드 이름 |
한 클래스 내에서 같음 |
상속 관계의 두 클래스 간 같음 |
매개 변수 개수, 타입 |
타입 또는 개수 달라야 함 |
같아야 함 |
접근 제한 |
무관 |
범위는 같거나 커야 함 |
사용 |
같은 이름 메소드 중복 정의 |
자식 클래스에서 부모 클래스의 메소드 재정의 |
객체지향 설계 원칙(SOLID) ⭐
단일 책임의 원칙(SRP : Single Responsibility Principle)
- 객체는 단 하나의 기능만 수행
- 변경 사항이 있을 경우 해당 객체만 수정
- 객체의 응집성을 높이고 결합도 낮추는 효과
개방-폐쇄의 원칙(OCP : Open Closed Principle)
- 확장에 대해서는 개방, 수정에 대해서는 폐쇄
- 새로운 기능이 추가되면 기존 코드를 수정하는 것이 아닌 확장
- 상속을 사용하여 새로운 기능 추가
리스코프 치환 원칙(LSP : Liskov Substitution Principle) ⭐
- 부모 클래스가 들어갈 자리를 자식 클래스로 대체하여도 계획대로 작동
- 자식 클래스는 부모 클래스의 역할을 수행할 수 있어야 함
- 코드의 재사용성과 유연성 높임
- 자식 클래스는 부모 클래스의 속성과 기능을 모두 상속 받아야 함
인터페이스 분리 원칙(ISP : Interface Segregation Principle)
- 자신이 사용하지 않는 메소드(인터페이스)와 의존 관계를 맺으면 안 됨
- 인터페이스는 작게 분리 되어야 하고 필요한 기능만 제공
의존 역전 원칙(DIP : Dependency Inversion Principle)
- 구체적인 구현이 아닌 추상화에 의존
- 상위 수준의 모듈은 하위 수준의 모듈에 의존하지 않아야 함
- 추상화된 인터페이스나 추상 클래스에 의존해야 함
- 코드의 결합도를 낮추고 유지보수성과 확장성을 높임
객체지향 개발 방법론
- Booch, OOSE, OMT, Coad와 Yourdon 기법
OMT(Rumbaugh)
- 객체 모델링 : 객체도, 정적 구조
- 동적 모델링 : 상태도, 객체의 제어 흐름/상호 반응
- 기능 모델링 : 자료 흐름도, 데이터 값의 변화 과정
- CASE와 연동 충실함
Coad 와 Yourdon 기법
- E-R 다이어그램을 사용해 객체의 행위를 데이터 모델링 하는 데 초점을 둔 방법
- 객체 식별 → 구조 식별 → 주체 정의 → 속성 및 관계 정의 → 서비스 정의 → …
- 분석가와 설계자에 적합한 기법
- 최근에는 UML이 더 많이 사용됨
클래스 설계
- 개념: 분석 단계 중 아직 확정되지 않은 클래스 내부 부분 중 구현에 필요한 중요한 사항을 결정하는 작업
- 인터페이스에 대한 정확한 정의, 메소드 내부의 로직 등 상세히 설계
클래스 인터페이스
관점에 따라 구현할 것인지, 사용할 것인지, 확장할 것인지 다르므로 클래스 인터페이스는 중요함
- 클래스 구현 : 설계로부터 클래스를 구현하려는 개발자
- 클래스 사용 : 구현된 클래스를 이용해 다른 클래슬르 개발하려는 개발자
- 클래스 확장 : 구현된 클래스를 확장하여 다른 클래스를 만들려는 개발자
협약에 의한 설계 (Design by Contract) 3가지 타입 ⭐
- 선행 조건 (Pre Condition)
- 호출되기 전에 참이 되어야 할 조건
- 충족 되지 않으면 예외 발생
- 결과 조건 (Post Condition)
- 불변 조건 (Invariant Condition)
- 클래스 내부가 실행되는 동안 항상 만족해야 하는 조건
디자인 패턴(Design Pattern)
- 개념
- 자주 사용하는 설계 형태를 정형화해 설계 템플릿을 만들어 두고 개발 중 나타나는 과제를 해결하는 방법 중 한 가지
- 상세한 내부적인 소프트웨어 개발 방법
↔ 아키텍처 패턴 : 설계, 구조
- 운용성, 원활한 의사소통, 구조 파악 용이, 설계 변경에 대한 유연한 대처, …
- 장점
- 이미 검증된 해결책을 제공하므로 시간, 비용 절약
- 코드의 구조 명확해짐
- 패턴 재사용이 가능해 코드의 양을 줄임
- 단점
- 초기 투자 비용 부담
- 잘못된 패턴 적용은 오히려 코드의 가독성과 유지 보수성을 떨어뜨림
- 디자인 패턴을 남용하면 코드의 복잡도 증가
- 디자인 패턴 구성 요소
- 필수 요소
- 문제, 해결책, 결과, 컨텍스트, 구성 요소, 상호작용, 문서화, 유연성, 일반성, 적용 예시,
- 품질 향상, 적용 가능성, 개발 방법론, 팀원 협업
- 추가 요소 ⭐
- 알려진 사례 : 간단한 적용 사례
- 샘플 코드 : 패턴이 적용된 원시 코드
- 원리, 정당성, 근거
디자인 패턴 |
아키텍처 패턴 |
시스템 전체 구조 설계 |
시스템 내 컴포넌트와 그들 간의 관계를 구성 |
상위 설계 |
하위 설계 |
GoF(Gangs of Four) 패턴
- GoF 디자인 패턴
- 총 23 가지 패턴
- 종류: 생성 패턴, 구조 패턴, 행위 패턴
생성 패턴 (Creational Patterns)
생성 패턴 종류 |
설명 |
Factory Method |
상위 클래스에서 객체를 생성하는 인터페이스를 정의하고, 하위 클래스에서 인스턴스를 생성 |
Abstract Factory ⭐ |
구체적인 클래스에 의존하지 않고 연관되거나 의존적인 객체들의 조합을 만들어 인터페이스를 제공 |
Singleton |
전역변수를 사용하지 않고 객체를 하나만 생성하도록 함 |
Prototype |
프로토타입을 먼저 생성하고 인스턴스를 복제하여 사용 |
Builder |
복잡한 객체를 생성할 때 생성하는 방식을 분리하는 방법 |
구조 패턴 (Structural Patterns)
- 복잡한 형태의 구조를 개발하기 쉽게 만들어 주는 패턴
구조 패턴 종류 |
설명 |
Adapter |
인터페이스를 다른 인터페이스로 변환해 다른 클래스가 이용할 수 있도록 함 |
Bridge |
구현부와 추상부로 분리해 각자 독립적으로 확장할 수 있게 함 |
Composite |
객체들의 관계를 트리구조로 구성해 복합 객체와 단일 객체를 구분 없이 다룸 |
Decorator |
어떤 객체에 다른 객체를 덧붙임 |
Facade |
서브시스템에 있는 인터페이스 집합에 대해 하나의 인터페이스 제공 |
Flyweight |
크기가 작은 여러 개의 객체를 매번 생성하지 않고 가능한 한 공유하도록 함 |
Proxy |
접근이 어려운 객체에 접근할 수 있는 인터페이스 제공 |
행위 패턴 (Behavioral Patterns)
- 반복적으로 사용되는 객체들의 상호작용을 패턴화 한 것
- 상호작용하는 방법과 책임을 분산
- 메시지(message) 교환과 관련된 것
행위 패턴 종류 |
설명 |
Chain of Reponsibility |
요청을 한 객체가 처리하지 못하면 다음 객체로 넘어가는 패턴 |
Iterator |
접근이 잦은 객체는 동일한 인터페이스를 사용하도록 하는 패턴 |
Command |
명령어를 캡슐화 |
Interpreter |
언어에 문법 표현을 정의하는 패턴 |
Memento |
객체 내부 상태를 객체화하여, 객체를 해당 시점의 상태로 돌릴 수 있게 함 |
Observer |
한 객체의 상태가 변하면, 객체에 상속되어 있는 다른 객체 상태에 따라 변화된 상태를 전달하는 패턴 |
State |
상태의 캡슐화 |
Strategy |
동일 계열 알고리즘을 개별적으로 캡슐화 |
Visitor |
처리 기능을 클래스로 구성해, 처리기능이 각 클래스를 방문해 처리기능을 수행 |
Template Method |
상위에서 인터페이스 정의, 하위에서 구체화 |
Mediator |
상호 작용을 캡슐화 |