[소프트웨어설계] 5. 객체지향 설계와 디자인 패턴

소프트웨어 설계 기법

  • 소프트웨어 설계 기법의 종류
    • 구조적 프로그래밍 Structured Programming
    • 절차적 프로그래밍 Procedure Programming
    • 객체지향 (Object Oriented)
  • 객체지향 프로그래밍
    • 개체(Entity)를 속성(Attribute)와 메소드(Method)로 결합하여 객체(Object)로 표현
    • 생산성, 재사용성, 확장성, 사용 편의성, 유지 보수성 용이

객체지향 프로그래밍(Object Oriented Programming)

  • 개념:
    • 코드 단위로 보는 것이 아닌 객체 단위로 구분하고 객체 간의 모음으로 설계하는 것
    • 객체는 서로 메시지를 주고 받음
  • 특징: 캡슐화, 정보은닉, 추상화, 상속성, 다형성⭐
Untitled
관계성⭐ 설명
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 가지 패턴
    • 종류: 생성 패턴, 구조 패턴, 행위 패턴
Untitled 1

생성 패턴 (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 상호 작용을 캡슐화