기초튼튼 코드튼튼 다함께 프로그래밍

http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791185890494&orderClick=

'테마 정하기' 라는 것은 막연하게 가지고 있던 생각을 구체화 하는 작업이다. 이때 중요한 것은 처음부터 욕심을 부리지 않는 것이다. 사용하는 프로그래밍 언어에 따라 다르지만 프로그램은 처음부터 끝까지 완벽하게 만들어야만 비로소 움직인다. 어딘가 중간에 실수가 하나라도 있으면 전혀 움직여주지 않는다. '이것도 하고 싶고 저것도 하고 싶다'고 욕심을 부려 다양한 기능을 포함시키면 프로그램 소스가 점점 길어진다. 그리고 그에 따라 프로그램에 문제점이 포함될 확률도 점점 증가하고, 때로는 문제점을 좀처럼 찾지 못하는 악순환에 빠지게 된다. 그 결과는 어떻게 될까? 두근거리는 마음으로 프로그램을 실행하려고 했지만 전혀 움직이지 않는다. "자, 그럼 여기를 고치고 저기를 고치고... 그래도 여전히 움직이지 않네? 왜지? 음.. 하기 싫어졌다. 아~ 그만할까? 그래. 그만하자' 이런식이 된다면 시간이 아무리 지나도 프로그램을 작성할 수 없다.
제2장의 '2.3.5 프로그래머의 길'에서도 언급했지만, 프로그램을 작성할 수 있게 되기 위한 지름길은 '프로그램이 움직일 때의 감동을 맛보는 것'이다. 그러기 위해서는 거듭 강조했던 작은 목표를 마련하는 것이 무엇보다 중요하다. 사람은 이상한 생물이라서 자신의 힘을 과신하는 경향이 있다. 그러므로 프로그램을 공부할 때는 '이 정도면 할 수 있을 것 같다'는 생각을 과감히 버리기 바란다. '겨우 이만큼?'이라고 느낄 정도의 목표가 가장 좋은 것이다.
간단한 목표라면 약간의 노력으로도 달성할 수 있다. 그리고 목표를 달성할 수 있었다면 그 다음은 목표를 좀 더 높은 위치로 설정한다. 이것을 반복하다 보면 언젠가 반드시 스스로도 놀라울 정도로 높은 목표를 달성 할 수 있을 것이다.
자. 그럼 욕심 부리지 않고 테마를 정하려면 어떻게 해야 할까? 그것은 '이것이 없으면 ㅇㅇㅇ라고 부를 수 없다'라는 수준까지 기능을 좁히는 것이다. 예를 들어 용돈 기록부라면 가장 중요한 것은 돈의 흐름이다. 이 부분에 주목해 보면 다음 두가지 기능은 반드시 필요하다.

1. 사용한 금액(출금)을 입력하면 잔고가 표시된다.
2. 받은 금액(입금)을 입력하면 잔고가 표시된다.

기타 정보, 예를 들어 날짜와 무엇에 돈을 사용했는지 등의 정보는 없어도 그다지 불편하지 않다. '입금액 또는 출금액을 입력하면 현재의 잔액이 표시된다' 첫번째 테마는 이정도가 딱 좋다.
사람은 이상한 생물이라서 자신의 힘을 과신하는 경향이 있다. 그러므로 프로그램을 공부할 때는 '이 정도면 할 수 있을 것 같다'는 생각을 과감히 버리기 바란다. '겨우 이만큼?'이라고 느낄 정도의 목표가 가장 좋은 것이다.
'이것이 없으면 ㅇㅇㅇ라고 부를 수 없다'라는 수준까지 기능을 좁히는 것

개발자가 반드시 정복해야 할 객체지향과 디자인 패턴

https://kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788969090010

  • 객체는 프로시저를 실행하는데 필요한 만큼의 데이터를 가지며, 객체들이 모여 프로그램을 구성한다.

  • 시그니처(Signature)

    • 기능 식별 이름
    • 파라미터 및 파라미터 타입
    • 기능 실행 결과 값
  • 객체가 제공하는 모든 오퍼레이션의 집합을 객체의 인터페이스(interface)라고 부르며 서로 다른 인터페이스를 구분할 때 사용되는 명칭이 타입(type) 이다.

  • 객체간의 인터페이스를 맞춘고 할 때는 개념적인 의미의 인터페이스를 뜻하는 것이지 각 언어에서 제공하는 인터페이스가 아님에 유의해야 한다.

  • 실행을 요청(request)하는 것을 '메세지'를 보낸다고 표현한다.

  • 한 객체가 갖는 책임을 정의한 것이 바로 타입/인터페이스라고 생각하면 된다.

  • UML에서 점선화살표 == 의존(dependency)

  • 캡슐화를 위한 두개의 원칙

    • Tell, Don't Ask

    • 데미테르의 법칙(Law of Demeter) - 신문 배달부 예제 - 52p

      Law of Demeter
      Tell, Don’t Ask 규칙을 따를 수 있도록 만들어주는 다른 규칙이다. 이는 다음과 같은 간단한 규칙으로 구성된다.
      
      메서드에서 생성한 객체의 메서드만 호출
      파라미터로 받은 객체의 메서드만 호출
      필드로 참조하는 객체의 메서드만 호출
      
  • 인터페이스 상속과 구현 상속

  • 추상화를 한다고 해서 반드시 추상 타입을 만들어야 하는 것은 아니다. 단순히 구현 클래스로부터 추상 타입을 이끌어 내는 것만이 추상화라고 오해하면 안된다

  • 추상화는 공통된 개념을 도출해서 추상타입을 정의해 주기도 하지만 또한, 많은 책임을 가진 객체로부터 책임을 분리하는 촉매제가 되기도 한다.

  • 하위 수준의 상세구현보다는 변하지 않는 상위 수준의 로직을 재사용 할 수 있도록 설계하는 것이 더 중요하다.

  • 경험지 않은 분야라 하더라도 추상화 할 수 있는 방법 - 변화되는 부분을 추상화 하는 것

  • 추상화를 하면 추상타입을 사용하는 코드에 영향을 주지 않으면서 추상 타입의 실제 구현을 변경 할 수 있다.

  • 인터페이스에 대고 프로그래밍하기(program to interface)

    • 실제 구현을 제공하는 콘크리트(구상, 실제 구현을 제공) 클래스를 사용해서 프로그래밍 하지 말고, 기능을 정의한 인터페이스를 사용해서 프로그래밍하라
  • 인터페이스를 사용해야 할 때는 변화 가능성이 높은 경우에 한해서 사용해야 한다.

  • 상속보다는 객체 조립을 사용 할 것

  • 위임은 내가 할 일을 다른 객체에게 넘긴다는 의미를 담고 있으며 보통 조립방식을 이용해서 위임을 구현한다.

  • 상속을 사용할 때는 재사용이라는 관점이 아닌 기능의 확장 이라는 관점에서 상속을 적용해야 한다. 또한 추가로 명확한 IS-A 관계가 성립 되어야 한다.

  • 상속은 명혹한 IS-A 관계에서 점진적으로 상위 클래스의 기능을 확장해 나갈 때 사용할 수 있다 단 최초에는 명확한 IS-A관계로 보여서 상속을 이용해서 기능을 확장했다고 하더라도, 이후에 클래스의 개수가 불필요하게 증가하는 문제가 발생하거나 상위 클래스의 변경이 어려워지는 등 상위 클래스를 상속받을 때의 단점이 발생한다면 조립으로 전환하는 것을 고려해야 한다.

  • 참고 : OOP의 규칙들

  • 설계원칙 : SOLID
    • 단일 책임 원칙
    • 개방-폐쇄 원칙
    • 리스코프 치환 원칙
    • 인터페이스 분리 원칙
    • 의존 역전 원칙
  • 어떻게 하면 단일 책임 원칙을 지킬 수 있을까? 그 방법은 바로 메서드를 실행하는 것이 누구인지 확인해 보는 것이다.
  • 클래스의 사용자들이 서로 다른 메서드들을 사용한다면 그들 메서드는 각각 다른 책임에 속할 가능성이 높고, 따라서 책임 분리 후보가 될 수 있다.
  • SOLID 원칙을 한마디로 정의하면 변화에 유연하게 대처할 수 있는 설계 원칙 이다.
  • 단일 책임 원칙인터페이스분리 원칙은 객체가 커지지 않도록 막아준다. 객체가 많은 기능을 가지게 되면, 객체가 가진 기능의 변경 여파가 그 객체의 다른 기능에 까지 번지게 되고 이는 다시 다른 기능을 사용하는 클라이언트에까지 영향을 준다. 객체가 단일 책임을 갖게 하고 클라이언트마다 다른 인터페이스를 사용하게 함으로써 한 기능의 변경이 다른 곳에까지 미치는 영향을 최소화 할 수 있고, 이는 결국 기능 변경을 보다 쉽게 할 수 있도록 만들어 준다.
  • 리스코프 치환 원칙의존 역전 원칙개방 폐쇄 원칙을 지원한다. 개방 폐쇄 원칙은 변화되는 부분을 추상화 하고 다형성을 이용함으로써 기능 확장을 하면서도 기존 코드를 수정하지 않도록 만들어 준다. 여기서 변화되는 부분을 추상화 할 수 있도록 도와주는 원칙이 바로 의존 역전 원칙이고, 다형성을 도와주는 원칙이 리스코프 치환 원칙인 것이다.
  • 또한 SOLID 원칙은 사용자 입장에서의 기능 사용을 중시한다. 인터페이스 분리 원칙은 클라이언트 입장에서 인터페이스를 분리하고 있으며, 의존 역전 원칙 역시 저수준 모듈을 사용하는 고수준 모듈 입장에서 추상화 타입을 도출하도록 유도한다. 또한 리스코프 치환 원칙은 사용자에게 기능 명세를 제공하고, 그 명세에 따라 기능을 구현 할 것을 약속한다. 이처럼 SOLID원칙은 사용자 관점에서의 설계를 지향하고 있다.
  • 개방 폐쇄 원칙은 유연함에 대한 것
    • 코드에 대한 변화 요구가 발생하면, 변화와 관련된 구현을 추상화해서 개방 폐쇄 원칙에 맞게 수정 할 수 있는지 확인하는 습관을 갖도록 하자
  • 인터페이스 분리 원칙은 클라이언트를 기준으로 인터페이스를 분리하는 원칙이다.
  • 의존 역전 원칙은 런타임의 의존이 아닌 소스 코드의 의존을 역전시킴으로써 변경의 유연함을 확보할 수 있도록 만들어 주는 원칙이지, 런타임에서의 의존을 역전시키는 것은 아니다.
  • 리스코프 치환 원칙의존 역전 원칙개방 폐쇄 원칙을 지원한다. 개방 폐쇄 원칙은 변화되는 부분을 추상화하고 다형성을 이용함으로써 기능 확장을 하면서도 기존 코드를 수정하지 않도록 만들어 준다. 여기서 변화되는 부분을 추상화할 수 있도록 도와주는 원칙이 바로 의존 역전 원칙이고, 다형성을 도와주는 원칙이 리스코프 치환 원칙인 것이다.

성공과 실패를 결정하는 1%의 네트워크 원리

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&orderClick=JAa&barcode=9788931553482

웹브라우저에 URL을 입력했을 때 일어나는 일들

  1. 사용자가 URL을 입력
  2. URL을 웹 브라우저가 해석하여 HTTP 메시지를 만들고, Socket 라이브러리에 건냄
  3. Socket 라이브러리는 받은 HTTP 메시지를 송신 데이터로 프로토콜 스택에 건네줌
  4. TCP 는 송신 데이터를 패킷의 길이에 맞게 분할하고 TCP 헤더를 부가하여 IP 에 건네줌
  5. IP 는 TCP 에서 받은 패킷에 IP 헤더를 부가. 또한 MAC 주소를 조사하여 MAC 헤더도 부가하고 나서 LAN 드라이버에 건네줌
  6. LAN 드라이버는 IP 에서 송신 패킷을 받고, 이것을 LAN 어댑터에 건네주어 송신을 지시
  7. LAN 어댑터는 이더넷이 송신 가능한 상태가 되는 것을 보아서 패킷을 전기 신호로 변환한 후 트위스트 페어 케이블에 내보냄
  8. 신호는 트위스트 페어 케이블 속을 통해 리피터 허브에 도달
  9. 리피터 허브가 신호를 모든 포트로 보내면 이것이 스위칭 허브에 도달
  10. 스위칭 허브는 도착한 패킷의 수신자 MAC 주소의 값과 자기 속에 있는 주소 테이블을 대조하여 출력할 곳의 포트를 판단하고, 포트에 패킷을 중계.
  11. 라우터는 도착한 패킷의 수신자 IP 주소의 값과 저장된 라우팅 테이블의 내용을 대조하여 출력 포트를 판단하고, 이 포트에 패킷을 중계
  12. 라우터가 인터넷에 출력한 패킷에는 PPPoE 헤더와 PPP 헤더가 붙어있음
  13. ADSL 모뎀에 도착한 패킷은 여기에서 ATM 셀로 분할됨
  14. ADSL 모뎀은 ATM셀로 분할한 후 전기 신호로 변환하여 전화선에 내보냄
  15. ADSL 모뎀이 내보낸 신호는 전화선을 통해서 전화국이나 아파트 안에 있는 통신실의 DSLAM(전화국용 집합 모뎀)에 도착
  16. DSLAM 은 수신한 전기 신호를 ATM 셀의 형태로 되돌려서 광대역 액세스 서버에 보냄
  17. 광대역 액세스 서버는 ATM 셀을 패킷의 형태로 만들고 나서 수신자 주소를 살펴보고 패킷을 중계
  18. 광대역 액세스 서버가 중계한 패킷은 L2TP 헤더가 붙어 터널 안으로 흘러감
  19. 터널의 출구에 있는 터널링용 라우터에 패킷이 도착하면 L2TP 헤더와 PPP 헤더가 분리되어 인터넷을 통과하여 웹 서버측으로 흘러감
  20. 서버측의 LAN 에는 방화벽이 있어 이것을 통해 들어온 패킷을 검사하고, 통과시킬지와 차단할지를 판단
  21. 웹 서버의 바로 앞에 캐시 서버를 설치하는 경우 방와벽을 통과한 패킷을 캐시 서버가 가로챔. 사용자가 요청한 페이지가 캐시 서버에 저장되어 있으면 캐시 서버가 웹 서버를 대신해서 해당 페이지를 되돌려 보냄
  22. 캐시 서버에 페이지가 저장되어 있지 않으면 여기에서 요구가 전송되어 웹 서버에 도착
  23. 웹 서버에 패킷이 도착하면 LAN 어댑터와 LAN 드라이버가 연대하여 패킷을 수신하고, 프로토콜 스택에 건네줌
  24. 프로토콜 스택은 IP헤더와 TCP 헤더를 차례대로 검사하여 오류가 없으면 패킷에서 HTTP 메시지의 조각을 추출해 원래의 모습으로 되돌림
  25. 원래 모습으로 되돌아온 HTTP 메시지는 Socket 라이브러리를 통해 웹 서버에 전달됨
  26. 웹 서버는 받은 HTTP 메시지의 내용을 해석해서 요청하는 내용에 따라 데이터를 추출하여 클라이언트에 반송

TCP/IP 4계층

  • TCP/IP - 인터넷과 관련된 프로토콜의 모음
  • 4계층 - 애플리케이션 / 트랜스포트 / 네트워크 / 데이터링크
  • 애플리케이션 - 유저에게 제공되는 애플리케이션에서 사용하는 통신의 움직임 결정
  • 트랜스포트 - 애플리케이션 계층에 네트워크로 접속되어 있는 2대의 컴퓨터 사이의 데이터 흐름 제공
  • 네트워크 - 네트워크 상에서 패킷의 이동을 다룸
  • 링크 - 네트워크에 접속하는 하드웨어적인면을 다룸
  • 메시지 -> 세그먼트 -> 데이터그램 -> 프레임
  • 각 계층을 거칠때는 헤더로 불려지는 해당계층마다 해당 계층에 필요한 정보를 추가.
  • 수신측에서는 각 계층을 거칠 때 마다 해당 계층마다 사용한 헤더 삭제
  • IP의 역할 - 개개의 패킷을 상대방에게 전달하는 것
  • TCP의 역할 - 대용량의 데이터를 보내기 쉽게 작게 분해하여 상대에게 보내고, 정확하게 도착했는지 확인하는 역할