라이브러리 만들 때 유의사항

panda005의 이미지

라이브러리를 만들 때 어떤 유의사항들이 있을까요...
정리된 것을 찾지 못 해서
제가 그간 개발하면서 느꼈던 라이브러리 만들 때 주의사항을 정리해봅니다.
의견 있으신 분들 댓글 달아주세요~

1. 캡슐화
좀 구질구질하게 만든 라이브러리를 보면 헤더 파일이 무지 많은 경우가 있습니다.
그런 걸 보면 라이브러리를 사용해서 뭔가를 만들어보는 사람들은 한숨부터 납니다.

라이브러리는 헤더 파일 및 심볼이
외부로 노출되어야 할 것과 캡슐화 되어야 할 것을 구분한 후에,
정말 필요한 정보들만 라이브러리 외부로 노출시켜서 보는 사람이 편하게 하는 것이 좋습니다.

외부로 노출이라 함은 헤더 파일에 선언된 것들일 수도 있고,
extern으로 선언된 함수일 수도 있습니다.

2. 오브젝트 묶기
정적 라이브러리를 만들어서 링킹할 때,
아카이브에 있는 심볼들을 오브젝트 단위로 링킹하게 됩니다.

만약 경우에 따라서는 링크할 필요가 없는 심볼들도,
같은 오브젝트에 존재할 경우에 모두 링크되어
바이너리 파일의 크기를 증가시킬 수 있습니다.

따라서 가급적이면 함수 플로우에 연관성이 강한 함수들끼리 같은 오브젝트로 묶고
그렇지 않은 것은 분리하여 놓으면 더 효율적입니다.

3. 명명 규칙
대소문자를 혼합하여 쓴다던지
_로 구분한다던지
명명사전을 이용해서 약어로 표현한다던지
그건 해당 프로젝트의 명명 규칙을 따르면 됩니다.

다만, 라이브러리라 함은 별도의 독립된 실행파일이 아니기 때문에
다른 라이브러리나 오브젝트와 충돌이 생길 수 있습니다.
따라서 해당 라이브러리의 고유한 이름을 함수명, 타입명, define명 등의 prefix에 붙여주는 것이
이러한 충돌을 예방할 수 있는 지름길입니다.
static은 별 상관없겠지만요...

4. 예외처리
물론 예외처리는 모든 프로그래밍에서 중요한 일이겠습니다만,
라이브러리는 자신이 만들고 타인이 땡겨다 쓸 수 있기 때문에 예외처리가 더욱 중요합니다.
절대 라이브러리 중간에 exit문들 넣어서는 안 되며,
적절한 리턴값을 리턴해서 메인 프로그램에서 에러 여부를 판단하도록 해야 합니다.
리턴값을 리턴할 때는 무슨 에러인지를 판단할 수 있도록 잘 구분해주어야 하고요...
그리고 입력값에 대한 검사를 철저히 해야 합니다.
어떤 메인 프로그램이 붙느냐에 따라서 입력을 예상할 수 없는 경우가 많기 때문에,
모든 입력값에 대해서 발생가능한 예외를 체크해야 합니다.
또한 로깅이나, 파이프 출력은 자제하시는 것이 좋습니다.

5. 쓰레드 세이프
라이브러리는 어떤 메인 붙을 지 모르므로,
가급적이면 쓰레드 세이프하게 구현하는 것이 좋습니다.
localtime -> localtime_r
strtok -> strtok_r
이런 것들이 좋은 예가 되겠지요

6. 독립성
라이브러리는 가급적이면 타 라이브러리/프로그램과 의존성을 갖지 않고
독립성을 유지하는 것이 더욱 보편적이고 좋습니다.

gamdora의 이미지

4. 로깅을 자제하라는 말은 라이브러리에서 로그 파일을 만들어 쓰면 안 된다는 말인가요?

5. 성능을 위해 쓰레드에 안전한 API와 그렇지 않은 API를 둘 다 제공하는 것은 어떨까요?

좋은 글 보고 갑니다. :)

ljs0766의 이미지

로그파일을 생성하는 라이브러리가 있는데 라이브러리를 init하면 스레드를 생성해서 작동합니다.
이 라이브러리가 생성하는 로그와 메인 프로세스에서 생성하는 로그가 뒤죽박죽 되는 경우가 생기더군요..
로그레벨 설정도 까다롭고요...그런 이유로 해당 라이브러리를 사용할 경우 로그관련 라이브러리쪽 소스를
메인스레드쪽 소스파일에 포함시키고 라이브러리쪽과 충돌이 나지않도록 변경해서 사용하는 번거로움이 발생하더군요.
저희 회사 소스관리나 개발방법론이 좀 원시적이라 -ㅁ-; 생긴 문제인듯 합니다.

panda005의 이미지

바로 위에 ljs0766님이 쓰신 말과 비슷한 맥락으로 썼습니다.
로그 파일에 로그를 남기는 것은,
각 프로그램마다 추구하는 로그 포맷이나 정책이 다를 수 있기 때문에,
라이브러리에서 이것을 직접 로깅하기 보다는 적절한 리턴값과 에러 메시지를 던져줌으로써
메인 프로그램에서 알아서 남기게 하는 것이 좋습니다.

5번은 gamdora님 말씀대로 2가지 API를 모두 제공하는 것도 좋은 방법일 것 같습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.