목차
- ☆ 표시가 붙은 부분은 스터디 중 나온 얘기 혹은 제 개인적인 생각이나 제가 이해한대로 적어놓은 것으로, 책에 나오지 않는 내용입니다. 따라서 책에서 말하고자 하는 바와 다를 수 있습니다.
- 모든 이미지의 출처는 디자인패턴의 아름다움(왕정 저) 책 입니다.
2.1~2.2 정리 글 : 링크
2.3 객체지향 분석, 객체지향 설계, 객체지향 프로그래밍을 수행하는 방법
- ☆ 예제를 가지고 설명하는 부분이기도 하고, 2.3에 나온 예제가 그리 좋은 예제가 아니라고 생각하다보니, 내용 정리 시 책에 쓰여진 말을 제 생각대로 많이 축약 시켰습니다. 그래서 제가 잘못 이해한 경우, 2.3의 내용정리 부분은 책이 전달하고자 하는 내용과 다를 수 있습니다.
예제 소개와 난이도 분석
- HTTP 인터페이스를 노출하는 마이크로 서비스 개발에 참여하는 상황
- 이 때, 인터페이스 호출의 보안을 보장하기 위해 인터페이스 호출의 인증 기능을 설계해서 구현해달라는 요구사항이 들어왔다.
- 위의 요구사항은 다소 모호하고 너무 일반적인 내용이라 설계 및 구현을 할 수 있을 정도로 상세하지 않다.
- 또한 인증 기능의 개발은 더 어렵다. 이러한 기능에 대한 교육 경험이 많지 않을 것이며, 상대적으로 일반적인 개발 요구 사항에 직면하면 경험 부족으로 인해 어디서부터 시작해야 할지 모를 수 있다.
객체지향 분석 수행 방법
- 객체지향 분석을 풀어서 이야기하면 '요구 사항 분석' 이라고 할 수 있다.
- 요구 사항 분석 프로세스는 지속적인 반복 최적화 프로세스다.
- 대략적인 기본 계획을 제공한 다음 단계별로 천천히 반복적으로 최적화해야 한다.
1. 기본 분석
- 인증 시 사용자 id와 암호화 되지 않은 비밀번호 사용
2. 1차 분석
- '1'의 방법은 비밀번호가 도용되기 쉽다.
- 그렇다면 비밀번호를 SHA와 같은 암호화 방식으로 암호화하면 안전할까? 이 경우에도 리플레이 공격을 당할 수 있다.
- 이러한 문제들은 OAuth 인증을 이용하여 해결할 수 있다.
3. 2차 분석
- '2'는 여전히 리플레이 공격에 당할 위험이 있어서 안전하지 않다.
- 시간값 등을 사용해 랜덤 변수를 도입하여 인터페이스 요청이 이루어질 때마다 생성되는 토큰을 매번 다르게 할 수 있다.
- 시간값을 넣어 유효 시간 내에 토큰이 생성된 것인지 확인하도록 하자.
4. 3차 분석
- 토큰 유효 시간이 만료되기 전에 요청을 가로채 인터페이스를 호출할 가능성이 남아있기 때문에 여전히 보안에 문제가 있다.
- 하지만 절대적인 보안 시스템은 존재하지 않는다.
- 이 설계는 보안, 개발 비용, 시스템 성능에 미치는 영향을 고려했을 때 이 정도까지가 합리적인 절충안이라고 볼 수 있다.
객체지향 설계 방법
- 객체지향 분석이 완료되면 상세한 요구 사항 명세를 얻을 수 있으며, 객체지향 설계가 완료된 결과는 클래스 설계이다.
- 객체지향 설계는 요구 사항 명세를 특정 클래스 설계로 변환하는 작업이다.
- 객체지향 설계 프로세스
- 책임과 기능을 나누고 어떤 클래스가 있는지 확인한다
- 클래스를 정의하고, 클래스의 속성과 메서드를 정의한다.
- 클래스 간의 상호 작용을 정의한다.
- 클래스를 연결하고 실행 엔트리 포인트를 제공한다.
1. 책임과 기능을 나누고 어떤 클래스가 있는지 확인한다.
- 요구 사항 명세에 따라 관련된 기능들을 하나씩 나열한 후, 어떤 기능들이 유사한 책임을 지고 동일한 속성을 사용하는지 확인하는 방법으로 클래스를 분류하는 방법을 추천한다.
- 이 예시와 달리 대규모 프로젝트인 경우 요구 사항에 따라 기능을 나열하다 보면 매우 긴 목록이 생성되며, 결국 지저분할 뿐만 아니라 불규칙하게 보인다. 이 경우 먼저 모듈을 나누고, 요구 사항을 여러 개의 작고 독립적인 기능 모듈로 나누는 작업이 선행되어야 한다.
- 요구 사항 명세를 단일 책임(SRP) 기능으로 분해한다. (요구 사항 명세 -> 기능 목록)
- 1), 2), 6), 7) 항목의 기능을 담당하는 AuthToken / 3), 4) 항목의 기능을 담당하는 Url 클래스 / 5) 항목의 기능을 담당하는 CredentialStorage 클래스의 세 가지 핵심 클래스가 될 것이다.
2. 클래스, 클래스의 속성과 메서드 정의
- '1'에서 요구 사항 명세를 분석하여 세 가지 핵심 클래스가 필요하다는 것을 알았다.
- 이제 각 클래스에는 어떤 속성과 메서드가 있는지 살펴봐야 한다.
3. 클래스 간의 상호 작용 정의
- UML에는 일반화, 실체화, 집합, 합성, 연관, 종속과 같이 여섯 가지 클래스 상호 작용이 정의되어 있다. 하지만 사실 불필요할 정도로 세부적이기 때문에 모두 사용할 필요는 없다.
- 이 책에서는 일반화, 실체화, 합성, 의존의 네 가지만 남겨둘 것이다.
- ☆ 일반화는 extends, 실체화는 implements, 합성은 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 사용하는 것, 의존은 아무튼 결합도를 가지는거 (함수에서 다른 인스턴스를 받는 경우도 포함) 정도로 보면 맞을 것 같다.
4. 클래스 연결 및 실행 엔트리 포인트 제공
- 클래스와 클래스 간의 상호 작용을 설계했다면, 이제 모든 클래스를 함께 조합하고 실행 엔트리 포인트를 제공할 차례다.
- 엔트리 포인트는 main() 함수일 수도 있고, 외부 호출을 위한 API 모음일 수도 있다.
객체지향 프로그래밍을 하는 방법
- 객체지향 설계가 완료되면, 클래스, 속성, 메서드, 클래스 간의 상호 작용을 정의하고 모든 클래스를 조합하여 통합된 엔트리 포인트가 준비된 상태가 된다.
- 객체지향 프로그래밍 작업은 이러한 설계 사상을 코드로 실체화하는 것이다.
2.4 객체지향 프로그래밍, 절차적 프로그래밍, 함수형 프로그래밍의 차이
절차적 프로그래밍
- 절차적 프로그래밍은 프로그래밍 패러다임이기도 하다. 코드를 구성하기 위한 기본 단위로 메서드, 기능, 연산처럼 절차가 필요하다.
- 절차적 프로그래밍 스타일은 순서대로 실행되는 메서드들을 나열하여 데이터를 조작하고, 이를 통해 기능을 구현하는 프로그래밍 스타일이다.
- ☆ 기존 어셈블리어 같은게 순차지향 (sequential oriented -) 였는데, 그 후에 C 같은게 절차지향 (procedural oriented -)임. 한글로 '절차지향' 이라고 하면 사실 저 sequential이 더 가깝게 느껴져서, 약간 오역이라고 봄. 오히려 프로시져, 즉 함수지향에 가깝지 않나 생각됨. 책에서도 63page에 "객체지향 프로그래밍의 가장 큰 특징은 함수를 단위로 사용하여" 라는 부분이 있음.
객체지향 프로그래밍과 절차적 프로그래밍의 비교
1. 객체지향 프로그래밍은 대규모의 복잡한 프로그램 개발에 더 적합하다
- 간단한 프로그램을 개발하는 경우, 절차적 프로그래밍 스타일과 객체지향 프로그래밍 스타일 중에서 어느 것을 사용하더라도 구현되는 코드에서 큰 차이를 발견하기 어렵다.
- 그러나 복잡한 대규모 프로그램을 개발하는 경우, 전체 프로그램의 처리 흐름이 복잡하고 작업 흐름이 여러 개로 구성된다. 이 흐름을 그림으로 표현하면 그물망이나 나뭇가지처럼 여러 방향으로 얽혀 있는 모습이 된다. 이러한 구조를 굳이 절차적 프로그래밍의 프로세스 지향적이고 선형적인 사고방식에 끼워 맞춰 프로세스로 만든다면 훨씬 더 많은 노력과 시간이 필요하게 될 것이다.
- ☆ 알고리즘 문제 풀 때만 봐도, 일반적으론 대부분의 사람들이 절차지향 방식으로 코드를 짠다. 하지만 '백준의 RPG Extreme' 같은 복잡한 문제를 풀게되면 대부분 본능적으로 객체지향으로 문제를 풀게 된다. 절차지향으로 짜려면 많이 복잡하니깐.
- 절차적 프로그래밍 언어로 객체지향 프로그래밍 스타일의 코드를 작성할 수는 있지만 객체지향 프로그래밍 언어로 작성하는 것보다 훨씬 더 많은 비용이 들 수 있다.
- ☆ 해봤는데, 확실히 훨씬 더 짜기 어렵다. '[자료구조] C언어 - 이중 연결 리스트(doubly linked list) 구현 - 객체지향' - 리눅스 커널 VFS 쪽 코드와 비슷하게 객체지향 개념을 넣어 C로 짜본 연결 리스트 코드
2. 객체지향 프로그래밍 스타일의 코드는 재사용, 확장, 유지 관리가 쉽다
- 캡슐화는 객체지향 프로그래밍과 절차적 프로그래밍의 근본적인 차이점이다.
- 접근 제어를 통해 외부 호출자만이 클래스에 의해 노출되는 제한된 메서드를 통해 데이터에 접근할 수 있다. -> 유지 관리성을 향상
- 절차적 프로그래밍과 객체지향 프로그래밍 모두 추상화를 지원한다. 그러나 객체지향 프로그래밍은 인터페이스를 기반으로 하는 추상화 등과 같은 더 나은 추상화를 제공한다.
- 다형성으로 특정한 함수 구현을 수정해야 하는 경우 새 하위 클래스를 구현하여 기존 함수를 재정의할 수 있으며, 상위 클래스를 하위 클래스로 대체할 수 있다.
3. 객체지향 프로그래밍 언어는 더 사용자 친화적이고 고급 언어이며 지능적이다
- 이진 명령, 어셈블리 언어, 절차적 프로그래밍 언어는 컴퓨터의 사고방식을 사용하는 반면, 객체지향 프로그래밍 언어는 인간의 사고방식을 사용한다.
- 기계를 다루는 방법에 대해 생각하기보다 비즈니스 자체에 집중할 수 있다.
- 프로그래밍 언어가 발전할수록 기계에서 멀어지고 인간과 가까워지며, 이렇게 변경할수록 더 지능적인 언어라고 할 수 있을 것이다.
함수형 프로그래밍
- 함수형 프로그래밍을 독특하게 만드는 것은 프로그래밍 철학이다. 함수형 프로그래밍에서는 프로그램이 일련의 수학적 함수 또는 표현식의 조합으로 표현될 수 있다고 생각한다.
- 이론적으로는 가능하지만 모든 프로그램이 이에 적합한 것은 아니다. 비즈니스와 매우 강한 연관이 있는 대규모 비즈니스 시스템 개발을 할 때, 수학적 표현으로 힘들게 추상화하고 그것을 구현하기 위해 함수 프로그래밍을 사용해야 한다면 분명히 문제가 발생할 것이다.
- 비즈니스와 밀접한 관련이 있는 대규모 비즈니스 시스템의 개발 시나리오에서는 코드가 더 읽기 쉽고 유지 관리가 용이한 객체지향 프로그래밍이 더 적합하다.
- 함수형 프로그래밍의 함수 : 함수가 상태를 가지고 있지 않은 stateless function. 즉, 함수에 포함된 변수는 클래스 멤버 변수를 공유하는 객체지향 프로그래밍과 전역 변수를 공유하는 절차 프로그래밍과 달리 지역 변수다. 동일한 입력 매개변수를 어떻게 실행하든 그 결과는 동일하다.
- 자바에서 제공하는 함수형 프로그래밍 : Stream, 람다 표현식, 함수형 인터페이스
객체지향 프로그래밍과 함수형 프로그래밍의 비교
- 절차지향 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍 모두 변수와 함수의 개념을 가지고 있다. 그리고 클래스나 함수와 같은 프로그래밍 단위를 갖추고 있다.
- 그러니 객체지향 프로그래밍의 프로그래밍 단위는 클래스 또는 객체이고, 절차적 프로그래밍의 프로그래밍 단위는 함수이며, 함수형 프로그래밍의 프로그래밍 단위는 스테이트리스 함수라는 점이 다르다.
- 함수형 프로그래밍은 컴퓨터 과학, 데이터 처리, 통계 분석과 같은 특수한 분야에서만 그 장점을 충분히 발휘할 수 있다.
'Study > 디자인 패턴의 아름다움' 카테고리의 다른 글
[디자인 패턴의 아름다움] 3. 설계 원칙 - 3.1~3.5 정리 (SOLID) (1) | 2024.04.13 |
---|---|
[디자인 패턴의 아름다움] 2. 객체지향 프로그래밍 패러다임 - 2.8~2.9 정리 (0) | 2024.04.06 |
[디자인 패턴의 아름다움] 2. 객체지향 프로그래밍 패러다임 - 2.5~2.7 정리 (1) | 2024.04.05 |
[디자인 패턴의 아름다움] 2. 객체지향 프로그래밍 패러다임 - 2.1~2.2 정리 (0) | 2024.03.03 |
[디자인 패턴의 아름다움] 1. 개요 (4) | 2024.02.24 |
댓글