본문 바로가기

Open API22

상수 참조로 입력 파라미터 전달 - 함수가 입력 파라미터를 변경하지 않는 상황이라면 포인터보다는 상수 참조를 통해 입력 파라미터를 전달- 반대로 출력 파라미터의 경우 비상수 참조보다는 포인터를 사용- 그 이유는 클라이언트에게 이 변수는 분명히 변경될 수 있다는 것을 알리기 위해서임 C++에서 함수의 파라미터 전달은 "값"으로 처리- 이 말은 함수에 전달하는 객체는 복사되고 복사된 객체는 함수가 결과를 리턴할 때 메모리에서 해제- 원본 객체의 복사 생성자와 소멸자 호출에 대한 오버헤드 발생 * 상수 참조로 객체에 전달- 객체의 포인터만 함수로 전달- 이 메서드는 객체 변경이 불가 - 내장형 타입의 경우에는 굳이 그럴 필요가 없다- 이미 최소한의 공간만을 사용 -> CPU 레지스터에 저장하기에 전혀 부담이 없음- 게다가 STL 반복자와 함.. 2017. 2. 9.
인터페이스의 성능 - 언젠가 성능 문제가 수면 위로 오르면 문제를 쉽게 해결하기 위해 최대한 인터페이스의 성능을 최적화- 요구 사항은 계속 변함- API를 릴리즈한 이후로 언젠가는 코드를 최적화 해야 하는 상황 발생- 성능에 관한 문제를 미리 염두해 두고 하위 호환성을 잘 유지하면서 성능을 개선할 수도 있도록 기반 만들기 - 성능을 개선한다는 이유로 API 본연의 모습을 훼손해서는 안 된다- 대개, 좋은 설계는 좋은 성능을 이끌어 낸다 - API의 성능 개선 작업이 다른 부분에 영향을 미치지 않고 인터페이스도 변경하지 않도로 충분히 주의 * API 성능에 관한 요소 1. 컴파일 타임 속도- API의 컴파일 속도는 클라이언트 프로그램의 컴파일 시간과 관련되며 이는 API 사용자의 생산성에 영향 2. 런타임 속도- API 메.. 2017. 2. 9.
작게 완성하기 - 좋은 API라면 최소한의 크기로 완성- API라면 소수의 클라이언트만 사용하는 기능이라 할 지라도 그것을 제공 - 클라이언트가 API에게 무엇을 바라는지 이해하려면 요구사항 수집과 유스케이스 모델링 - 설계에 기반한 요구사항과 유슼이스 - API를 작게 만드는 것은 API를 사용하는 데도 큰 영향을 미친다- 왜냐하면 간소한 인터페이스는 사용자가 원하는 바를 충분히 만족 - API를 최소화 해서 만들 수 있는 다양한 기법 1. 지나친 약속은 금지2. 가상 함수의 추가는 신중하게3. 편리한 API 2017. 2. 9.
클래스 구현 숨기기 - 클래스의 내부 메서드와 변수를 감추는 것- 구현 코드를 담고 있는 모든 실제 클래스의 내부 코드를 감출 수 있도록 계속해서 노력 - 대부분의 개발자들 역시 메서드와 변수를 감추려고 노력- 그들 중 대부분은 public이 아닌 클래스라는 사실을 잊음- 실제로 어떤 클래스는 오로지 내부 구현을 위해서만 사용될 뿐 API의 public 인터페이스로는 절대 사용되지 않음 - 이런 경우는 내부 클래스로 private에서 정의해서 사용 - 어떤 경우에 내부 클래스는 Getter/Setter 메서드를 사용하지 않는다- 물론 원한다면 사용해도 된다- 필요하지 않는 경우의 클래스는 public 인터페이스로 사용되지 않기 때문 2017. 2. 9.
메서드 구현 숨기기 - 모든 멤버 변수를 노출하지 않는 것과 함께 public으로 선언할 필요가 없는 모든 메서드를 감추는 것도 중요 정보은닉 사용한 프로그램이 그렇지 않은 것 보다 4배 쉬움 * 클래스는 그것이 어떻게 구현될지를 정의하는 것 아니라 무엇을 할 것인지 정의 * 절대로 비상수 포인터나 참조를 private 데이터 멤버로 리턴하지 않는다 이것은 캡슐화를 어기는 행위 * URLDownloader 클래스의 경우 생성자와 DownloadToFile() 메서드를 제외하고 모두 private으로 선언- 그 다음은 메서드를 제대로 구현- 이제 코드를 변경해야 한다 해도 클라이언트에게 미칠 영향을 걱정하지 않고 자유롭게 코드를 수정 - 지금까지는 컴파일러의 관점에서 API의 상세한 구현 코드가 보이지 않도록 노력했다- 하지.. 2017. 2. 9.
멤버 변수 감추기 * 캡슐화- 어떤 데이터가 필요한 메서드에 데이터를 전달하는지를 설명할 때도 사용 - 잘 설계된 API의 관점에서 본다면 멤버 변수를 public으로 선언하는 일은 절대로 하지 말아야 함- 만약 데이터 멤버가 API의 논리적 인터페이스 중 일부라면 멤버 변수가 간접적으로 노출되도록 Getter와 Setter 메서드를 제공 다음은 좋은 방법이 아니다 class Vector3{public: double x, y, z;}; 그렇기 때문에 아래 방법 사용 class Vector3{public: double GetX() const; double GetY() const; double GetZ() const; void SetX(double val); void SetY(double val); void SetZ(doub.. 2017. 2. 9.
물리적 은닉 : 선언 VS 정의 * 정보 은닉 - 클라이언트는 API의 내부적인 구현 내용을 알아서는 안 된다 * 물리적 은닉 vs 논리적 은닉 물리적 은닉 - private 으로 코드를 선언해서 클라이언트가 코드를 사용할 수 없게 만드는 것논리적 은닉 - API의 특정 요소에 접근하지 못하도록 언어의 기능을 활용 * 선언 - 단순히 메모리 할당 없이 이름과 타입을 컴파일러에게 알려줌, 함수 프로토타입 extern int i;class Myclass;void MyFunc(int value); * 정의 - 타입의 상세 구조를 제공하고 변수의 경우 메모리를 할당 int i = 0; class MyClass{public:float x, y, z;}; void MyFunc(int value){ printf("In MyFunc(%d).", va.. 2017. 2. 9.
핵심 객체 모델링 * 객체 지향 설계 또는 객체 모델링- 특정 문제 도메인의 객체의 계층 구조를 설명- 목표 : 주요 객체들을 식별, 각 객체들이 제공해야 하는 동작과 서로의 연결 관계를 확인 예제 : 주소록 API 요구사항 1. 한 사람이 여러 개의 주소를 가질 수 있다2. 한 사람이 여러 개의 전화 번호를 가질 수 있다3. 전화 번호가 유효한지를 체크하고 특정 포맷으로 표현되어야 한다4. 주소록은 같은 이름의 사람을 여러 명 포함할 수 있다5. 기존의 주소록은 수정 가능하다 API의 핵심 객체 모델은 시간이 지나면 변경이 필요하다는 점을 염두에 둬야한다새로운 요구사항이 발생하거나 새로운 기능이 추가되면서 관련 클래스와 메서드들이 변경될 수 있기 때문에 새로운 설계를 통해 객체 모델이 더 개선될 수 있도록 새로운 요구사.. 2017. 2. 3.
문제 도메인 모델 * 좋은 API가 갖추어야 할 기본 품질- 세련된 설계와 높은 가용성 * 정보 은닉, 일관성, 느슨한 연결- 상수 정확도, 네임 스페이스, 생성자 활용 * API 는 문제에 대한 논리적인 추상화를 제공하고 문제를 해결할 수 있어야 한다- 해당 문제 도메인 내에서의 문제 해결은 저수준의 세세한 구현 코드를 그대로 노출하기 보다는 상위 수준에서 이루어져야 한다 - API 문서는 개발자가 아닌 일반 사용자에게도 제공될 수 있으며 실제로 그런 경우에 사용자는 API 인터페이스가 어떻게 동작하는지 그 개념을 이해할 수 있어야 하기 때문이다 - 각각의 클래스는 고유의 목적을 갖고 있어야 하며 클래스와 메서드의 이름을 통해서 그 목적이 드러나야 한다- 그렇기 때문에 초기 단계에 다른 사람의 시선을 통해서 API가 논.. 2017. 2. 1.
서문 * 일반 애플리케이션 개발과 API 개발의 차이점 - API 개발에서는 변경 관리에 대해 더 많은 노력이 필요하다는 사실 - 소프트웨어 개발에서 변경은 피할 수 없는 요소 - 새로운 요구사항, 기능 개발 요청, 그리고 버그 수정 이들 모두는 프로젝트가 처음 시작했을 때 논의되지 않았던 다양한 방법들로 소프트웨어를 발전시김 - 수백명의 최종 사용자 프로그램이 사용 중인 API 에서의 변경이란 커다란 영향력을 발생시키고 심지어는 클라이언트가 API를 더 이상 사용하지 않는 상황까지 초래 - 클라이언트가 필요로 하는 기능을 제공하면서 동시에 새로운 버전이 릴리즈 될 때 가장 이상적인 것은 클라이언트에게 어떤 영향도 미치지 않는 것이지만 이것이 힘든 경우라면 최소한의 영향만을 미치게 하는 것 * 왜 이 책이 필.. 2016. 11. 10.