출처: http://baiduhix.blogspot.com.br/2015/08/android-how-to-do-findviewbyid-in.html

★ http://www.vogella.com/tutorials/AndroidLifeCycle/article.html

  • Activity and Fragment Lifecycle





  • Activity Lifecycle (출처: http://philosymbol.net/?p=571)
    : 안드로이드 어플리케이션은 자신의 프로세스 수명을 직접 제어하지 않으며, 안드로이드 런타임이 각 어플리케이션의 프로세스와 그 안에 있는 각 activity를 관리한다.
    : 런타임이 프로세스와 activity의 종료와 관리를 다루는 동안, activity의 상태는 자신의 부모 어플리케이션 프로세스의 우선순위를 결정하는데 사용된다.
    : 어플리케이션 우선순위는 런타임이 어플리케이션과 그 안에 실행중인 activity를 종료시킬 가능성에 영향을 미치게된다.

    - 활성(Active)
     : activity가 stack의 최상위에 있을 경우 이 activity는 현재 화면에 보이고 사용자 입력을 받는다.
     : 안드로이드는 무슨 일이 있어도 활성 상태에 있는 activity가 살아있도록 노력하며, 이 activity가 필요로 하는 리소스를 확보하기 위해 필요에 따라 stack의 아래쪽에 있는 activity들을 종료시킬 수 있다.
     : 다른 activity가 활성화되면 기존의 활성 activity는 일시 중지(Pause)된다.

    - 일시 중지(Active)
     : 경우에 따라 activity는 화면에는 보이지만 포커스를 지니지 않을 수 있다.
     : 이 상태는 투명한 activity나 화면 전체를 사용하지 않는 activity가 그 앞에 활성화되어 있는 경우이다.
     : 일시 중지 상태가 되는 경우 activity는 활성 상태인것처럼 다뤄지지만 사용자 입력을 받지 않는다.
     : 극단적인 경우, 안드로이드는 활성 activity를 위한 리소스 확보를 위해 일시 중지 상태의 activity를 종료시킬 수 있을 것이다.
     : 만약 activity가 완전히 가려지게 되면 그 activity는 중지상태가 된다.

    - 중지(Stop)
     : activity는 화면에 보이지 않는다.
     : 이 activity는 모든 상태 및 멤버 정보를 메모리에 남기지만, 만약 시스템이 활성 activity를 위해 메모리를 요청할 경우 리소스 확보를 위한 정리 후보 1순위가 된다.
     : activity가 중지될 때는 데이터와 현재 UI상태를 저장하는 것이 중요하다.
     : activity가 화면 밖으로 나가거나 닫히고 나면 그 activity는 비활성 상태가 된다.

    - 비활성(Inactive)
     : activity는 종료되고 난 이후와 시작되기 이전 비활성 상태에 머문다.
     : 비활성 activity는 activity stack에게 제거되며, 화면에 다시 나타내기 위해서는 재시작되어야 한다.

     



    - Activity 생명주기를 구성하는 메소드

    메소드 

    설명

     onCreate

     액티비티가 최초 생성시에 호출된다. 초기화 설정을 하는 곳으로 보관된 상태의 액티비티가 있다면, 그 상태를 저장중인 Bundle 객체를 받는다. onStart() 메소드가 이어진다. 강제종료가 불가능하다.

     onRestart

     액티비티가 정지 후 다시 시작되기 바로 직전에 호출된다.
    onStart() 메소드가 이어진다. 강제종료가 불가능하다. 

     onStart

     액티비티가 사용자에게 보여지기 직전에 호출된다. 액티비티가 보여지게되면 onResume() 메소드가, 안보이게 되면 onStop() 메소드가 이어진다. 강제종료가 불가능하다.

     onResume

     액티비티가 사용자와 상호작용하기 직전에 호출된다. (스택의 최상위에 위치) onPause() 메소드가 이어진다. 강제종료가 불가능하다.

     onPause

     시스템이 다른 액티비티를 시작하려 할 때 호출된다. 일반적으로 데이터 저장을 하기에 좋은 곳이다. 소스코드의 속도가 빨라야 한다. 왜냐하면 이 메소드가 끝나기 전까지 다음 액티비티가 실행되지 않기 때문인데 액티비티가 되돌아오면 onResume(), 보이지않게되면 onStop()이 이어진다. 강제종료가 불가능하다.

     onStop

     액티비티가 사용자에게 보이지 않을때 호출 된다. 액티비티가 제거되거나 다른 액티비티가 실행되어 해당 액티비티를 덮어버렸을때, 호출된다.
    액티비티가 되돌아오면 onRestart(), 액티비티가 사라지면 onDestroy() 가 이어진다. 강제종료가 가능하다.

     onDestroy

     액티비티 삭제 직전에 호출된다. 액티비티가 받는 마지막 호출 메소드로 시스템이 메모리 확보를 위해 액티비티 인스턴스를 없애버리거나, finish() 메소드가 호출되면 호출되는 메소드이다.
    isFinishing() 메소드로 두 가지를 분기할 수 있다. onStart() 메소드가 이어진다. 강제종료가 불가능하다. 



    - Activity 상태 저장 (출처: http://namsieon.com/286)


    시스템이 액티비티를 강제종료 했을때, 사용자는 이전의 액티비티로 돌아가고 싶을 수 있습니다. 이럴 경우 액티비티가 강제종료 되기 전에 상태를 저장할 수 있는
     
    onSaveInstanceState() 메소드를 구현하면 저장이 가능해 집니다.



    즉, 액티비티가 파괴되기전에 호출되는 메소드 인데요. ( onPause() 호출 이전에 호출됩니다. )
    이 메소드는 이름/값 쌍으로 이루어진 번들 객체(Bundle) 를 인수로 가집니다. 액티비티가 다시 시작되면 번들은 onSaveInstanceState() 와 onStart() 이후에 호출되는 onRestoreInstanceState() 에게 전달됩니다.



    ☞ onSaveInstanceState() , onRestoreInstanceState() 메소드는 생명주기 메소드는 아닙니다.
    따라서 항상 호출되지는 않으며 특정 상황 ( 액티비티 강제종료전에 onSaveInstance() 호출처럼 ) 에서만 호출됩니다. 단, 사용자 액션에 의해 종료될 때는 ( 사용자가 직접종료 ) 호출되지 않습니다.
    - 사용자가 되돌아가지 않을 생각으로 종료한 것으로 판단한 것이겠죠...

    onSaveInstanceState() 는 액티비티의 일시적인 상태 저장을 위한 것이므로 , 데이터 등을 안전하게 저장하려면 onPause() 메소드에서 처리해야 합니다.



  • Fragment
















'Programing > Android' 카테고리의 다른 글

Google I/O - Memory Management For Android  (0) 2016.05.03
Avoiding Memory Leaks  (0) 2016.05.03
Handler, Looper  (0) 2016.04.19
Parcelable vs. Serializable  (0) 2016.03.22
안드로이드 - 자바 시스템 프레임워크  (0) 2016.01.26
출처 : https://realm.io/kr/news/android-thread-looper-handler/

소개

안드로이드의 애플리케이션을 실행하면 시스템은 메인 액티비티를 메모리로 올려 프로세스로 만들며, 이 때 메인 스레드가 자동으로 생성됩니다. 메인 스레드는 안드로이드의 주요 컴퍼넌트를 실행하는 곳이자 UI를 그리거나 갱신하는 일을 담당할 수 있는 유일한 스레드이므로 UI 스레드라고도 불립니다.

안드로이드 화면을 구성하는 뷰나 뷰그룹을 하나의 스레드에서만 담당하는 원칙을 싱글 스레드 모델이라고 합니다. 싱글 스레드 모델의 규칙은 첫째, 메인 스레드(UI 스레드)를 블럭하지 말 것, 둘째, 안드로이드 UI 툴킷은 오직 UI 스레드에서만 접근할 수 있도록 할 것, 이 두 가지입니다. 이런 싱글 스레드 모델의 영향을 고려하지 않으면 애플리케이션의 성능이 저하될 수 있습니다. 긴 시간이 걸리는 작업을 메인 스레드에서 담당한다면 애플리케이션의 반응성이 낮아질 수 있고, 급기야 사용자의 불편함을 방지하고자 시스템이 애플리케이션을 ANR(Appication Not Responding) 상태로 전환시킬 수도 있습니다. 따라서 시간이 걸리는 작업을 하는 코드는 여분의 스레드를 사용하여 메인 스레드에서 분리해야 하고, 자연스럽게 메인 스레드와 다른 스레드가 통신하는 방법이 필요하게 됩니다.

다른 스레드에서 메인 스레드로 접근하기 위해 Looper와 Handler를 사용할 수 있으며, 안드로이드는 Java의 Thread를 좀 더 쉽게 사용할 수 있도록 래핑한 HandlerThread, 더 나아가 Thread나 Message Loop 등의 작동 원리를 크게 고려하지 않고도 사용이 가능한 AsyncTask 등의 클래스를 제공합니다. 이 글에서는 먼저 Thread-Looper-Handler의 개념을 이해하고, 나아가 HandlerThread와 AsyncTask에 대해 정리해보도록 하겠습니다.

Looper와 Handler의 사용 목적

왜 안드로이드는 메인 스레드에서만 UI 작업이 가능하도록 제한할까요? 메인 스레드가 아닌 스레드가 병렬적으로 실행되고 있을 때, 메인 스레드와 다른 스레드, 두 개 이상의 스레드가 동시에 같은 텍스트뷰에 setText()를 시도하는 경우를 생각하면 간단합니다.

둘 중 어느 스레드의 setText()가 적용될지 예측할 수 없고, 사용자는 둘 중 하나의 값만을 볼 수 있어 다른 한 스레드의 결과는 버려집니다. 이같이 두 개 이상의 스레드를 사용할 때의 동기화 이슈를 차단하기 위해서 Looper와 Handler를 사용하게 됩니다.

Looper와 Handler의 작동 원리

먼저 스레드와 Looper, Handler가 어떻게 작동하는지 알아볼까요? 메인 스레드는 내부적으로 Looper를 가지며 그 안에는 Message Queue가 포함됩니다. Message Queue는 스레드가 다른 스레드나 혹은 자기 자신으로부터 전달받은 Message를 기본적으로 선입선출 형식으로 보관하는 Queue입니다. Looper는 Message Queue에서 Message나 Runnable 객체를 차례로 꺼내 Handler가 처리하도록 전달합니다. Handler는 Looper로부터 받은 Message를 실행, 처리하거나 다른 스레드로부터 메시지를 받아서 Message Queue에 넣는 역할을 하는 스레드 간의 통신 장치입니다.

이제 Handler와 Looper, Message Queue에 대해 좀 더 자세히 살펴보겠습니다.

Handler

Handler는 스레드의 Message Queue와 연계하여 Message나 Runnable 객체를 받거나 처리하여 스레드 간의 통신을 할 수 있도록 합니다. Handler 객체는 하나의 스레드와, 해당 스레드의 Message Queue에 종속됩니다. 새로 Handler 객체를 만든 경우 이를 만든 스레드와 해당 스레드의 Message Queue에 바인드됩니다. 다른 스레드가 특정 스레드에게 메시지를 전달하려면 특정 스레드에 속한 Handler의 post나 sendMessage 등의 메서드를 호출하면 됩니다. 
앞서 Message Queue는 전달받은 Message를 선입선출 형식으로 보관한다고 설명했지만, 전달 시점에 다른 메서드를 사용하여 Queue의 맨 위로 보내거나, 원하는 만큼 Message나 Runnable 객체의 전송을 지연시킬 수도 있습니다. 자주 쓰이는 Handler의 메서드를 아래 표에 정리했습니다.

리턴값메서드명인자설명
voidhandleMessageMessage msgLooper가 Message Queue에서 꺼내준 Message나 Runnable 객체를 처리 
(상속 시 구현 필수)
final booleanpostRunnable rMessage Queue에 Runnable r을 전달
final booleansendMessageMessage msgMessage Queue에 Message msg를 전달
final booleanpostAtFrontOfQueueRunnable rMessage Queue의 맨 앞에 Runnable r을 전달
final booleansendMessageAtFrontOfQueueMessage msgMessage Queue의 맨 앞에 Message msg를 전달
final booleanpostDelayedRunnable r, long delayMillisdelayMillis만큼 지연 후Message Queue에 Runnable r을 전달
final booleansendMessageDelayedMessage msg, long delayMillisdelayMillis만큼 지연 후Message Queue에 Message msg를 전달

외부, 혹은 자기 스레드로부터 받은 메시지를 어떤 식으로 처리할 지는 handleMessage() 메서드를 구현하여 정합니다. sendMessage()나 post()로 특정 Handler에게 메시지를 전달할 수 있고, 재귀적인 호출도 가능하므로 딜레이를 이용한 타이머나 스케줄링 역할도 할 수 있어 편리합니다.

Looper Message Queue

Looper는 무한히 루프를 돌며 자신이 속한 스레드의 Message Queue에 들어온 Message나 Runnable 객체를 차례로 꺼내서 이를 처리할 Handler에 전달하는 역할을 합니다. 메인 스레드는 Looper가 기본적으로 생성돼 있지만, 새로 생성한 스레드는 기본적으로 Looper를 가지고 있지 않고, 단지 run 메서드만 실행한 후 종료하기 때문에 메시지를 받을 수 없습니다. 따라서 기본 스레드에서 메시지를 전달받으려면 prepare() 메서드를 통해 Looper를 생성하고, loop() 메서드를 통해 Looper가 무한히 루프를 돌며 Message Queue에 쌓인 Message나 Runnable 객체를 꺼내 Handler에 전달하도록 합니다. 이렇게 활성화된 Looper는 quit()이나 quitSafely() 메서드로 중단할 수 있습니다. quit() 메서드가 호출되면 Looper는 즉시 종료되고, quitSafely() 메서드가 호출되면 현재 Message Queue에 쌓인 메시지들을 처리한 후 종료됩니다.

Message Runnable

Message란 스레드 간 통신할 내용을 담는 객체이자 Queue에 들어갈 일감의 단위로 Handler를 통해 보낼 수 있습니다. 일반적으로 Message가 필요할 때 새 Message 객체를 생성하면 성능 이슈가 생길 수 있으므로 안드로이드가 시스템에 만들어 둔 Message Pool의 객체를 재사용합니다. obtain() 메서드는 빈 Message 객체를, obtain(Handler h, int what …)은 목적 handler와 다른 인자들을 담은 Message 객체를 리턴합니다.
Runnable을 설명하려면 스레드를 만드는 두 가지 방법부터 말씀드려야 합니다. 새 스레드는 Thread() 생성자로 만들어서 내부적으로 run()을 구현하던지, Thread(Runnable runnable) 생성자로 만들어서 Runnable 인터페이스를 구현한 객체를 생성하여 전달하던지 둘 중 하나의 방법으로 생성하게 됩니다. 후자에서 사용하는 것이 Runnable로 스레드의 run() 메서드를 분리한 것입니다. 따라서 Runnable 인터페이스는 run() 추상 메서드를 가지고 있으므로 상속받은 클래스는 run()코드를 반드시 구현해야 합니다.
앞서 언급한대로 Message가 int나 Object같이 스레드 간 통신할 내용을 담는다면, Runnable은 실행할 run() 메서드와 그 내부에서 실행될 코드를 담는다는 차이점이 있습니다.

HandlerThread

Looper에서 언급했듯이 안드로이드의 스레드는 Java의 스레드를 사용하기 때문에 안드로이드에서 도입한 Looper를 기본으로 가지지 않는다는 불편함이 있습니다. 이 같은 불편함을 개선하기 위해 생성할 때 Looper를 자동으로 보유한 클래스를 제공하는데, 이것이 바로 HandlerThread입니다.
HandlerThread는 일반적인 스레드를 확장한 클래스로 내부에 반복해서 루프를 도는 Looper를 가집니다. 자동으로 Looper 내부의 Message Queue도 생성되므로 이를 통해 스레드로 Message나 Runnable을 전달받을 수 있습니다.

AsyncTask

AsyncTask는 스레드나 메시지 루프 등의 작동 원리를 몰라도 하나의 클래스에서 UI작업과 backgrond 작업을 쉽게 할 수 있도록 안드로이드에서 제공하는 클래스입니다. 캡슐화가 잘 되어 있기 때문에 사용시 코드 가독성이 증대되는 장점이 있으며, 태스크 스케쥴을 관리할 수 있는 콜백 메서드를 제공하고, 필요할 때 쉽게 UI 갱신도 가능하며 작업 취소도 쉽습니다. 따라서 리스트에 보여주기 위한 데이터 다운로드 등 UI와 관련된 독립된 작업을 실행할 경우 AsyncTask로 간단하게 구현할 수 있습니다.

그림: AsyncTask의 구조

그러나 AsyncTask를 사용해서 스케줄링 할 수 있는 작업 수의 제한이 있고, 몇 초 정도의 짧은 작업에서만 이상적으로 동작한다는 한계가 있습니다. 또한, 안드로이드의 버전 별로 병렬 처리 동작이 다르므로 허니콤 이후 버전에서 멀티 스레드로 병렬적인 동작을 원한다면 AsyncTask를 실행할 때 AsyncTask.THREAD_POOL_EXECUTOR 스케줄러를 지정해야 합니다. 
한편 앞서 살펴본 Handler와 Looper를 사용한다면 작동 원리를 고려해야 하며 구현을 직접 해야 하고 코드가 복잡해져서 가독성을 저해한다는 단점이 있지만 그만큼 개발 범위가 자유롭습니다. 또한 UI 스레드에서만 작업하지 않아도 되므로 보다 많은 자율성을 가지고 코드를 제어하기를 원한다면 Handler나 HandlerThread 사용을 고려해 보세요.


1. JOIN 이란?
데이터를 검색하다 보면 테이블 하나만을 이용해서는 원하는 정보를 다 가져오지 못하는 경우가 많습니다. 예를 들어 사원의 급여 정보를 검색하는 경우에 [급여] 테이블에는 사원 번호와 급여 정보만 있는 경우 사원 이름을 같이 검색하고자 한다면 사원 이름을 가지고 있는 [사원] 테이블을 참조해야 합니다. 이렇게 테이블을 서로 연결하여 검색을 할 때 사용되는 것이 JOIN 문 입니다.
JOIN의 종류는 다음과 같이 나눌 수 있습니다.
INNER JOIN
OUTER JOIN
FULL JOIN
CROSS JOIN
이 중에서 가장 많이 사용되는 것이 INNER JOIN 입니다. 다음 [그림 1]을 기준으로 해서 이들 조인의 기능을 살펴보도록 하겠습니다.

[그림 1]
[그림 1]과 같이 [사원] 테이블과 [급여] 테이블이 있습니다. 실제 업무와 다를 수 있지만 조인의 기능을 확인하기 위하여 가정을 하도록 하겠습니다. [사원] 테이블에는 사원 정보가, [대출] 테이블에는 대출 정보가 기록되어 있습니다.
2. INNER JOIN
INNER JOIN은 양쪽의 행들 중에서 서로 연관된 내용만 검색하는 조인 방법입니다. INNER JOIN을 위해서는 우선 [그림 2]처럼 두 테이블에서 공통되지 못한 부분은 JOIN의 대상에서 제외가 됩니다.

[그림 2]
그리고 남아 있는 양쪽의 행들이 다음 [그림 3]과 같이 서로 연관된 행들끼리 결합을 하게 됩니다.

[그림 3]
결국 다음 [그림 4]와 같은 결과를 얻을 수 있게 됩니다.

[그림 4]
위 내용을 INNER JOIN을 이용한 쿼리문으로 표현한다면 다음과 같습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A INNER JOIN 대출 B ON A.사번 = B.사번


o 이 쿼리문에서 A와 B 는 [사원] 테이블과 [대출] 테이블을 가리키는 Alias 입니다. 
o ON 부분을 보면 두 테이블을 '사번' 을 이용하여 연결하고 있습니다.

위 쿼리문은 다음과 같이 표현 할 수도 있습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A JOIN 대출 B ON A.사번 = B.사번
즉 'INNER' 를 생략하고 단순히 'JOIN' 만 사용해도 'INNER JOIN'으로 인식됩니다. 이것은 대부분의 JOIN 이 INNER JOIN 이기 때문에 사용자의 편의를 위한 것입니다.
3. OUTER JOIN
OUTER JOIN은 한쪽 테이블을 기준으로 해서 조인을 형성합니다. 그래서 기준이 되는 테이블은 조인되는 테이블과 연관성이 없다 하여도 검색의 대상이 됩니다. 이러한 이유로 OUTER JOIN에는 다음과 같이 두가지의 방법이 존재하게 됩니다.
LEFT OUTER JOIN (기본값)
RIGHT OUTER JOIN
만일 [사원] 테이블과 [대출] 테이블을 OUTER JOIN 시킬 때 [사원] 테이블을 기준으로 한다면 다음 [그림 5] 와 같은 결과를 얻게 됩니다.

[그림 5]
위 내용을 쿼리문으로 표현한다면 다음과 같습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A LEFT OUTER JOIN 대출 B ON A.사번 = B.사번
하지만 [대출] 테이블을 기준으로 한다면 다음 [그림 6] 과 같은 결과를 얻게 됩니다.

[그림 6]
위 내용을 쿼리문으로 표현한다면 다음과 같습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A RIGHT OUTER JOIN 대출 B ON A.사번 = B.사번
4. FULL JOIN
FULL JOIN은 [그림 5]와 [그림 6]의 결합이라고 생각하시면 됩니다. 결합이 되는 양쪽 테이블에서 연관성이 없는 행도 조인의 결과에 포함되기 때문입니다. [사원] 테이블과 [대출] 테이블의 FULL JOIN의 결과는 다음 [그림 7]과 같습니다.

[그림 7]
위 내용을 쿼리문으로 표현한다면 다음과 같습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A FULL JOIN 대출 B ON A.사번 = B.사번
5. CROSS JOIN
CROSS JOIN은 한쪽 테이블의 모든 행들에 대하여 다른 쪽 행들이 전부 대입이 되는 형태의 조인입니다. 만일 [사원] 테이블과 [대출] 테이블을 CROSS JOIN 시킨다면 [그림 8] 과 같은 각각 대입되어 [그림 9]와 같은 결과를 얻게 됩니다. 단, [그림 8]은 첫번째 행에 대한 대입만을 보여주고 있는데 이러한 대입이 [사원] 테이블의 모든 행에 대하여 이루어지게 됩니다.

[그림 8]

[그림 9]
결국 [사원] 테이블의 행의 갯수 X [대출] 테이블의 행의 갯수 만큼의 행이 CROSS JOIN의 결과를 얻어지게 됩니다.
위 내용을 쿼리문으로 표현한다면 다음과 같습니다.
SELECT A.사번, A.이름, B.도서
FROM 사원 A CROSS JOIN 대출 B
즉, 두 테이블의 연관성이 전혀 필요없게 되므로 ON 절이 포함되지 않습니다.
6. 정리
SELECT 문을 사용 할 때 가장 이해하기 힘든 부분이 JOIN 이 아닌가 싶습니다. JOIN 기능을 잘 익혀 두면 좀더 효율적인 검색을 할 수 있습니다. OUTER JOIN이나 FULL JOIN, CROSS JOIN은 잘 사용이 되지 않습니다. 그 이유는 많은 사람들이 INNER JOIN 까지만 배우고 더이상은 JOIN에 대하여 배우지 않고 무작정 SELECT 문을 사용하기 때문이 아닌가 싶습니다.
다음 강좌에서는 실제로 JOIN을 사용하는 예제를 보면서 다시한번 JOIN에 대하여 살펴볼 예정입니다. 온라인 설명서(Books Online)을 보시면 JOIN에 대한 방대한 량의 설명이 있습니다. 그 내용을 꼭 참고하여 주시기 바랍니다.


'Major > Database' 카테고리의 다른 글

데이터베이스 - MySql  (0) 2015.11.26
데이터베이스 - 데이터 타입  (0) 2015.11.26
데이터베이스 - 트랜잭션  (0) 2015.11.26
데이터베이스 - SQL  (0) 2015.11.25
데이터베이스 - 관계 대수  (0) 2015.11.25

출처: http://sejoong.github.io/dev/2015/02/15/dev/HTTP 2.0 : The New Web Standard and Issue(허태성, saturn.twinfish@gmail.com)

HTTP 1.1 이후로 처음 등장한 새로운 버전인 HTTP/2.0을 알아보기 전에 HTTP가 무엇인지 알아보고 HTTP/2.0에서는 어떤 변화가 있는지 알아보자.

HTTP

HyperText Transfer Protocol의 약자로 WWW(World Wide Web)에서 하이퍼텍스트(hypertext) 문서를 교환하기 위하여 사용되는 통신규약이다.
1.0(1996s)m 1.1(1999s)두가지 버전이 있다.

  • Status code:
    http 통신중 요청의 상태 정보를 제공한다. 공식 적인 상태코드 목록은 IANA에서 확인할 수 있다.
    상태코드의 첫 숫자는 응답의 종류를 나타낸다. 아래는 응답의 종류와 내가 개발중 많이 접했던 몇가지 상태 코드 이다.
  1. 1xx - Informational - 정보교환
  2. 2xx - Success - 성공
    200 - OK - 요청이 성공적으로 전송됨
  3. 3xx - Redirection - 방향 지정
    301 - Moved Permanently - 요청 페이지의 영구적인 위치 변화
    302 - Found - 요청 페이지이 일시적인 위치 변화
  4. 4xx - Client Error - 클라이언트 오류
    404 - Not Found - 요청받은 자원을 서버에서 찾을 수 없을때 나타나는 상태 
    405 - Method Not Allowed - 서버에서 사용자가 요청한 주소의 메소드를 지원하지 않을때 나타남
  5. 5xx - server Error - 서버 오류
  • Request methods:
    요청이 수행될 작업의 방법을 나타낸다.

    1. OPTIONS: 요청한 URL에 어떠한 메소드 요청이 가능한지 묻는다.
    2. GET: 다른 작업없이 데이터의 검색에 이용.
    3. HEAD: 데이터의 검색에 이용하나 GET과는 다르게 응답 HEADER만 받는다.
    4. POST: URL에 새로운 데이터를 보낼때 사용.
    5. PUT: URL에 저장될 정보를 보낸다.
    6. DELETE: URL의 리소스를 삭제한다.
    7. TRACE: 보낸 메세지를 다시 돌려받는다.
    8. CONNECT: 프록시에서 사용되는 예약 메소드.
  • 요청/응답 스펙

Request-Line
*(( general-header | request-header | entity-header ) CRLF)
CRLF
[ message-body ]

  1. Request-line: method, request url, http버전
  2. Request-header: general-header, request-header, entity-header가 존재하며 필요에 따라 사용

Status-Line

*(( general-header | response-header | entity-header ) CRLF)
CRLF
[ message-body ]

  1. status-line: http 버전, 상태 코드, 상태 메세지
  2. Request-header: general-header, response-header, entity-header

HTTP/2.0의 등장 배경 및 특징

latency를 줄여 웹의 속도를 개선하기 위해 등장.
1. HTTP Header 데이터 압축
2. Server Push(서버에서 부터 시작되는 전송)
3. HTTP 1에서 존재하던 head-of-line blocking 문제 개선
4. 싱글 TCP connection내에서 병렬 페이지 로딩 구현
2.0은 기존 버전인 1.1과의 높은 호환성(method, status codes 등)은 보장하고 클라이언트 서버 간 전송 및 프레임의 개선에 초점을 맞췄다.
head-of-line blocking: 동일한 송신 포트 자원에 대한 처리량 경쟁으로 인해 처리량 지연 및 프레임 손실 발생 유발 작업대기 중인 2개의 패킷이 존재할 경우 첫번째 패킷이 대기중이면 그 뒤 패킷들은 무조건 대기할때 발생












HTTP 2.0의 개선 사항

  1. 효율적인 페이지 로딩을 위해 URL의 이미지, 스크립트등의 자원을 압축해 페이지 렌더링을 위한 요청횟수를 감소시켰다.
  2. 뿐만 아니라 server가 push가 가능해 웹페이지의 렌더링이 필요하단 사실을 알게되면 추가 요청없이 서버가 리소스를 제공한다.
  3. 그 외에도 성능 개선을 위한 요청 다중화, 헤더 압축, HOL Blocking해결을 위한 요청 우선순위 결정등이 있다.

HTTP/2.0과 SPDY와의 관계

  • SPDY:
    Google이 ‘speedy’라는 단어를 기반으로 제안한 새로운 프로토콜이다. HTTP의 단점들을 보완하여, 인터넷 환경을 보다 효율적으로 이용하기 위한 프로토콜이다. HTTP/2.0에서는 스펙에 SPDY를 반영할 예정이다.

  • 특징:

    1. TLS 위에서 동작한다.

      • https에서만 적용가능
    2. HTTP 헤더를 압축한다.

      • 요청마다 반복되는 내용을 압축해 성능 향상 효과가 나타남
    3. 바이너리로 프레임을 구성한다.

      • 파싱 속도가 향상되고 오류확률은 낮아진다.
    4. 다중 연결을 지원한다.

      • 다수의 요청, 응답 을 동시에 처리 할 수 있어 속도 향상
    5. 인터리빙을 허용한다.

      • 우선순위가 높은 데이터가 더 빨리 전송 될 수있다.
    6. 서버 푸시가 가능하다.

결론

HTTP 1.1 이 사용하는 전송방식(RFC7230)에는 몇가지 문제점이 존재했다.
HTTP/1.0은 TCP connection에서 한번에 하나의 요청 만이 가능했고 HTTP/1.1에서는 그보다 발전하여 request pipelining을 사용했지만 여전히 HOL Blocking 문제가 존재했다.
HTTP/2.0은 오랫동안 변화하지 않았던 HTTP를 현 웹 환경에 맞게 발전시켜 속도의 향상을 도모 한다는데 크 의의가 있다.

참고: http://http2.github.io/http2-spec/#intro 참고: http://helloworld.naver.com/helloworld/140351


'Major > Network' 카테고리의 다른 글

http vs https  (0) 2016.03.23
네트워크 - 총 정리  (0) 2015.12.18
네트워크 - Link Layer  (0) 2015.12.17
네트워크 - Network Layer  (0) 2015.12.10
네트워크 - Transport Layer  (0) 2015.12.09

※요약

인라인 함수는 프로그램의 실행 속도를 높이기 위해 추가된 기능이며 C언어의 매크로 함수와 비교된다.


(개발자 입장에서)일반 함수와 인라인 함수의 가장 큰 차이점은 함수의 호출 방식이다.

일반 함수의 호출 방법은 프로그램 실행 중 함수를 실행해야하면 해당 함수의 주소로 점프시켰다가, 함수의 처리가 종결되면 다시 원래의 자리로 돌아오는 것이다.

이렇게 앞뒤로 점프를 수행하고, 점프할 위치를 기억하려면 함수를 사용하는데 시간이 많이 걸린다.


인라인 함수는 컴파일된 함수 코드가 프로그램의 코드 안에 직접 삽입되어진다.

이 말은 컴파일러가 함수를 호출하는 대신, 그에 대응하는 함수 코드로 대체한다는 것을 의미하며 함수 호출없이 삽입된 함수 코드를 그 자리에서 처리하므로 해당 함수를 수행하기 위해 프로그램이 다른 주소로 점프했다가 되돌아 올 필요가 없어 속도면에서 유리하다.



일반 함수 어셈블리어


인라인 함수 어셈블리어



※특징

 - 인라인 함수를 사용하려면 함수 선언 앞에 inline이라는 키워드를 붙이거나 함수 정의 앞에 inline이라는 키워드를 붙인다.

 - 클래스 멤버 함수가 inline을 사용하려면, 함수 정의의 위치가 *.h에 있어야 한다. 안 그러면 확인할 수 없는 외부 참조라고 뜬다.

 - 프로그래머가 inline 선언을 해도 컴파일러가 인라인화를 거부할 수 있다.

 - 프로그래머가 inline 선언을 안 해도 컴파일러가 인라인화를 할 수 있다.

 - 함수의 덩치가 크거나 재귀호출이면 inline 요구를 거절하는 컴파일러도 있다.

 - 함수 코드의 수행 시간이 짧고 빈번하게 호출되는 함수가 아니라면, 인라인 함수로 인한 절대적인 시간 절약은 그다지 크지 않다.



※장점

 - 함수가 인라인화 되어 성능의 향상으로 이어질 수 있다.



※단점

 - 메모리 사용 측면에서는 인라인 함수가 일반 함수보다 불리하다.

   이유는 어떤 프로그램에서 인라인 함수를 열 번 호출한다면, 

   프로그램은 그 함수의 사본을 프로그램의 코드 안에 열 번이나 삽입해야 하기 때문이다.

 - 매크로 함수와 달리 자료형에 독립적이지 못 하다. 단, 템플릿을 이용하면 자료형에 독립적으로 사용할 수 있다.



※예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
using namespace std;
 
inline void Test( int nNum1 );
 
int main( )
{
    Test( 2 );
 
    return 0;
}
 
void Test( int nNum1 )
{
    int nResult = nNum1;
}


  • 동적 계획법
    - Top-down
    1. 문제를 작은 문제로 나눈다.
    2. 작은 문제를 푼다.
    3. 작은 문제를 풀고, 문제를 푼다.(큰 문제를 풀어 간다.)

    * CODE - 피보나치
     : 트리로 생각하자

    int memo[100];
    int fibonacci(int n) {
    	if (n <= 1) {
    		return n;
    	}
    	else {
    		memo[n] = fibonacci(n - 1) + fibonacci(n - 2);
    		return memo[n];
    	}
    }
    

     : memorization을 이용하면 반복을 줄일 수 있다! 


    int memo[100];
    int fibonacci(int n) {
    	if (n <= 1) {
    		return n;
    	}
    	else {
    		if (memo[n]) {
    			return memo[n];
    		}
    		memo[n] = fibonacci(n - 1) + fibonacci(n - 2);
    		return memo[n];
    	}
    }
    

     
    - Bottom-up
    1. 문제를 크기가 작은 문제부터 차례대로 푼다.
    2. 문제의 크기를 조금씩 크게 만들면서 문제를 점점 푼다.
    3. 작은 문제를 풀면서 왔기 때문에, 큰 문제는 항상 풀 수 있다.
    4. 반복하면 언젠간 풀어야 하는 문제를 풀 수 있다.

    * CODE - 피보나치

    int dp[100];
    int fibonacci(int n) {
    	dp[0] = 1;
    	dp[1] = 1;
    	for (int i = 2; i <= n; i++) {
    		dp[i] = dp[i - 1] + dp[i - 2];
    	}
    	return dp[n];
    }


'Algorithm' 카테고리의 다른 글

에라토스테네스의체  (0) 2016.03.22
알고리즘 - 보간 탐색  (0) 2015.11.14
알고리즘 - 이진 탐색  (0) 2015.11.14
알고리즘 - 순차 탐색  (1) 2015.11.14
알고리즘 - 위상 정렬  (0) 2015.11.14

출처:  http://ohyecloudy.com/pnotes/archives/294/


컨테이너 정렬이 필요할 때, sort를 사용하고 순서가 유지돼야 하면 stable_sort를 사용했다. partial_sort와 nth_element는 한 번도 사용해본 적이 없는데, 일부분만 정렬이 필요하거나 몇 번째 원소를 뽑을 때 유용하게 사용할 수 있을 것 같다. 예를 들면 최고 작은 수 10개만 차례대로 혹은 차례 상관없이 뽑는다던지, 9번째로 작은 수만 뽑는다던지 할 때에 사용하면 좋을 거 같다. 구현하는데 시간을 추가로 쓰는 것도 아니고 이미 구현되어 있는데, 딱 필요한 만큼만 정렬해서 시간을 절약할 수 있다. 아무리 작은 시간이라 하더라도 그냥 낭비하는 건 죄를 짓는 거.

nth_element는 정렬 기준에 따라 몇 번째 원소만 정확히 뽑아준다. 원소를 기준으로 정렬 기준에 맞게 좌우를 나눠주기는 하는데, 그 원소들 사이에 정렬은 되어 있지 않은 상태이다. 

partial_sort는 시작점부터 지정한 위치까지만 정렬해준다. 나머지는 정렬되지 않은 상태로 놔둔다. sort와 stable_sort는 시작점에서 끝점까지 정렬하는데, 정렬되고 난 뒤 stable을 보장 여부가 다르다. 동일한 정렬 기준을 가진 녀석들의 순서가 정렬 후에도 바뀌지 않으면 stable하다고 하는데, 뒤에 소스 코드 예를 보면 단박에 이해된다. 참고로 merge sortinsertion sort가 대표적인 stable sort 알고리즘이고 unstable sort의 대표적인 알고리즘은 quicksort다.

수행 시간은 nth_element < partial_sort < sort < stable_sort 이다.

sort, stable_sort, partial_sort 테스트 소스 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

////////////////////////////////////////////////////////////////////////////////
// Item
////////////////////////////////////////////////////////////////////////////////
struct Item
{
    int     num;
    char    tag;

    explicit Item(int n, char t = ' ') : num(n), tag(t) {}
};

inline bool operator< (const Item& lhs, const Item& rhs)
{
    return lhs.num < rhs.num;    // 숫자만 비교한다.
}

inline std::ostream& operator<< (std::ostream& ost, const Item& item)
{
    ost << item.num << item.tag;
    return ost;
}

정렬 알고리즘에서 호출해주는 operator < 는 숫자만 비교한다. tag는 stable하게 정렬되는지 확인하는 용도로 사용한다.

////////////////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////////////////
int main()
{
    const Item itemArray[40] =
    {
        Item (-4, ' '), Item (16, ' '),
        Item (17, ' '), Item (-3, 's'),
        Item (14, ' '), Item (-6, ' '),
        Item (-1, ' '), Item (-3, 't'),
        Item (23, ' '), Item (-3, 'a'),
        Item (-2, ' '), Item (-7, ' '),
        Item (-3, 'b'), Item (-8, ' '),
        Item (11, ' '), Item (-3, 'l'),
        Item (15, ' '), Item (-5, ' '),
        Item (-3, 'e'), Item (15, ' '),
        Item (-4, ' '), Item (16, ' '),
        Item (17, ' '), Item (-3, 's'),
        Item (14, ' '), Item (-6, ' '),
        Item (-1, ' '), Item (-3, 't'),
        Item (23, ' '), Item (-3, 'a'),
        Item (-2, ' '), Item (-7, ' '),
        Item (-3, 'b'), Item (-8, ' '),
        Item (11, ' '), Item (-3, 'l'),
        Item (15, ' '), Item (-5, ' '),
        Item (-3, 'e'), Item (15, ' ')
    };

    typedef std::vector<Item> ItemVector;

    ItemVector v0(
        itemArray, itemArray + sizeof(itemArray) / sizeof(itemArray[0]));
    ItemVector v1(v0.begin(), v0.end());
    ItemVector v2(v0.begin(), v0.end());

    std::sort (v0.begin(), v0.end());
    std::stable_sort (v1.begin(), v1.end());
    std::partial_sort (v2.begin(), v2.begin() + 10, v2.end());

    std::cout << "### sort(begin, end)\n";
    std::copy (v0.begin(), v0.end(), std::ostream_iterator<Item>(std::cout, " "));
    std::cout << "\n\n### stable_sort(begin, end)\n";
    std::copy (v1.begin(), v1.end(), std::ostream_iterator<Item>(std::cout, " "));
    std::cout << "\n\n### partial_sort(begin, begin+10, end)\n";
    std::copy (v2.begin(), v2.end(), std::ostream_iterator<Item>(std::cout, " "));

    return 0;
}

20개 정도로 하니깐 sort로 정렬해도 결과가 stable해서 40개로 늘렸다. VS2005의 딩컴웨어 STL에서는 원소 개수가 32개 보다 작으면 insertion sort를 하기 때문에 20개로 sort를 호출하면 stable한 결과가 나온다. 정렬 알고리즘은 원소를 변경하기 때문에 복사해서 똑같은 원소를 가진 벡터를 3개 만들고 각각을 정렬한 다음 출력했다.

sort는 stablestable의 순서가 엉켜있고 stable_sort는 제대로 출력하고 있다.partial_sort는 [begin, begin+10) 까지만 정렬을 한다.

nth_element 테스트 소스 코드

nth_element 같은 경우는 위와 같은 예제로 하면 확인이 어려워 따로 테스트 코드를 만들었다.

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

int main()
{
    // VS 2005에서 원소 개수가 32개 이하면 Insertion sort를 한다.
    static const int INSERTION_SORT_THRESHOLD = 33;
    std::vector<int> v;
    v.reserve(INSERTION_SORT_THRESHOLD);

    for (int i = 0; i < INSERTION_SORT_THRESHOLD; ++i)    v.push_back(i);
    std::random_shuffle(v.begin(), v.end());

    std::cout << "### before\n";
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;

    std::cout << "### nth_element(begin, begin+12, end)\n";
    std::nth_element(v.begin(), v.begin()+12, v.end());
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
}

VS 2005의 딩컴웨어 STL 구현을 보면 분할 정복 알고리즘(Divide and conquer algorithm)을 사용해서 구현했는데, 여기서도 sort와 같이 분할한 구역 원소 개수가 32개 이하이면 insertion sort을 한다. 그래서 출력해보면 12 앞에 숫자들이 정렬된 상태로 보인다. 처음에 원소를 10개로 잡아 놓고 테스트를 했는데, 전체가 정렬돼서 무척 의아했다. 궁금해서 소스코드를 보니 원소 개수가 32개 이하이면 insertion sort로 정렬하더라.

STLport 5.1.3 으로 돌려본 결과. insertion sort를 하는 threshold가 3이다.


'Programing > C++' 카테고리의 다른 글

inline 함수  (0) 2016.04.12
  • HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)는 월드 와이드 웹 통신 프로토콜인 HTTP의 보안이 강화된 버전이다. HTTPS는 통신의 인증과 암호화를 위해 넷스케이프 커뮤니케이션즈 코퍼레이션이 개발했으며, 전자 상거래에서 널리 쓰인다.
    HTTPS는 소켓 통신에서 일반 텍스트를 이용하는 대신에, SSL이나 TLS 프로토콜을 통해 세션 데이터를 암호화한다. 따라서 데이터의 적절한 보호를 보장한다. HTTPS의 기본 TCP/IP 포트는 443이다.
    보호의 수준은 웹 브라우저에서의 구현 정확도와 서버 소프트웨어, 지원하는 암호화 알고리즘에 달려있다.
    HTTPS를 사용하는 웹페이지의 URL은 'http://'대신 'https://'로 시작한다.

5. HTTPS

SSL은 전자상거래에서의 데이터 보안을 위해서 개발한 통신 레이어다. SSL은 표현계층의 프로토콜로 응용 계층 아래에 있기 때문에, 어떤 응용 계층의 데이터라도 암호화해서 보낼 수 있다.

HTTP는 기본적으로 평문 데이터 전송을 원칙으로 하기 때문에 개인의 프라이버시가 오가는 서비스들(전자상거래, 전자메일, 사내문서)에 사용하기 힘들다. HTTPS는 SSL 레이어위에 HTTP를 통과 시키는 방식이다. 즉 평문의 HTTP 문서는 SSL 레이어를 통과하면서 암호화 돼서 목적지에 도착하고, 목적지에서는 SSL 레이어를 통과하면서 복호화 돼서 웹 브라우저에 전달된다.

간혹 HTTPS를 하나의 프로토콜로 인식하기도 하는데, HTTP와 SSL은 전혀 다른 계층의 프로토콜콜의 조합이다. HTTPS over SSL로 보는게 좀더 정확한 시각이다. 거의 모든 웹 서버와 웹 브라우저와 HTTP 기반의 툴들 - wget, curlab 기타등등 - 이 SSL을 지원한다.

5.1.1. HTTP와 다른 점

  • HTTPS URL은 "https://"로 시작한다. 기본 포트번호는 443이다. HTTP URL은 "http://"로 시작한다. 기본 포트번호는 80이다.
  • HTTP는 평문 데이터를 기반으로 하기 때문에, 유저정보와 같은 민감한 정보가 인터넷 상에 그대로 노출된다. 이 정보는 수집되거나 변조될 수 있다. HTTPS는 이러한 공격을 견딜 수 있도록 설계돼 있다.
  • HTTPS는 인증서를 이용해서, 접속 사이트를 신뢰할 수 있는지 평가할 수 있다.
  • 일반적으로 HTTPS는 HTTP에 비해서 (매우 많이)느리다. 많은 양의 데이터를 처리할 경우 성능의 차이를 체감할 수 있다. 많은 웹 사이트들이 민감한 정보를 다루는 페이지(로그인 혹은 유저정보) 페이지를 HTTPS로 전송하고, 기타 페이지는 HTTP로 전송하는 방법을 사용한다. 하드웨어 SSL 가속기를 이용해서 암/복호화 성능을 높이는 방법을 사용하기도 한다.

출처: http://www.joinc.co.kr/w/Site/Network_Programing/AdvancedComm/HTTP

'Major > Network' 카테고리의 다른 글

HTTP1.0 ~ HTTP2.0  (0) 2016.04.12
네트워크 - 총 정리  (0) 2015.12.18
네트워크 - Link Layer  (0) 2015.12.17
네트워크 - Network Layer  (0) 2015.12.10
네트워크 - Transport Layer  (0) 2015.12.09

출처 - http://aroundck.tistory.com/2477

 android, Parcelable vs. Serializable

 

[android] Parcelable vs Serializable


Serializable 은 Java 만 아는 사람이라면 쉽게 알 수 있는 serialization 방법.

그냥 Serializable 을 implementation 만 해주면, serialize 가 필요한 순간에 알아서 serialze 해주는 편리한marker interface.


그러나, mobile 시대가 강림하면서 등장한 유망한 어린이(?) 가 있으니 그는 바로 Parcelable.

이 녀석은 IPC ( Inter Process Communication ) 에 최적화된 녀석으로.

Serialize 보다 속도가 빠르다.

물론, 해야 하는 일은 Serialize 보다 훨씬 많다.

직접 serialize 되어야 할 녀석들을 선별해서 그것을 쓰고 읽는 작업을 해주어야 한다.


그럼 왜 serialization 이 parcelable 보다 속도가 느릴까?

그 이유는, serialization 은 reflection 방법을 사용하여 serialization 을 하는데,

parcelable 은 프로그래머가 직접 바로 setting 을 해주기 때문에 빠른 것이다.

( reflection 이 성능이슈를 야기할 수 있다는 것은 이미 알고 있을꺼라 생각한다.. )


다행스럽게도 둘의 성능차이가 얼마나 날까 테스트 결과를 찾아봤는데

이런 결과를 볼 수 있었다.


[android] Parcelable vs Serializable이미지 출처 : http://www.developerphil.com/parcelable-vs-serializable/

결론적으로 보면,

Serialization 도 그렇게 느리지는 않지만, Parcelable 이 훨씬 빠르다.

정말 많은 뭉태기의 property 들이 한 클래스에 있는 경우는 드물겠지만,

그런 경우라면 Parcelable 의 성능이 훨씬 빠르겠고..

IPC 가 많이 발생하는 경우라면, 가랑비에 옷 젖는 줄 모른다고, 작은 성능 차이가 결국 최적화에 엄청난 영향을 미칠 수 있다. 결국 정말 특별한 이유가 없다면, 사실 귀찮더라도 Serializable 보다는 Parcelable 을 사용하는 것이 추천된다.



컴퓨터 프로그래밍에서 SOLID란 로버트 마틴[1][2]이 2000년대 초반[3]에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 마이클 페더스가 두문자어 기억술로 소개한 것이다. 프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 할 때 이 원칙들을 함께 적용할 수 있다.[3] SOLID 원칙들은 소프트웨어 작업에서 프로그래머가 소스 코드가 읽기 쉽고 확장하기 쉽게 될 때까지 소프트웨어 소스 코드를 리팩토링하여 코드 냄새를 제거하기 위해 적용할 수 있는 지침이다. 이 원칙들은 애자일 소프트웨어 개발과 적응적 소프트웨어 개발의 전반적 전략의 일부다.[3]

개요[편집]

두문자약어개념
SSRP
단일 책임 원칙 (Single responsibility principle)
한 클래스는 하나의 책임만 가져야 한다.
OOCP
개방-폐쇄 원칙 (Open/closed principle)
“소프트웨어 요소는 …… 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.”
LLSP
리스코프 치환 원칙 (Liskov substitution principle)
“프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.” 계약에 의한 설계를 참고하라.
IISP
인터페이스 분리 원칙 (Interface segregation principle)
“특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.”[4]
DDIP
의존관계 역전 원칙 (Dependency inversion principle)
프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”[4] 의존성 주입은 이 원칙을 따르는 방법 중 하나다.


'Others' 카테고리의 다른 글

[현장] 전설의 개발자 제프 딘, 한국 개발자를 만나다  (0) 2016.03.20
Bluetooth Low Energy  (0) 2016.01.26
코드 하이라이트 사용법  (0) 2015.10.26

+ Recent posts