문제를 해결하기 위해 사용하는 저장소는 장기 기억이 아니라 단기기억이다.
문제 해결에 필요한 요소의 수가 단기 기억의 용량을 초과하는 순간 문제 해결 능력은 급격하게 떨어진다. -> 인지 과부하(cognitive overload)
인류가 복잡한 분야(소프트웨어 개발 영역)의 문제를 해결하기 위해 사용한 것
- 추상화
- 불필요한 정보를 제거하고 현재의 문제 해결에 필요한 핵심만 남기는 작업
- 한 번에 다뤄야 하는 문제의 크기를 줄이는 것
- 한 번에 단기 기억에 담을 수 있는 추상화의 수에는 한계가 있지만 추상화를 더 큰 규모의 추상화로 압축시킴으로써 단기 기억의 한계를 초월할 수 있다.
- 분해(decomposition)
- 큰 문제를 해결 가능한 작은 문제로 나누는 작업
프로시저 추상화와 데이터 추상화
프로그래밍 언어의 발전
- 좀 더 효과적인 추상화를 이용해 복잡성을 극복하려는 개발자들의 노력에서 출발
- 프로그래밍 언어를 통해 표현되는 추상화의 발전 -> 다양한 프로그래밍 패러다임의 탄생으로 이어짐
현대적인 프로그래밍 언어를 특징짓는 두 가지 추상화 메커니즘
- 프로시저 추상화(procedure abstraction) : 프로그램이 무엇을 해야 하는지를 추상화
- 기능 분해(functional decomposition, =알고리즘 분해)
- 데이터 추상화(data abstraction) : 소프트웨어가 무엇을 알아야 하는지를 추상화
- 추상 데이터 타입: 데이터를 중심으로 타입을 추상화
- 객체지향: 데이터를 중심으로 프로시저를 추상화
프로시저 추상화와 기능 분해
전통적인 기능 분해 방법 -> 하향식 접근법
시스템을 구성하는 최상위 기능을 정의하고 좀 더 작은 단계의 하위 기능으로 분해해 나가는 방법
하향식 기능 분해 방법 문제
- 시스템은 하나의 메인 함수로 구성돼 있지 않다.
- 대부분의 시스템에서 하나의 메인 기능이란 개념은 존재하지 않는다.
- 실제 시스템에 정상(top)이란 없다.
- 기능 추가나 요구사항 변경으로 인해 메인 함수를 빈번하게 수정해야 한다.
- 실제 시스템은 여러 개의 정상으로 구성되기 때문에, 새로운 정상을 추가할 때마다 내부 구현을 수정해야 한다.
- 비즈니스 로직이 사용자 인터페이스와 강하게 결합된다.
- 설계 초기 단계부터 입력 방법과 출력 양식을 함께 고민하게 만든다.
- 코드 내에 비즈니스 로직과 사용자 인터페이스 로직이 밀접하게 결합되어 관심사의 분리가 힘들어진다.
- 하향식 분해는 너무 이른 시기에 함수들의 실행 순서를 고정시키기 때문에 유연성과 재사용성이 저하된다.
- what이 아닌 how에 집중하게 만든다. 실행 순서를 정의하는 시간 제약을 강조하게 된다.
- 하위 함수는 상위 함수가 강요하는 문맥 안에서만 의미를 가지기 때문에 결합도가 높고 재사용성이 낮다.
- 데이터 형식이 변경될 경우 파급효과를 예측할 수 없다. 어떤 데이터를 어떤 함수가 사용하고 있는지 추적하기 어렵다.
설계는 코드 배치 방법이며 설계가 필요한 이유는 변경에 대비하기 위한 것이다.
하향식 접근법과 기능분해는 변경에 취약한 설계를 낳는다는 근본적인 문제점을 가진다.
모듈
시스템의 변경을 관리하는 기본적인 전략
함께 변경되는 부분을 하나의 구현단위로 묶고 퍼블릭 인터페이스를 통해서만 접근하도록 만드는 것
-> 즉, 기능이 아니라 변경의 방향에 맞춰 시스템을 분해하는 것
정보 은닉(information hiding)
- 시스템에서 자주 변경되는 부분을 상대적으로 덜 변경되는 안정적인 인터페이스 뒤로 감치려 한다
- 외부에 감춰야 하는 비밀에 따라 시스템을 분할하는 모듈 분할 원리
모듈의 장점과 한계
- 모듈 내부의 변수가 변경되더라도 모듈 내부에만 영향을 미친다.
- 비즈니스 로직과 사용자 인터페이스에 대한 관심사를 분리한다.
- 전역 변수와 전역 함수를 제거함으로써 네임스페이스 오염(namespace pollution)을 방지한다
모듈은 프로시저 추상화보다는 높은 추상화 개념을 제공하지만,
변경을 관리하기 위한 구현 기법이기 때문에 여전히 한계가 있다.
모듈은 인스턴스 개념을 제공하지 않는다. 모든 직원 정보를 가지고 있을 뿐이다
데이터 추상화와 추상 데이터 타입
기존 프로시저 추상화를 보완하기 위해 데이터 추상화 개념이 등장했다.
추상 데이터 타입은 추상 객체의 클래스를 정의한 것으로 추상 객체에 사용할 수 있는 오퍼레이션을 이용해 규정된다.
클래스
클래스 vs 추상 데이터 타입
- 클래스는 상속과 다형성을 지원하는 데 비해 추상 데이터 타입은 지원하지 못한다
- 객체지향 프로그래밍(Object-Oriented Programming) : 상속과 다형성 지원
- 객체기반 프로그래밍(Object-Based Programming) : 상속과 다형성을 지원하지 않는 추상 데이터 타입 기반의 프로그래밍 패러다임
- 추상 데이터 타입 : 오퍼레이션을 기준으로 타입을 묶는 방법
- 객체지향 : 타입을 기준으로 오퍼레이션을 묶는다.
개방-폐쇄 원칙(Open-Closed Principle, OCP)
- 기존 코드에 아무런 영향도 미치지 않고 새로운 객체 유형과 행위를 추가할 수 있는 객체지향의 특성
- 객체지향 설계가 전통적인 방식에 비해 변경하고 확장하기 쉬운 구조를 설계할 수 있는 이유