1. 소프트웨어 설계 이란?
  ㅇ 크고 복잡한 소프트웨어 시스템의 요구사항과 목적을 만족시키기 위해,
     - 시스템의 구조(Structure), 행위(Behavior), 상호작용(Interaction)을,
     - 체계적으로 정의하고 구체화하는 과정
2. 소프트웨어 설계 상의 특징
  ㅇ 단지 코딩이 아니라, 무엇을 어떻게 구현할지에 대한 청사진(blueprint)을 만드는 단계
  ㅇ 소프트웨어 품질 속성(유지보수성, 확장성, 재사용성, 성능, 보안 등)을 고려해야 함
  ㅇ 설계 산출물은 이후 구현, 테스트, 유지보수의 기반이 됨
3. 소프트웨어 설계 과정
  ※ 통상, 상위 수준 설계(Architecture)에서 시작해, 세부 수준 설계(Detail Design)로 내려가는,
     계층적 접근을 따른
  ㅇ 아키텍처 설계 
     - 시스템 전체의 뼈대를 정의   
  ㅇ 데이터베이스 설계
     - 시스템에서 사용할 데이터 모델을 정의
  ㅇ 서브 시스템 설계
     - 아키텍처를 더 작은 단위(서브시스템, 모듈)로 나누어 각 부분의 역할과 책임을 구체화
  ㅇ 컴포넌트 설계
     - 서브시스템 내부의 클래스, 함수, 객체와 같은 소프트웨어 컴포넌트의 세부 구조 설계
  ㅇ 자료구조, 알고리즘 설계
     - 문제 해결에 가장 적합한 자료구조 및 알고리즘을 선택
4. 객체 지향 설계의 5가지 기본 원칙 (SOLID)
  ㅇ 단일 책임의 원칙 (Single Responsibility Principle, SRP)
     - 하나의 책임만 가지도록 함
        . 즉, 하나의 클래스,속성,메서드,패키지,모듈,컴포넌트,프레임워크 등에 단일 책임 만 부여
  ㅇ 개방 폐쇄의 원칙 (Open Closed Principle, OCP)
     - 확장에는 개방, 변경에는 닫힘 (확장은 쉽게, 변형은 어렵게)
        . 즉, 기능 추가시, 기존 코드를 수정 않고 확장 가능해야 함 (다형성, 추상화 활용)
  ㅇ 리스코프 교체의 원칙 (Liskov Substitution Principle, LSP)
     - 서브클래스는 상위 타입을 대체할 수 있어야 함
        . 즉, 자식 클래스는 부모 클래스를 대체 가능 해야 함
           .. 프로그램의 정확성을 깨지 않으면서, 하위 타입의 인스턴스를 바꿀 수 있어야 함
  ㅇ 인터페이스 분리의 원칙 (Interface Segregation Principle, ISP)
     - 하나의 범용 인터페이스 보다, 여러 개의 구체적인 인터페이스가 나음
        . 즉, 클라이언트는 자신이 사용하는 인터페이스 만 알면 됨
  ㅇ 의존성 역전의 원칙 (Dependency Inversion Principle, DIP)
     - 고수준 모듈이 저수준 모듈에 의존해서는 안 되며, 추상화에 의존해야 함
        . 프로그래머는, 구체화 보다는 추상화에 의존해야 함
5. 디자인 패턴 (Design Pattern)
  ㅇ 모든 프로그램 형식에, 일반적으로 적용 가능한,
     - 자료 구조 및 프로그램 구조를 다루는 이론
  ㅇ 주로, 
     - 소프트웨어 아키텍처 수준 보다 낮은 수준의 설계 문제에서, 
     - 자주 접하는 문제에 대해,
     - 객체 간의 상호관계 등을 이용하여,
     - 재사용 가능한 솔루션을 제공하기 위함
  ㅇ 주요 종류
     - 싱글톤 패턴  :  하나의 클래스에 단 하나의 인스턴스 만 생성,존재하도록 보장하는 패턴
     - 반복자 패턴  :  컬렉션의 요소를 순차적으로 접근하도록 하는 패턴
     - 어댑터 패턴  :  호환되지 않는 인터페이스를 연결하는 변환 패턴
     - 데코레이터 패턴  :  객체에 추가 기능을 동적으로 제공하는 패턴
     - 팩토리 메소드 패턴  :  객체 생성 과정을 서브클래스에서 정의하는 패턴
     - 추상 팩토리 패턴  :  관련 객체의 생성을 일관되게 제공하는 패턴
     - 상태 패턴  :  객체의 상태에 따라 행위를 변경하는 패턴
     - 옵저버 패턴  :  객체 상태 변화를 감지하고 자동으로 업데이트하게 하는 패턴
        . 객체 상태 변화를 관찰자들에게 알림
           .. 주체가 어떤 객체의 상태 변화를 관찰하면서, 
           .. 상태 변화 발생시, 메서드 등을 통해, 옵저버 목록에 있는 옵저버들에게 변화를 알려줌
        . 옵저버 (observer) : 객체 상태 변화시, 이에따라 추가 변화가 생기는 객체
     - MVC 패턴  :  UI(User Interface)와 비즈니스 로직을 분리하는 패턴