2015. 3. 17. 18:04

네트워크 스위치와 라우터의 차이는 무엇인가? (What is a Network Switch vs. a Router?)

두가지 장비는 비슷해 보이고, 또한 유사한 기능을 제공하지만, 두 기기는 네트워크 상에서 뚜렷이 구분되는 기능을 수행한다.

 

네트워크 스위치란 무엇인가?

기본적으로 네트워킹을 이해하기 위해선, 다음과 같은 질문에 답해야만 한다. "네트워크 스위치란 무엇인가?"

대다수의 현대 비즈니스 네트워크는 빌딩이나 대학 캠퍼스 내에서 컴퓨터, 프린터 및 서버들을 연결하기 위해서 스위치를 사용한다. 스위치는 컨트롤러(controller)의 기능을 수행하며, 네트워크 디바이스들이 서로간에 효율적으로 대화할 수 있게끔 한다. 정보를 공유하고 자원을 할당하는 기능을 제공함으로서 스위치는 비즈니스 비용을 감소시키고, 직원들의 생산성을 증가시킨다.


서로 다른 타입의 이더넷 스위치(Ethernet switches)와 기능을 이해해보자.


비관리형 스위치 (Unmanaged Switches)

비관리형(unmanaged) 스위치는 개봉 후 즉시 사용 가능하게끔 만들어져 있다. 아예 설정할 수 없게끔 설계되었으며, 따라서 설치하거나 제대로 설정하기 위해 고민할 필요가 없다. 비관리형 스위치는 관리형 스위치 보다 네트워크 용량(허용치)이 낮다. 일반적으로 홈 네트워킹 기기에서 비관리형 스위치를 발견할 수 있다. 


관리형 스위치 (Managed Switches)

관리형 스위치는 설정 가능하며, 좀 더 유연하며  높은 용량을 가진다. 관리형 스위치는직접 혹은 원격으로 모니터링 가능하고, 설정을 조정함으로써 네트워크를 제어할 수 있다.


네트워크 스위치와 라우터의 차이는 무엇인가?

스위치는 네트워크를 만들어낸다. 라우터는 네트워크들을 연결한다. 라우터는 컴퓨터를 인터넷에 연결하여 사용자들을 연결해 준다. 라우터는 분배기(dispatcher)처럼 동작하며, 정보가 가장 빠르게 전달될 수 있도록 가장 적합한 경로를 선택한다.

  

네트워크 스위치와 내 비즈니스의 상관관계

스위치와 라우터는 데이터, 음성, 비디오 뿐만 아니라 무선 접속을 아우르는 비즈니스 통신을 구축하기 위한 블록(building blocks)이다.


출처 : 시스코 홈페이지  


추가 정보

  • Switch (넑은 의미) : L2, L3, L4, L7 Switch 등 대부분의 in-path 네트워크 장비를 일컷는 말.
  • Switch (좁은 의미) : L2 Switch로 L2 주소(Mac)를 기반으로 패킷을 스위칭해 주는 장비.
  • Router : L3(IP)주소를 가지고 라우팅(이 경우 스위칭이라 하지 않고 라우팅이라고 함)해 주는 장비로 L3 Switch라고도 함.
  • 흔히 사용하고 있는 공유기를 L4 switch라고 한다. 왜냐 하면 공유기(NAT)는 ip(L3)뿐만 아니라 port(L4)까지 관리해야 하니까.

관련 문서



Posted by 곽중선
2015. 3. 17. 02:11

▶  온라인 저지 (Online Judge)

프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳


▶  알고리즘 추천 도서


▶  정구진님 추천 사이트

  • https://algospot.com/calendar/ 
    알고스팟 사이트 자체도 괜찮구요. 캘린더 들어가 보시면 알고리즘 대회 스케쥴이 있어요. 가볍게 참가 해 보시면 어느새 열정적으로 하고 있는 자신을... 주로 스케쥴 잡혀있는게 코드포스 랑 탑 코더 인데 둘다 굉장히 짧은 주기로 자주 열고 있습니다. (2-3주) 시차 감안해서 시간 될 때 얼마든지 참가 가능하구요. 코드포스는 제가 알기론 러시아 사이트 인데 문제 풀 때 번역기를 돌려도 이해가 좀 어렵지만 탑코더도 문제가 영어라 문제 이해를 하는데 시간이 조금 걸리더라구요.

  • http://www.topcoder.com/
    탑코더는 정말 유명하죠. 스폰하고 있는 기업만 보더라도 그 위치가 어느정도 인지 알수 있습니다. 들어가자마자 뜨는 합격 수기 같은거 보면 살짝 흥분도 되죠. 디자인하고 소프트웨어, 머신러닝 세가지 주제로 운영중이고 재밌는게 SW 클라우드 소싱을 제공합니다. 이 안에서 할수 있는게 굉장히 많죠. 말씀하신 알고리즘도 안에 있어서 이 안에서 오래 머물 수 있습니다. 알고리즘 하다 지겨우시면 클라우드 소싱을 통해 직접 돈도 버실수 있죠. 능력에 따라 벌수 있는 돈은 천지차이로 나열되어 있습니다. 이 자체로도 충분한 동기부여가 될수 있죠. 

  • https://www.hackerrank.com/contests
    이전에 페이스북 개발자 채용에 한 과정이였는지 확실하지 않은데 페이스북 퍼즐 문제 가 있었습니다 지금은 문을 닫았는데 문을 닫고 내놓은 링크가 이 사이트 입니다. 알고리즘 패턴 별로 굉장히 잘 정리되어 있어서 원하는 유형의 문제를 풀고자 할때 굉장히 좋아요. 사이트 자체 규모가 어느정도 인지는 모르겠으나 한국인은 거의 없는 거 같더군요. 문제별 랭킹도 제공하고 토탈 랭킹도 있습니다. 웹에서 컴파일하고 결과 볼수 있는 사이트들이 많듯이 여기도 원하는 언어로 문제 풀고 바로바로 결과를 피드백 받아볼 수 있어요. 처음하실 때 인풋이 어떻게 들어오는가를 잘 보셔야 합니다. 로컬에서 똑같이 했을 때는 되는데 통과를 못하는 경우가 종종 생기더라구요. 페이스북과 이 사이트의 관계는 잘 모르겠으나 관계 상관없이 정말 좋은 사이트라고 생각됩니다.

  • http://www.comp.nus.edu.sg/~stev.../visualization/index.html
    싱가폴에 한 대학교 에서 만든거 같은데 아예 모르는 경우나 알고 있다가 까먹은 경우나 두가지 모두 유용하게 사용할수 있는 사이트 입니다. 알고리즘 자체도 psuedo code로 간략하게 설명해 놓았고 어떻게 돌아가는지 직접 확인 가능합니다. (첨언 : 아래의 VisualGo 와 동일한 사이트입니다.)

▶  영어 알고리즘 온라인 강의 사이트 ( [출처] 알고리즘 학습 자료 모음|작성자 낙투르 )



▶  PDF / Website


▶  기타 추천 사이트

  • Coding is fun
    장원영 님께서 직접 제작하신 사이트. 알고리즘을 배우기 보다는 한국 정보 올림피아드 기출문제를 푸는 편이라고 합니다.

  • 구글 코드 잼
    구글 코드잼은 구글에서 매년 진행하는 알고리즘 경진대회입니다. 아웃사이더 님의 참가 후기를 읽어 보시는 것을 추천합니다.

  • 프로젝트 오일러
    프로젝트 오일러 (ProjectEuler.net) 는 수학적인 문제들을 컴퓨터 프로그래밍으로 하나씩 해결해가는 퀴즈 풀이 사이트입니다. 프로젝트 오일러 코리아 사이트 (Project Euler @ kr) 에서는 보다 많은 이들이 쉽게 접근해서 즐길 수 있도록 원본 문제를 한국어로 번역해서 제공합니다.

  • VISUALGO
    : VisuAlgo 는 2011년 Steven Halim 박사가 자신이 가르치는 학생들이 데이터 구조와 알고리즘을 좀 스스로 이해하고, 자신만의 학습속도에 따라서 공부할 수 있도록 하기 위해 고안한 것입니다. 싱가폴 국립대학교의 학생들과 함께 간단한 정렬 알고리즘부터 복잡한 그래프 자료구조, 알고리즘, 문자열+위상 알고리즘까지 통합한 시각화된 자료들을 개발했습니다.

  • http://coderbyte.com
    : Coderbyte 는 다양한 프로그래밍 문제 모음을 통해 프로그래밍을 연습하고 기술을 향상할 수 있도록 도와주는 웹 어플리케이션입니다. 문제들은 다양한 난이도로 제공하고 있으며 온라인 어플리케이션 내에서 학습할 수 있도록 되어 있습니다. 아무것도 다운로드 하거나 업로드할 필요가 없습니다. Javascript, Python, Ruby, PHP, Java, C++ 등의 언어로 문제를 풀어볼 수 있습니다.

  • http://www.checkio.org/
    : 알고리즘을 게임 형식으로 좀 더 재미있게 공부할 수 있게 해주는 사이트이며, 한글 인터페이스가 제공됩니다. 문제를 풀면 좀 더 어려운 문제를 푸는 스테이지(stage)가 열립니다.

  • 알고리즘 오픈마켓
    : 알고리즘을 사고 파는 시장!

  • 코딩 도장
    : 코딩 도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

  • What makes good programmer
    : 좋은 프로그래머가 되기 위해 알아야 할 것들 (컬럼)

  • API Academy
    : '좋은 API 만드는 방법'을 배우는 온라인 학습 사이트


Posted by 곽중선
2015. 3. 16. 22:45

로깅(logging)은 "비 기능 요구사항(Non Functional Requirement)"에 속한다. 그러나 고객의 요구 여부에 상관없이 로그 출력 기능은 프로그램 개발 중 디버깅 및 개발 완료 후 문제 발생 시 원인 분석을 위해 좋은 프로그램이 필수적으로 갖추어야 하는 요구조건에 속한다.


로깅이란 무엇인가? How To BeAProgrammer 발췌


로그 기록(logging)이란 정보를 제공하는 일련의 기록인 로그(log)를 생성하도록 시스템을 작성하는 활동을 말한다. 프린트 줄 넣기(printlining)는 간단한, 보통은 일시적인, 로그를 생성하기만 한다. 완전한 초보자들은 프로그래밍에 대해 아는 것에 한계가 있기 때문에 로그를 이해하고 사용해야 한다. 시스템 설계자들은 시스템의 복잡성 때문에 로그를 이해하고 사용해야 한다. 로그가 제공하는 정보의 양은, 이상적으로는 프로그램이 실행되는 중에도, 설정 가능해야 한다. 일반적으로 로그 기록은 다음의 이점이 있다.

  • 그는 재현하기 힘든 (예를 들어, 개발 완료된 환경에서는 발생하지만 테스트 환경에서는 재현할 수 없는) 버그에 대한 유용한 정보를 제공할 수 있다.
  • 로그는, 예를 들어, 구문(statement)들 사이에 걸리는 시간과 같이, 성능에 관한 통계와 정보를 제공할 수 있다.
  • 설정이 가능할 때, 로그는 예기치 못한 특정 문제들을 디버그하기 위해, 그 문제들을 처리하도록 코드를 수정하여 다시 적용하지(redeploy) 않아도, 일반적인 정보를 갈무리할 수 있게 한다.


    자바에서 로그를 출력하는 방법

    초보자들은 System.out.print() 메소드를 이용해 실행 중 다양한 입출력 및 변수 값들을 출력한다. System.out.println 명령은 출력되는 로그의 양(혹은 수준)을 조절할 수가 없고, 표준출력(standard out)을 통해 출력하는 것은 로그를 파일 등에 저장하기도 불편하고 성능 면에서도 낮은 편에 속한다.


    자바 개발자를 위한 로깅 라이브러리는 이미 다양하게 개발되어 있기 때문에 직접 로그 출력 기능을 개발하는 것은 무의미하다. 다만, 다양한 라이브러리 중에서 적합한 것을 고르는 안목이 필요하다. 


    널리 쓰이는 로그 출력 라이브러리

    다양한 오픈 소스 로그 라이브러리가 존재하지만, 그 중에 널리 쓰이는 것들이 있기 마련이다.

    • java.util.logging
      JDK(Java Development Kit) 1.4 버전부터 자바에 포함된 표준 로그 API 이다. 별도의 라이브러리를 추가할 필요가 없다는 점이 장점이나, 다른 것들이 더 많이 사용되는 이유는 아마도 제공하는 기능이 가장 적다는 이유 때문일 것이다.
      Java Doc 혹은 Java Logging API - Tutorial 사이트를 참조하길 바란다.

    • Apache Commons logging
      아파치 재단(Apache Foundation)이 웹 서버(Apache Web Server)나 톰캣(Apache Tomcat) 서버만 제공하는 것이 아니다. 오히려, 아파치 재단에서 제공하는 다양한 오픈 소스 자바 라이브러리들이 아파치 재단의 영향력을 잘 보여준다. 그중에서 Commons 라이브러리는 프로그램의 기초를 단단히 다지고자 하는 학생에서는 멋진 도서관이다. Commons 라이브러리 중에서 로그 출력 기능을 제공하는 라이브러리가 Commons Logging 이다. Apache Commons logging 공식 홈페이지를 참조하길 바란다.

    • Log4j
      재밋는 사실은 아파치 재단에서 제작되는 로그 라이브러리가 하나 더 있다는 점이다. log4j 는 로그 라이브러리 중에서 가장 성공적이고 널리 사용된 라이브러리일 것이다. (공식 통계는 없지만....) Log4j 공식 홈페이지는 역시 아파치 사이트 중 하나이다. 참고로 Log4j version 2 부터는 JAVA 6 이상을 필요로 한다.

    • Logback
      Log4j를 만드신 분은 Ceki Gülcü 인데, Log4j를 만들어 놓고 더 좋은 라이브러리를 새로 만들게 된 것이 logback 이다. 오픈 소스 진영은 이렇듯 "창조적 파괴"가 빈번히 일어나기 때문에, 이미 잘 알고 있거나 오래도록 쓰고 있던 기술이 있더라도 항상 더 나은 기술이 나오지는 않았는지 살펴보는 주의력이 필요하다. 자칫 뒤떨어지기 마련이다. Logback 홈페이지는 다른 라이브러리에 비해서 매뉴얼이 상세한 편이다. 그만큼 제공하는 기능이 많다는 점은 확실히 부담스럽다.

    • 세상의 모든 로그 라이브러리
      남들이 쓰지 않는 특이한 것에 관심이 있다면 거의 모든 오픈 소스 로그 라이브러리 목록 : 
      Open Source Logging in Java 을 참고하면 된다.

    로그 라이브러리를 갈아끼울 수는 없을까?
    컴퓨터에 설치된 소프트웨어는 언제나 지우고 다른 제품을 설치할 수 있다. 그렇다면, 로그 라이브러리도 필요에 따라 갈아끼울 수는 없을까? 이런 생각을 하는 사람들이 분명 있다. 앞서 설명한 바와 같이 오픈 소스 진영에서 계속 새로운 라이브러리가 나오고 있으니 말이다.
    로그 라이브러리를 갈아 끼울 수 있게 만드려면 무엇이 필요할까? 혹은 어떤 선행 조건이 필요한가? 전기 콘센트에는 TV, 냉장고, 세탁기, 그외에 다양한 전자제품을 연결할 수 있다. 콘센트와 플러그가 호환만 된다면 말이다. 플러그는 제품에 붙어 있지만, 콘센트는 항상 벽에 붙여 있다. 이렇듯 프로그램에서 콘센트 역할을 하는 모듈과 플러그 역할을 하는 모듈을 분리하면 언제든 기능을 교체할 수 있다.

    그래서 콘센트 역할 - 이것을 디자인 패턴에서 사드(facade) 패턴이라고 한다 -을 하는 라이브러리가 나오게 되었고 SLF4J 라고 한다. SLF4J 자체는 로그를 출력하는 기능을 제공하는 것이 아니다. (콘센트가 있다고 저절로 냉장고가 생기는게 아닌 것처럼...) 하지만, 다양한 로그 라이브러리를 골라가며 쓰고 싶다면 한번쯤 공부해볼 만한 기법이다. 실제로 다양한 오픈 소스 제품들이 SLF4J를 활용하고 있다.


    그외에 읽을만한 거리...

    로거(logger)쯤은 이미 잘 활용하고 있기에 끝까지 한 달음에 읽었다면 다음 글들도 한 번 읽어보시길 권한다.

    logback을 사용해야 하는 이유

    아키텍처 설계: Logback을 활용한 Remote Logging


    SLF4J 로깅 처리


    Logging framework logback

    Posted by 곽중선
    2015. 3. 16. 16:00

    문서(혹은 파일)을 저장하는 메커니즘을 설계하기 위해 "문서관리시스템 (EDMS : Electronic Document Management System)" 관련 기술을 구글에 검색하니, 스택오버플로우(stackoverflow) 사이트에 아래와 같은 질의 응답이 올라와 있는 것을 발견했다. 한 때, EDMS 와 그룹웨어(groupware) 제품을 개발했었는데, 한동안 다른 일을 하다보니 최신 표준과 기술 변화를 감지하지 못한 것을 반성한다. 돌다리도 다시 두들겨 보라는 옛말을 이제는 아는 것도 구글링 해봐야 한다는 말로 바꾸어야 할 듯 싶다.


    스택오버플로우 질의응답 : 단순한 문서 관리 시스템 구현 질의응답


    다음은 영문 질의 응답 내용을 요약한 것이다.


    [질문]

    다음과 같은 요구사항을 만족하는 단순한 문서관리 시스템을 구현하려면 어떻게 해야 하는가?

    (단순함의 의미가 기능이 적다는 의미일 수도 있고, 쉽게 구현할 수 있다는 의미가 될 수도 있음)


    1. 분산 웹 어플리케이션
    2. 문서 버전 관리 지원
    3. 문서 잠금(locking) 기능 지원
    4. 문서 검색

    [답변]

    바퀴를 다시 만들지 말고 표준 기술인 JCR을 활용하세요. JCR은 잘 정의된 표준 (많은 사람들의 시간과 기술을 투자한)입니다. JCR의 구현체(implementation)인 jackrabbit 을 권장합니다.


    [관련 표준]

    JSR : 자바 스펙 요구서(Java Specification Request,JSR)은 자바 플랫폼에 추가된 사양 및 기술을 기술하는 공식 문서.

    Posted by 곽중선
    2015. 3. 14. 23:38

    오픈소스 문서관리 시스템의 첫 단계인 "파일 중복 검사 어플리케이션" 제작 과정에 대한 요약 및 안내 입니다.


    문서(document) 정의와 구조

     : "문서"에 대한 용어 정의와 문서의 속성들에 대한 정리, 문서의 하위 객체와 문서의 관계 등을 정립 등.


    파일(File) 클래스 설계 - 상태과 행위

      : "파일" 클래스의 역할, 행위와 속성들에 대한 설계


    파일(File) 클래스 설계 - 버전 클래스 분리

      : "파일" 클래스에서 버전 클래스를 분리하게된 이유 설명


    파일(File) 클래스 설계 - 인스턴스 생성

      : 인스턴스를 생성하는 2가지 기법에 대한 설명과 파일 인스턴스를 생성 방식을 결정하기 위한 기술 검토.


    문서(document)의 색인 속성 설계 

      : 문서에 포함되는 속성들에 대한 자료형, 타입 등에 대한 검토


    FileVersion 클래스 구현

      : FileVersion 클래스 소스 및 설명


    File 클래스 구현 

      : File 클래스 소스 및 설명


    Document 클래스 구현

      : Document 클래스 소스 및 설명


    DocumentBuilder 클래스 구현

      : DocuemntBuilder 클래스 소스 및 설명


    파일 중복 검사

      : 파일 중복 검사 어플리케이션 소스 및 설명


    Posted by 곽중선
    2015. 3. 14. 22:59
    • 문서 관리 시스템의 로드맵(loadmap) 중에서 첫번째 어플리케이션은 파일 중복 검사 프로그램입니다.

    • 중복 방지 (preventing duplication) : 다양한 저장 매체(storage media)에서 문서를 수집할 때, 중복이 발생할 여지는 충분하다. 사용자가 다양한 환경에서 작업하면서 파일을 복사하는 경우가 빈번하기 때문이다. (USB 복사, 이메일 전송, SNS 공유 및 백업 등) 따라서, 다양한 매체에서  데이터를 수집할 때 이미 수집된 파일이 존재할 경우 새롭게 입력된 파일을 무시하는 기능은 필수적이다. 중복 방지 기능을 구현하기 위해서는 무결성 검사 혹은 check sum 기법을 적용해야 한다. 중복 방지 절차를 간단히 묘사하면 아래와 같다.

      • 파일을 저장소에 등록할 때 컨텐츠에 대한 체크섬을 생성한다.
      • 해당 체크섬에 해당하는 파일이 이미 존재하는지 검사한다. 만일 동일한 체크섬을 가진 파일이 존재한다면, checksum collision을 감안하여 동일한 파일 유무에 대한 정밀 확인 (파일 크기, 제목, 형식, 요약 등을 검사하고, 필요하다면 파일의 전반부 바이너리 데이터를 대조한다.)을 수행한다.
      • 동일한 파일이 존재하는 것으로 판단되면, 저장소에 등록하지 않는다.

    • 실행 결과 예시는 아래와 같습니다.


    Posted by 곽중선
    2015. 3. 14. 22:52
    • Document 클래스의 객체를 생성하기 위해서는 File 및 FileVersion 객체를 함께 생성해야 합니다. Document 객체만 생성해서는 쓸모가 없기 때문입니다.
    • Document 클래스 내에 File 및 FileVersion 객체를 생성할 수 있으나, 소프트웨어 설계 시에 가급적 KISS (Keep It Simple Stupid!) 원칙을 기억해야 합니다. 한번에 많은 기능을 구현할 수도 있고, 때로는 그런 방식으로 작업하는 것이 생산성이 높다고 여겨질 수 있습니다. 그러나, 소프트웨어는 살아있는 생명이며, 최초에 모든 요구사항(기능명세)을 명확히 결정하고 코딩할 수 없습니다. 따라서, 각각의 클래스는 최소한의 기능을 담도록 하고 변경이 발생할 가능성이 줄어들게끔 적은 라인의 코드를 담는 것이 좋습니다. 작은 모듈은 더 이상 필요 없을 때 폐기하는데도 유리합니다.
    • 따라서, Document 클래스 자체는 문서를 표현하는 데이터를 담는 역할만 수행하도록 제한하고, 문서와 그에 따른 부가적인 객체를 생성하는 역할을 별도의 빌더(builder) 클래스로 분리했습니다.
    • 나아가, 빌더 자체도 Document, File, FileVersion 을 생성하는 역할로 제한했습니다. 문서를 분석하고, 키워드, 요약, 체크섬 등을 생성하는 작업은 ContentAnalyzer 클래스로 분리했습니다.

    ContentAnalyzer.java


    DocumentBuilder.java

    public class DocumentBuilder {
    ...... 중략 .....
    	public Document createDocument() {
    		
    		// ---- 필수 항목 점검 및 analyzer 준비 ----
    		if(location == null) {
    			throw new IllegalStateException("location property is not specified");
    		}
    		if(writer == null) {
    			throw new IllegalStateException("writer property is not specified");
    		}
    		
    		ContentAnalyzer contentAnalyzer = new ContentAnalyzer(location);
    		contentAnalyzer.analyze();
    
    		// ---- 입력 값이 없는 항목에 대한 대체 처리 -----
    		if(createDate == null) {
    			createDate = new Date(Calendar.getInstance().getTimeInMillis());
    		}
    		if(title == null) {
    			title = contentAnalyzer.getFileName();
    		}
    
    		// -- FileVersion, File, Document 순서로 빌드 -----
    		FileVersion fileVersion = new FileVersion(1, createDate, description);
    		File file = new File(location, contentAnalyzer.getChecksum(), contentAnalyzer.getSize(), fileVersion);
    		Document document = new Document(title, writer, keywords, 
                                contentAnalyzer.getAbstraction(), location, contentAnalyzer.getFormat());
    		document.addFile(file);
    		
    		return document;
    	}
    }
    
    package docar.archive.document;
    
    /**
     * 문서 파일을 분석하는 클래스.
     * 
     * @author "Sunny Kwak"
     */
    public class ContentAnalyzer {
    	private static final String HTTP_PROTOCOL = "http";
    
    	private URL location;
    	private String fileName;
    	private long fileSize;
    	private String checksum;
    
    	public ContentAnalyzer(URL location) {
    		this.location = location;
    	}
    
    	public void analyze() {
    		InputStream inputStream = null;
    
    		try {
    			String protocol = location.getProtocol();
    			if (protocol == null
    					|| !protocol.toLowerCase().equals(HTTP_PROTOCOL)) {
    				inputStream = new FileInputStream(new java.io.File(location.toURI()));
    			} else {
    				inputStream = location.openConnection().getInputStream();
    			}
    
    			fileName = location.getFile();
    			fileSize = 0L;
    			checksum = getMD5Checksum(inputStream);
    
    		} catch (IOException e) {
    			// FIXME add logging
    			e.printStackTrace();
    		} catch (URISyntaxException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} finally {
    			if (inputStream != null) {
    				try {
    					inputStream.close();
    				} catch (IOException ignored) {
    					// do nothing
    				}
    			}
    		}
    
    	}
    


    Posted by 곽중선
    2015. 3. 14. 22:35
    • Document 클래스의 속성은 제목 (title), 작성자 (wirter), 키워드 목록 (keywords), 요약(abstraction), 원본 링크 (original link), 파일 형식 (format), 버전 파일 목록 (files) 등입니다.
    • 작성자 정보는 이름, 이메일 주소, 홈페이지 등의 복합된 속성을 지녀야 하기 하기 때문에 별개의 클래스로 분리하였습니다. 또한, 한명의 작성자가 여러 문서를 작성하는 일대다(1:n) 관계이기 때문에 분리하는 것이 타당합니다.
    • 키워드는 복수의 명사 단어로 구성되며, 중복된 단어가 입력되어서는 안되기 때문에 Set<String> 타입을 선언합니다. 자료 구조 중에서 Set 타입은 포함된 데이터들의 중복을 허용하지 않는 특성을 가진다는 점을 활용하는 것입니다.
    • 파일 형식은 enum 타입을 사용했으나, 향후에 refactoring 가능성이 있습니다.
    • 하나의 문서가 여려 가지 버전으로 존재할 수 있고, 동일한 파일이 여러 위치에 존재할 수 있습니다. 버전을 고려했을 때 순서(order)가 중요하므로 List 타입을 사용했습니다.
    package docar.archive.document;
    
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;
    
    import docar.user.Writer;
    
    /**
     * '문서' 클래스.
     *
     * @author "Sunny Kwak"
     */
    public class Document {
    	private String title;
    	private Writer writer;
    	private Set<String> keywords;
    	private String abstraction;
    	private URL originalLink;
    	private Format format;
    	private List<File> files;
    
    	public Document(String title, Writer writer, Set<String> keywords,
    			String abstraction, URL originalLink, Format format) {
    		if (title == null || title.isEmpty()) {
    			throw new IllegalArgumentException("title argument is missing");
    		}
    		if (writer == null) {
    			throw new IllegalArgumentException("writer argument is missing");
    		}
    		if (originalLink == null) {
    			throw new IllegalArgumentException(
    					"originalLink argument is missing");
    		}
    		if (format == null) {
    			throw new IllegalArgumentException("format argument is missing");
    		}
    
    		this.title = title;
    		this.writer = writer;
    		this.keywords = keywords;
    		this.abstraction = abstraction;
    		this.originalLink = originalLink;
    		this.format = format;
    
    		files = new ArrayList<File>();
    	}
    
    Posted by 곽중선
    2015. 3. 14. 22:19
    • File 클래스는 문서(Document)의 "물리적인 상태 정보"를 나타내는 클래스입니다. 파일 위치(URL), 체크섬(cheksum), 크기(size), 파일 버전(file version) 등의 속성을 포함하고 있습니다.
    • 파일 위치를 경로(path)가 아니라, URL 클래스로 선언한 것은 PC 혹은 서버의 로컬 디스크에 존재하는 파일 뿐만 아니라 인터넷 상에 존재하는 파일 위치를 지정할 수 있도록 하기 위해서입니다. checksum 문자열은 파일의 무결성(integrity)와 중복 검사(duplication check) 목적으로 사용됩니다.
    • File 클래스 또한 FileVersion 클래스 처럼 방어적 코딩이 포함되어 있습니다.



    File.java

    package docar.archive.document;
    
    import java.net.URL;
    
    /**
     * "파일"은 "문서"의 구성요소이다.
     * 
     * - 문서는 하나 이상의 파일을 포함할 수 있다.
     * - 각각의 파일은 문서의 다른 버전을 표현한다.
     * - 파일은 문서의 물리적인 형태를 의미한다.
     *
     * @author "Sunny Kwak"
     */
    public class File {
    	private URL location;
    	private String checksum;
    	private long size;
    	private FileVersion fileVersion;
    
    	/**
    	 * '파일' 생성자.
    	 * 
    	 * @param location 파일의 위치
    	 * @param checksum 파일 식별을 위한 지문(finger print)
    	 * @param size 파일 크기.
    	 * @param fileVersion 파일 버전.
    	 * @throws IllegalArgumentException 필수 항목이 누락된 경우, 예외 처리
    	 */
    	public File(URL location, String checksum, long size,
    			FileVersion fileVersion) {
    		
    		if(location == null) {
    			throw new IllegalArgumentException("location arguement is missing");
    		}
    		if(checksum == null || checksum.isEmpty()) {
    			throw new IllegalArgumentException("checksum argument is missing");
    		}
    		if(size < 1) {
    			throw new IllegalArgumentException("Invalid fie size. Input file = " + location);
    		}
    		if(fileVersion == null) {
    			throw new IllegalArgumentException("fileVersion argument is missing");
    		}
    		
    		this.location = location;
    		this.checksum = checksum;
    		this.size = size;
    		this.fileVersion = fileVersion;
    	}
    
    
    Posted by 곽중선
    2015. 3. 14. 22:06
    • FileVersion 클래스 구현에서 눈여겨 봐야할 점은 생성자(constructor)에서 인자(parameter) 값을 검사하는 로직이다.
      객체지향 프로그래밍이 절차적(혹은 함수형) 프로그램과 다른 점은 데이터(혹은 상태)와 데이터를 조작하는 메소드(혹은 행위)를 결합시킨 구조를 가지고 있다는 점이다. 이러한 구조의 잇점을 최대한 활용하기 위해서는 객체에 값이 설정 혹은 변경될 때 해당 값이 적합한지 여부를 검사하는 로직을 구현해야 한다. 단지, 인터페이스와 클래스를 사용한다고 해서 훌륭한 객체가 되는 것이 아니다.
    • 전달되는 값 (인자, parameter)이 유효한 것인지 판정해 잘못된 값이 입력되었을 경우, 즉시 오류를 발생시켜 문제가 발생하더라도 그 원인이 외부에 있음을 알아내기 쉽고, 원인을 빠르고 명확하게 파악할 수 있도록 하는 기법을 방어적 프로그래밍이라 한다.


    FileVersion.java


    public class FileVersion {
    	private int sequence;
    	private Date createDate;
    	private String description;
    
    	/**
    	 * 파일 버전 생성자.
    	 * 
    	 * @param sequence
    	 *            버전 순번.
    	 * @param createDate
    	 *            버전 생성 일시
    	 * @param description
    	 *            버전 설명
    	 * @throws IllegalArgumentException
    	 *             1보다 작은 순번 혹은 날짜가 입력되지 않은 경우 예외 발생.
    	 */
    	public FileVersion(int sequence, Date createDate, String description) {
    		if (sequence < 1) {
    			throw new IllegalArgumentException("sequence must greater than 0");
    		}
    
    		if (createDate == null) {
    			throw new IllegalArgumentException("Must specify valid date");
    		}
    
    		this.sequence = sequence;
    		this.createDate = createDate;
    		this.description = description;
    	}
    
    Posted by 곽중선