디자인 패턴
패턴
- 문제와 그 해법의 핵심을 기술한 것
- 여러 환경에서 재사용될 수 있음
- 여러 환경에서 재사용될 수 있음
- 상세한 명세가 아님
- 객체 지향 소프트웨어 설계에 큰 영향을 줌
디자인 패턴
- 객체 지향 설계와 연관
- 공개된 패턴 - 일반성을 제공하기 위한 상속과 다형성 같은 객체 특성에 의존
- 공개된 패턴 - 일반성을 제공하기 위한 상속과 다형성 같은 객체 특성에 의존
- 패턴 적용 일반 원칙
- 어떤 종류의 소프트웨어 설계에도 똑같이 적용 가능하게 하는 것
디자인 패턴의 네 가지 핵심 요소
- 패턴을 지칭하는 의미 있는 이름
- 패턴이 적용될 수 있는 환경을 설명하는 문제 영역에 대한 서술
- 설계 해법의 구성요소들에 대한 서술 및 그들의 관계와 책임
- 구체적 설계 기술이 아닌 다른 방법으로 인스턴스화될 수 있는 설계 해법을 위한 템플릿
- 구체적 설계 기술이 아닌 다른 방법으로 인스턴스화될 수 있는 설계 해법을 위한 템플릿
- 패턴을 적용한 결과에 대한 서술
- 설계자가 특성 상황에 패턴을 사용할 수 있는지를 결정하는데 도움
설계 문제
- 패턴을 설계에 사용하기 위해 설계 문제에 적용 가능한 관련된 패턴이 있는지 알아봐야 함
- 설계 문제의 예
- 어떤 객체의 상태가 변경되었음을 여러 객체에게 알린다(Observer 패턴)
- 종종 점증적으로 개발된 여러 관련된 객체들에 대한 인터페이스를 정돈(Facade 패턴)
- 어떻게 컬렉션이 구현되었는지에 무관하게 컬렉션의 원소를 접근하는 표준 방법을 제공한다.
(Iterator 패턴) - 실행 시간에 기존 클래스의 기능을 추가할 수 있는 가능성을 허용(Decorator 패턴)
패턴 적용의 제약점
- 컴포넌트의 구현 단계에서 만들어진 세부 설계 결정 사항으로 인해 제약을 받을 수 있음
- 패턴을 사용하는 것은 아이디어를 재사용하지만 개발하는 시스템에 맞게 구현을 맞추는 의미
- 패턴을 사용하는 것은 아이디어를 재사용하지만 개발하는 시스템에 맞게 구현을 맞추는 의미
- 시스템 설계를 시작할 때 미리 특정 패턴이 필요한지 아는 것은 어려움
- 효과적이려면 소프트웨어 설계 경험이 필요
여러 종류의 디자인 패턴
창조적 패턴
- 코드의 유연성과 재사용을 증가시키는 다양한 객체 생성 메커니즘을 제공
- 팩토리 메서드, 추상 팩토리, 빌더, 프로토타입, 싱글턴 등
구조적 패턴
- 객체들과 클래스들의 구조를 유연하고 효율적으로 유지하면 더 큰 구조로 조립하는 방법 제공
- 어댑터, 브리지, 복합체, 데코레이터, 퍼사드, 플라이웨이트, 프락시 등
행위적 패턴
- 알고리즘과 객체 간의 책임 할당과 관련 있음
- 책임 연쇄, 커맨드, 반복자, 중재자, 메멘토, 옵서버, 상태 등
디자인 패턴 카탈로그
창조적 패턴
- 팩토리 메서드, 추상 팩토리, 빌더, 프로토 타입, 싱글톤 등
- 팩토리 메서드, 추상 팩토리, 빌더, 프로토 타입, 싱글톤 등
구조적 패턴
- 어댑터, 브리지, 복합체, 데코레이터, 퍼사드, 플라이웨이트, 프락시 등
- 어댑터, 브리지, 복합체, 데코레이터, 퍼사드, 플라이웨이트, 프락시 등
행동 패턴
- 책임 연쇄, 커맨드, 반복자, 중제자, 메멘토, 옵서버, 상태, 전략, 템플릿 메서드, 비지터 등
- 책임 연쇄, 커맨드, 반복자, 중제자, 메멘토, 옵서버, 상태, 전략, 템플릿 메서드, 비지터 등
싱글턴 패턴
- 클래스에 대한 인스턴스 하나만 두고 이 인스턴스에 대한 전역 접근 지점을 제공하는 생성 디자인 패턴
- 싱글턴 패턴 → 단일 책임 원칙을 위반하면서 아래의 두 문제를 해결해야 함
단일 책임 원칙
- 모든 클래스는 하나의 책임만 가지며 클래스는 그 책임을 완전히 캡슐화해야 함
- 모든 클래스는 하나의 책임만 가지며 클래스는 그 책임을 완전히 캡슐화해야 함
- 클래스에 하나의 인스턴스만 두도록 함
- 일부 공유 리소스에 대한 접근을 제어하기 위함
- 생성자 호출은 특성상 반드시 새 객체를 반환해야 하므로 위 행동은 일반 생성자로 구현 불가능
- 해당 인스턴스에 대한 전역 접근 지점을 제공
- 싱글턴 패턴을 사용하면 프로그램의 모든 곳에서 일부 객체에 접근 가능
- 다른 코드가 해당 인스턴스를 덮어쓰지 못하도록 보호하기도 함
- 싱글턴 패턴 단계
- 다른 객체들이 싱글턴 클래스와 함께 new 연산자를 사용하지 못하도록 디폴트 생성자를 비공개로 설정
- 생성자 역할을 하는 정적 생성 메서드를 생성
- 객체를 만들기 위해 비공개 생성자를 호출한 후 객체를 정적 필드에 저장
- 이후에 모든 호출이 정적 필드에 저장된 객체에 반환
- 코드가 싱글턴 클래스에 접근할 수 있는 경우, 이 코드는 싱글턴의 정적 메서드를 호출할 수 있음
- 해당 메서드가 호출될 때마다 항상 같은 객체가 반환됨
싱글턴 패턴 - 적용 예시
- 싱글턴 클래스는 정적 메서드 getInstance를 선언
- 자체 클래스의 같은 인스턴스를 반환
- 자체 클래스의 같은 인스턴스를 반환
- 싱글턴 객체를 가져올 수 있는 유일한 방법
- getInstance 메서드를 호출
- 싱글턴의 생성자는 항상 클라이언트 코드에서 숨겨져야 함
옵저버 패턴
- 여러 객체에 자신이 관찰 중인 객체에 발생하는 모든 이벤트에 대해 알리는 구독 메커니즘을
정의할 수 있도록 하는 행동 디자인 패턴
구현 이슈
재사용
- 기존의 컴포넌트나 시스템을 재사용하여 구축
- 소프트웨어를 개발할 때 기존 코드를 가능한 많이 사용해야 함
- 재사용 수준
추상 수준
- 성공적인 추상화 지식을 소프트웨어 설계에 사용
- 디자인 패턴과 아키텍처 패턴
객체 수준
- 코드를 직접 작성하는 대신 라이브러리의 객체를 직접 재사용
- 코드를 직접 작성하는 대신 라이브러리의 객체를 직접 재사용
컴포넌트 수준
- 프레임워크를 이용하여 원하는 기능을 구축(예 - 사용자 인터페이스)
- 프레임워크를 이용하여 원하는 기능을 구축(예 - 사용자 인터페이스)
시스템 수준
- 전체 애플리케이션 시스템들을 재사용
- 전체 애플리케이션 시스템들을 재사용
- 소프트웨어 재사용
재사용 비용
- 소프트웨어를 찾고 평가하는 시간 비용
- 적용 가능한 소프트웨어를 구매하는 비용
- 요구사항을 반영하기 위해 소프트웨어 컴포넌트나 시스템을 개조하고 설정하는 비용
- 재사용가능한 소프트웨어 요소들을 서로 통합하고 새로 개발한 코드와 통합하는 비용
형상 관리
- 변화하는 소프트웨어 시스템을 관리하는 일반적인 프로세스
- 소프트웨어 개발에서 절대적으로 필요한 요소
- 소프트웨어 개발에 여러 사람이 관여할 때 타인의 일을 방해하지 않도록 해야 함
- 시스템 통합 프로세스를 지원하는 것을 목표로 함
- 개발 프로세스 중에 각 소프트웨어 컴포넌트의 많은 다른 버전들이 생성
- 이 버전들을 형상 관리 시스템에서 추적하지 않으면 시스템에 잘못된 버전의 컴포넌트를 포함하기 쉬움
4가지의 기본적인 형상 관리 활동
버전 관리
- 여러 프로그래머의 개발을 조정하는 기능 제공
- 개발자가 타인에 의해 시스템에 제출된 코드를 덮어쓰지 않게 해 줌
- 개발자가 타인에 의해 시스템에 제출된 코드를 덮어쓰지 않게 해 줌
- 여러 프로그래머의 개발을 조정하는 기능 제공
시스템 통합
- 필요한 컴포넌트들을 컴파일하고 링크하여 자동으로 시스템을 빌드하는 데 사용
- 필요한 컴포넌트들을 컴파일하고 링크하여 자동으로 시스템을 빌드하는 데 사용
문제 추적
- 사용자들이 버그와 다른 문제점들을 보고하는 것을 가능하게 함
- 모든 개발자들이 문제에 관한 작업 로그를 확인할 수 있게 함
릴리스 관리
- 새로운 릴리스의 기능과 배포를 위한 소프트웨어 구성을 계획하는 것과 관련
호스트 타깃 개발
- 제품 소프트웨어는 보통 소프트웨어 개발 환경과 같은 컴퓨터에서 실행되지 않음
- 소프트웨어는 호스트 시스템에서 개발하고 별개의 컴퓨터에서 실행됨
- 대게는 호스트와 타깃이 완전히 다름
호스트 타깃 개발 시 고려해야 하는 것
- 임베디드 시스템을 개발할 때 종종 시뮬레이터를 상용함
- 센서 같은 하드웨어 장치나 시스템이 설치될 환경에서의 이벤트를 시뮬레이션
← 소프트웨어를 타깃 하드웨어로 다운로드할 필요가 없어 개발 시간 단축 가능 - 시뮬레이터 개발 비용이 많이 드는 점이 문제
- 센서 같은 하드웨어 장치나 시스템이 설치될 환경에서의 이벤트를 시뮬레이션
- 타깃 시스템에 미들웨어나 사용해야 하는 다른 소프트웨어가 설치되어 있다면
그 소프트웨어를 이용하여 시스템을 시험해야 할 수 있음
- 개발된 코드를 실행 플랫폼으로 전송
- 사용권 제한 때문에 타깃 시스템에서 필요로 하는 소프트웨어를 개발 시스템에 설치하여 사용하지 못할 수도 있음
컴포넌트/시스템 배포 시 고려사항
- 컴포넌트의 하드웨어와 소프트웨어 요구사항
- 컴포넌트가 특정 하드웨어 아키텍처를 위해 설계되거나, 어떤 소프트웨어 시스템에 의존
- 컴포넌트가 특정 하드웨어 아키텍처를 위해 설계되거나, 어떤 소프트웨어 시스템에 의존
- 시스템의 가용성 요구사항
- 고가용성 시스템은 컴포넌트가 하나 이상의 플랫폼에 배치되는 것을 요구
→ 플랫폼 장애 시 컴포넌트의 다른 구현을 사용할 수 있음을 의미
- 고가용성 시스템은 컴포넌트가 하나 이상의 플랫폼에 배치되는 것을 요구
- 컴포넌트 통신
- 컴포넌트 간 통신이 많으면 보통 컴포넌트들을 같은 플랫폼 또는 물리적으로
서로 가까운 플랫폼에 배치하는 것이 핵심 → 통신 대기시간 감소
- 컴포넌트 간 통신이 많으면 보통 컴포넌트들을 같은 플랫폼 또는 물리적으로
오픈 소스 개발
- 소프트웨어 소스 코드가 공개되고 개발 프로세스에 지원자들이 참여 가능한 소프트웨어 개발 접근법
- 성공적인 오픈 소스 시스템은 소프트웨어에 대한 변경을 관리하는 개발자의 핵심 그룹에 의존
- 원칙적으로는 오픈 소스 프로젝트의 어떤 기여자도 버그를 보고하고 고치며 새로운 특징과 기능을 제안
오픈 소스 소프트웨어
- 인터넷과 소프트웨어 공학의 중심
- 대표적인 서버 시스템 - Linux 운영체제, Apache 웹 서버
- Java, Android, mySQL 등
- 오픈 소스 장점
- 값이 저렴하거나 무료
- 널리 사용되는 오픈 소스 시스템은 매우 안정적
회사에서 고려해야 할 오픈 소스 이슈
- 개발 중인 제품에 오픈 소스 컴포넌트들을 사용해야 하는가
- 자체 소프트웨어 개발을 위해 오픈 소스 접근법을 사용해야 하는가
오픈 소스 비즈니스
- 전문적인 시스템을 위해서 개발에 오픈 소스 접근법을 사용하고 있음
- 소프트웨어 제품을 판매하는 것보다 제품을 위한 지원을 판매하는 것에 의지
- 소프트웨어 제품을 판매하는 것보다 제품을 위한 지원을 판매하는 것에 의지
- 오픈 소스 접근법의 채택이 비즈니스 기밀을 유출 가능성으로 인해 꺼리는 회사도 있음
오픈 소스 라이선스
- 오픈 소스 소프트웨어 라이선스 내에 법적 구속 조건을 포함하여 코드가 어떻게
사용되는지에 대한 제약을 둘 수 있음 - 크게 3개의 일반 모델을 바탕
GNU 일반 공중 라이선스
- GPL 라이선스 아래에 있는 오픈 소스 소프트웨어를 이용하면 그 소프트웨어도 오픈 소스
- GPL 라이선스 아래에 있는 오픈 소스 소프트웨어를 이용하면 그 소프트웨어도 오픈 소스
GNU 약소 일반 공중 라이선스
- 오픈 소스 코드와 연결된 컴포넌트들을 작성하면 컴포넌트의 소스를 공개할 필요 없음
- 오픈 소스 코드와 연결된 컴포넌트들을 작성하면 컴포넌트의 소스를 공개할 필요 없음
버클리 표준 배포 라이선스
- 오픈 소스에 가한 어떤 변경이나 수정을 재공개할 의무가 없음
라이선스 관리 - 오픈 사용하는 프로젝트 관리 시 회사에서 해야 하는 일
- 다운로드되고 사용된 오픈 소스 컴포넌트들에 대한 정보를 관리할 시스템 수립
- 서로 다른 유형의 라이선스에 대해 알고 사용 전에 어떻게 컴포넌트가 라이선스 되었는지 이해해야 함
- 컴포넌트의 진화 경로 파악
- 오픈소스에 대하여 사람들을 교육
- 감사 시스템을 제자리에 두어야 함
- 오픈 소스 공동체에 참여하여야 함