Java 언어는 객체지향 언어로, 현실 사물을 "속성"과 "기능"을 가진 객체로 묘사합니다. 

 

또한 객체간의 관계를 맺어 주어 이해하기 쉽도록 만듭니다. 

 

이 글에서는 Java 언어가 객체간의 "관계"를 설정하는 방법에 대해 다뤄보겠습니다. 

 

 

상속 관계 (Inheritance)

 

두 객체간에 IS-A 관계 (~는 ~이다) 로 이어지는 관계를 보통 상속관계라고 합니다. 


자바에서는 코드의 재사용성, 유지보수, 신뢰성을 유지하기 위해 클래스 간 상속관계를 도입하였습니다. 

 

Java 코드로 묘사한 "물건" 클래스를 통해 상속관계를 이해해봅시다. 

 

“물건을 묘사하는 클래스, 확장가능성이 높은 클래스이다.”

/**
 * 물건을 묘사하는 "객채" 입니다.
 */
public class Thing {

    // 물건은 "모양" 속성을 가집니다.
    String shape;
    // 물건은 "색" 속성을 가집니다.
    String color;
    // 물건은 "주인" 속성을 가집니다.
    String owner;

    public void touchThing() {
        // 누군가가 "만질 수 있는" 기능이 있습니다.
        System.out.println("touch");
    }
    public void useThing() {
        // 누군가가 "사용할 수 있는" 기능이 있습니다.
        System.out.println("use");
    }
}

 

"물건(Thing)"은 우리가 현실에서 여러 가지 사물을 묘사할 때 많이 쓰는 포괄적인 단어입니다. 

 

지시대명사인 "그것", "저것" 처럼 수 많은 사물을 뭉뚱그려 한 단어로 설명할 수 있는 개념이죠. 

 

이렇게 여러 사물에서 공통된 특성을 뽑아내어 더 적은 수의 단어로 묘사하는 것을 "추상화" 라고 합니다.

 

여러 사물의 공통된 속성을 추출하는 것을 추상이라고 한다.

 

 

즉 "사물" 은 자동차, 컴퓨터와 같은 여러 구체적인 것들에서 

 

"물질로 구성되었다"라는 공통된 측면을 뽑아서 한 단어로 묘사한 것입니다.

 

제가 만든 클래스인 Thing은 현실의 단어 "사물"을 바탕으로 묘사한 것이므로 

 

물질로 된 것이라면 무엇이든지 묘사할 수 있습니다.

 

이렇게 많은 개념의 공통된 특성을 하나의 클래스로 묘사한다면 "확장성이 높다" 라고 말 할 수 있겠습니다. 

 

 

실제로 이 Thing을 확장시켜 보겠습니다.  

 

“기계를 묘사하는 클래스, 물건에서 확장된 개념이다. “

/*
* 기계를 묘사하는 "객체"입니다.
* */
public class Machine extends Thing{

    //기계는 "동력원" 을 속성으로 가집니다.
    String energySource;
    // 기계는 "부품"을 속성으로 가집니다.
    String part;

    public void activate() {
        // 기계는 "작동할 수 있는" 기능이 있습니다.
        System.out.println("activated");
    }
    public void shutDown() {
        // 기계는 "멈출 수 있는" 기능이 있습니다.
        System.out.println("SHUTDOWN");
    }

}

 

 맨 윗줄을 보면 class Machine .. 으로, 기계(Machine)이라는 이름의 클래스를 만든 것을 보실 수 있습니다. 

 

그런데 Thing과는 달리, 뒷줄에 두 단어가 더 붙어있습니다. 

 

'extends'와 'Thing'입니다.

 

Thing(사물)을 extends(확장) 시켜서 더 구체적으로 묘사한 결과가 Machine(기계)가 된다는 것입니다. 

 

"기계"는 다른 사물에는 없는 고유한 "속성"과 "기능"도 있습니다. 

 

'돌'은 같은 Thing일지는 몰라도 클래스에 정의된 속성 energySource 와 part를 가질 수는 없습니다. 

 

돌이 activate(작동) 하거나 shutDown(멈춤) 같은 기능이 있다고 보기도 어렵습니다.

 

즉, 여기서의 Machine 클래스는 Thing 클래스가 가진 속성과 기능을 가지면서도 

 

자신의 고유한 속성과 기능을 추가로 가지는 클래스가 된 것입니다. 

 

바로 그렇기 때문에 Thing에서 "확장" 되었다고 말 할 수 있겠습니다. 

 

 

이렇게 Java에서는 A extends B 라는 문법으로 A와 B를 "상속 관계" 로 만듭니다. 

 

두 객체간의 관계를 extends 라는 문법으로 확실히 정의해 주는 것입니다. 

 

객체 A (예를 들어, Thing)은 얼마든지 다른 객체로 "확장될" 수 있습니다.

 

게다가 물건이 꼭 기계만 있는 것은 아니기 때문에

 

Thing extends Cup, 역시 개념적으로 아무런 문제가 없습니다. 

 

객체 A는 무수히 많은 B와 상속관계를 맺을 수 있는 것입니다.

 

“자동차를 묘사하는 클래스, 기계에서 확장된 개념이다.”

/**
 * 자동차를 묘사하는 "객채" 입니다.
 */
public class Car extends Machine{

    // 차는 "엔진 회전수"를 속성으로 가집니다.
    String bpm;
    // 차는 "자동차 바퀴 갯수"를 속성으로 가집니다.
    int numberOfTire;
    // 차는 "주행거리"를 속성으로 가집니다.
    long distanceDriven;

    // 변수가 아닌 Class를 통해서 차와 - 부품들의 Has-a 관계를 묘사합니다.
    // 클래스는 다른 클래스를 "속성"으로 가질 수 (HAS-A) 있습니다.
    CarSheet carSheet = new CarSheet();
    Engine engine = new Engine();
    Wheel wheel = new Wheel();

    public void drive(String owner) {
        //차는 "운전할 수 있는" 기능이 있습니다.
        System.out.println(owner + "drives the car");
    }
    public void useAirConditioner(String bpm) {
        //차는 "에어컨을 돌릴 수 있는" 기능이 있습니다.
        System.out.println("car use AirConditioner with his " + bpm + "bpm Engine");
    }

}

 

이번에는 상속관계에 대해 좀 더 깊이 들어가 보도록 하겠습니다. 

 

현실 자동차의 속성과 기능을 가지는 Car 클래스를 만들어 봅시다. 

 

이번에도 역시 Car extends Machine 이라는 문법을 통해서 Machine을 확장시켜 Car을 묘사하고 있습니다. 

 

그런데, 앞에서 선언했듯이 Machine은 Thing을 확장시켜 만든 클래스입니다. 

 

즉, Car은 Machine을 확장시켜 만들었으니, Thing에도 포함되는 게 확실하겠군요. 

 

이렇게 상속관계는 서로다른 두 객체만 관계가 생기는 것이 아니라, 

 

상속을 받은 ( 확장된 ) 객체가 또 다른 객체와 상속관계를 맺으면 꼬리에 꼬리를 물고 이어지게 됩니다. 

 

결국 Car을 다시 확장해서 벤츠(Benz)를 만들면 "물건(Thing)" 이면서 "기계(Machine)"이면서 "차(Car)"이므로 

 

벤츠는 저 세 가지 객체의 속성과 기능을 모두 가지게 되는 것입니다. 

 

 

 

이런 상속관계를 세밀하게 묘사하면 어떤 장점이 있을까요? 

 

먼저 같은 코드의 재사용성이 높아집니다. 

 

만약 Thing을 상속하지 않았다면, 기계나 자동차에게 "색깔" 속성이나 "만질 수 있는" 기능을 일일히 붙여넣어 주어야 합니다. 

 

그러나 상속관계를 통해 속성과 기능을 공유하도록 만들었기 때문에 그럴 필요가 없습니다. 

 

Thing의 속성과 기능을 정의하는 코드는 앞으로 extends Thing 두 단어만 사용하면 어떤 클래스에든 재사용할 수 있습니다. 

 

코드의 유지보수도 역시 쉬워집니다. 

 

만약 내가 만드는 모든 자동차를 "가솔린" 차량으로 만들고 싶다면, energySource를 검증하는 기능을 하나 만들어주기만 하면 됩니다. 

 

public boolean checkIsGasolineCar() {
   if(energySource.equals("gasoline")) {
        return true; 
    } else {
        return false;
    }
}

 

 

 

게다가 코드에 대한 이해도가 매우 높아집니다.

 

만약 제가 DAS;KJFADFA9124109248S 라는 클래스를 만든다고 가정한다면, 이 코드만으로는 대체 

 

무엇을 묘사하고자 하는지 알기 힘들 것입니다. 

 

그러나 'DAS;KJFADFA9124109248S extends Car ' 라는 문법을 통해 Car 클래스와의 관계를 만들어 준다면 

 

코드를 읽는 사람이 "아 이 DAS;KJFADFA9124109248S는 Car과 관련있거나, 혹은 Car의 한 종류이겠군" 이라고

 

제가 짠 코드의 맥락(Context)을 금방 파악할 수 있을 것입니다. 

 

 

이렇게 상속관계를 세밀하게 묘사하면 객체지향 언어가 가지는 장점인 높은 재사용성, 쉬운 유지보수 뿐만아니라 

 

다른 사람도 이해하기 쉽고, 나중에 자신이 읽어도 금방 기억할 수 있는 코드가 됩니다. 

 

Java 언어를 사용하실 때는 이러한 장점들을 가진 "상속"을 꼭 사용해 보시기를 바랍니다. 

 

 

'플라자' 카테고리의 다른 글

SPI, Service Provider Interface ( 서비스 제공자 인터페이스 )  (0) 2022.07.17
JAVA의 객채지향  (0) 2022.06.12

RFC 문서를 통한 웹 표준 및 프로토콜 레벨의 기반기술에 대해 다루기 전에 

 

RFC 문서를 관리하고 생산하는 IETF를 소개합니다.

 

Internet Engineering Task Force

 

IETF, 인터넷 표준화를 지향하는 비영리 단체 

 

IETF의 공식 홈페이지에 소개된 글을 참조하면 

 

IETF는 자신들의 목적을 "인터넷을 더 좋게 만드는 것" 이라고 명시하고 있습니다. 

 

The IETF's mission is "to make the Internet work better," 

 

 

더 구체적으로는 "엔지니어링 관점에서 인터넷을 향상시키는 것"이라고 언급하여 

 

"엔지니어링 테스크포스"라는 정의에 알맞게 단체의 목적을 소개하고 있습니다. 

 

 

 

 IETF 단체는 주로 "RFC"라고 하는 특정한 문서(Document)를 관리, 생산합니다. 

 

'Request for Comment' 의 약어인 RFC는 실제 서비스되는 여러 어플리케이션과 프레임워크의 

 

기초적인 아이디어가 될 정도로 공학적으로 수준 높고 검증 가능한 기술문서로 널리 알려져 있습니다. 

 

대표적으로 HTTP로 잘 알려져 있는 Hypertext Transfer Protocol 역시 

 

RFC 2621로 RFC 문서화되어 웹에 개시되어 있으며,

 

이를 바탕으로 표준적인 웹 통신 규약으로써 쓰이고 있습니다. 

 

 

IETF 단체의 구조 

 

IETF는 구성원의 참여를 중시하는 비영리 단체로써, 자유로운 참여를 무엇보다 중요시합니다. 

 

공식 홈페이지에도 정기적으로 개최되는 Hackerthon(소프트웨어 이벤트) 및 CodeSprint 등을 지원하고

 

오프라인으로 참여하지 않더라도 이메일을 통해 현재 진행중인 웹 표준화 작업에 동참할 수 있습니다. 

 

IETF는 작은 워킹 그룹(Working Group)이 모여 에어리아(Area)라는 큰 주제에 대해 논의하며 

 

RFC로 공식화되기 이전의 임시 문서인 Internet-Drafts 문서를 생산하고 수정합니다. 

 

 

실제로, 현재 프로토콜에 대해 논의중인 구성원이나 의장에게 이메일을 보낼 수도 있으며 

 

개선 중인 문서를 살펴볼 수도 있습니다. 

 

실제 에어리아(Area)에 접근할 수 있다.

 

표준으로 선별되기 전의 문서들을 살펴보고 코멘트 할 수 있다

 

이렇게 생산된 문서들은 IESG(Internet Engineering Steering Group)에서 검토하여 

 

공식적으로 RFC 문서에 등록됩니다. 

 

비영리 단체인 만큼 대부분은 후원과 참여자의 자원으로 운영되지만 

 

 IANA에서 관리에 필요한 지원을 받고 있다고 공식적으로 언급하기도 합니다. 

 

 

 

 

적극적인 참여 유도 

 

 

 

 

기존의 WG(Working Group)나 각종 모임에 쉽게 참여할 수 있는 방법을 유튜브 영상으로 소개하기도 합니다. 

 

엔지니어들의 적극적인 참여를 바탕으로 운영되는 단체이다 보니 자발적인 관계를 추구하며 

 

공식 홈페이지에도 최근 (7월 23일, 29일) 에 열리는 행사를 소개할 만큼 

 

활발하게 운영되고 있어, 신뢰성 있는 단체라고 할 수 있겠습니다.  

 

공식 홈페이지에 소개된 IETF 114,115 시간과 장소

 

 

이로써 RFC문서를 생산하고 관리하는 비영리 단체 IETF에 대한 대략적인 소개를 마치겠습니다. 

 

W3C, WHATWG 등 여러 웹 표준화를 지향하는 단체들이 있지만 

 

프로토콜을 정의하고 관리하는 데 이만큼 공신력 있는 단체를 또 찾기는 어려울 것이라고 생각합니다. 

 

시간이 있으시다면, IETF에서 제공하는 다양한 문서나 

 

실제 문서제작 참여를 위한 튜토리얼 등도 구경해보시기 바랍니다. 

 

 

참고자료 

 

 

 

Home

 

www.ietf.org

 

HTTP는 팀 버너스리에 의해 발명된 WWW(월드와이드웹)에 내지 된 프로토콜이다.

HTTP를 간단하게 설명하면 웹에서 데이터를 전송하는 약속, 규칙이라고 생각하면 된다.

 

CERN(유럽입자연구소)에서 일하던 팀버너스리에 의해 HTTP가 제안이 되었다.

 

사용자가 서버(웹사이트)에 어떤 정보를 얻기위해서는 요청을 해야 하는데 이때 HTTP에서 제공하는 메서드와 헤더에 입력된 정보를 기반으로 정보를 응답받는다.

 

이런 식으로 우리가 사용하는 웹사이트가 정보를 주고받는다.

 

요청

GET /restapi/v1.0 HTTP/1.1
Accept: application/json
Authorization: Bearer UExBMDFUMDRQV1MwMnzpdvtYYNWMSJ7CL8h0zM6q6a9ntw

응답

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

<html>
<head>
  <title>An Example Page</title>
</head>
<body>
  Hello World, this is a very simple HTML document.
</body>
</html>

요청 메서드(HTTP 동사)

주어진 리소스(동영상, 메시지, 뉴스글 등)에 수행하길 원하는 행동을 나타낸다. 각각의 메서드는 서로 다른 의미를 구현

HTTP 메서드 RFC 간단설명
GET RFC 7231 해당 메서드는 특정 리소스를 받기만 요청한다.
POST RFC 7231 특정 리소스를 제출할 때 사용한다. 서버의 상태 변화를 일으킨다.
PUT RFC 7231 특정 리소스로 새롭게 생성하거나, 대상 리소스를 대체한다.
DELETE RFC 7231 특정 리소스를 삭제한다.
PATCH RFC 5789 해당 메서드는 리소스의 부분만을 수정하는데 사용한다.

이 외에도 HEAD, CONNECT, OPTIONS, TRACE가 존재한다.

 

응답 상태 코드

HTTP 요청이 성공적으로 완료되었는지 알려주는 코드입니다. 숫자로 사용자에게 알기 쉽게 표시를 해주며 총 5개의 그룹으로 나누어진다.

  • Informational responses(조건부응답) 100 ~ 199
  • Successful responses(성공응답) 200 ~ 299
  • Redirection messages(재요청응답) 300 ~ 399
  • Client error responses(요청오류응답) 400 ~ 499
  • Server error responses(서버오류응답) 500 ~ 599

여기서는 자주 접하거나 알아두면 좋은 코드들을 위주로 작성했다.

1xx (조건부응답) : 요청은 잘 받았고 받은 요청을 처리하고 있는 중이다.

해당 상태 코드는 RFC2616에 기록된 내용으로 보면 요청된 내용은 지금까지 모두 정상이며 요청이 계속되거나 이미 완료가 된 상태이면 요청을 무시해라고 적혀있다. 그래서 HTTP/1.0 버전 이후로 웹을 사용하는 사람들은 해당 응답 코드를 볼 수 없다.

 

100 (계속)

요청한 상태는 괜찮으며 첫 번째 요청을 받았으니 나머지는 기다리고 있다를 나타낸다.

 

2xx (성공응답) : 요청이 성공적으로 완료되었습니다.

200 (성공)

요청한 내용이 제대로 처리되었고 원하는 리소스를 제공받았다.

 

201 (생성)

요청이 성공적으로 완료하였고 서버(웹사이트)에 새로운 리소스를 생성했다.

 

204 (콘텐츠없음)

정상적으로 요청을 마무리했지만 리소스(콘텐츠)를 제공하지 않는다.

 

3xx (재요청응답) : 요청을 완료하기 위해서 추가 동작을 취해야 한다.

300 (여러선택 항목)

요청에 대해서 하나 이상의 응답이 가능하다. 요청자는 그중에 반드시 하나를 선택해야 한다.

 

4xx (요청오류) : 잘못된 문법을 사용자가 사용하여 서버가 상태를 이해하지 못한다.

400 (잘못된요청)

잘못된 문법으로 인하여 서버가 요청을 이해하지 못한다.

 

401 (인증없음)

요청했던 해동이 인증(권한)이 필요하여 사용자는 해당 요청을 위해서 인증을 받아야 한다.

 

403 (접근금지)

사용자가 해당 리소스에 인증 여부와는 관련 없이 접근할 권리가 없다. (401은 인증 실패, 403은 인가 실패)

 

404 (찾을 수 없음)

서버가 요청한 페이지(리소스)를 찾을 수 없다. 알려지지 않는 URL을 의미한다.

 

5xx (서버오류) : 유효한 요청을 서버가 제대로 수행하지 못했을 때를 의미한다.

500 (내부 서버 오류)

서버에 문제가 발생한 것으로 요청을 수행할 수 없다.


위에 입력된 상태 코드와 요청 메서드 말고도 더 다양하니 참고자료에 적힌 사이트에 들어가서 직접 보는 것을 권장합니다.

 

참고자료

HTTP - 위키백과, 우리 모두의 백과사전 (wikipedia.org)

HTTP 상태 코드 - HTTP | MDN (mozilla.org)

HTTP/1.1: Status Code Definitions (w3.org)

rfc2616 (ietf.org)

JWT는 "Json Web Token"의 약자로써 RFC7519로 인터넷표준 암호화 토큰이다. 해당 기술은 세션기반의 인증보다는 Stateless기반(비세션기반)의 웹페이지에서 주로 사용을 한다고 한다.

 

 세션기반의 인증은 클라이언트가 로그인시 해당 유저의 정보를 서버의 세션에 저장을 한뒤 서버의 세션값을 유저에게 보낸다. 그리고 정해진 시간안에서는 세션이 계속 유지가되면서 서버와의 데이터전송이 가능하다. 

 

다만 해당 세션기반의 가장 치명적인 약점은 바로 "확장성"이다.

 

예를들어 A라는 웹애플리케이션을 처음 설계를 할때는 사용자가 많지않을꺼라 생각해서 100명정도의 수용량을 계산하여 설계했다.  그런데 예상치 못한 인기에 B라는 웹애플리케이션을 또 하나 배치하여 분산(이런 기술을 로드밸런서라고 한다)을 시키기로 하였다.

로드밸런서란 여러명의 이용자가 하나의 서버에 접속을 하여 서비스에 지장을 주는 것을 방지하기 위한 기술로 일정한 수용량이 되면 로드밸런서가 일부 사용자를 다른 서버로 이동시켜서 서버에 부하를 방지하는 기술이다.

 

 여기까지는 크게 문제가 없다. 로드밸런서로 서버의 부하도 막고 아무런 문제가 없어보인다. 진짜 문제는 여기서부터인데 A와 B는 같은 웹애플리케이션을 실행시키지만 결론적으로만 생각해보면 A와 B는 다른 서버이기 때문에 둘은 세션 ID값이 다를 수 밖에 없다. 그래서 A라는 곳에서 놀다가 B라는 곳으로 이동을 하게되면 다른 ID값이기 때문에 다시 인증을 해야하는 경우가 온다.

물론 세션 ID값을 공유하거나 다루는 서버를 만들고 A와 B를 연결하는 방법등도 존재한다고 한다.. 여기서는 다루지 않는다.

그래서 사람들은 인증방식의 정보를 세션이 아닌 사용자에게 주면 해결이 되는게 아닌가?에서 나온 방법이 바로 JWT이다.

구조는 HeaderPayloadSignature 이렇게 3개로 구성이 되어있다.

우선 HEADER 부분을 보면 "alg": "HS256"이 부분이 눈에 띈다. 여기서 HS256은 JWT의 암호화방식은 HMAC(HS256 등), RSA, ESDSA가 있다. 그리고 "typ": "JWT"로 JWT임을 증명한다.

 

그 다음은 PAYLOAD는 사용자와 서버 간 주고 받기로 한 데이터들로 구성이 되어있다. PAYLOAD에 있는 속성들은 클레임 셋(Claim Set)이라고 부른다.

 

마지막으로 SIGNATURE는 위의 HEADER와 PAYLOAD의 값들을 "alg"에 정의된 방식으로 암호화하고 Base64로 인코딩을 한다. 그리고 위의 사진에 Encoded부분을 보면 .(점)으로 HEADER, PAYLOAD, SIGNATURE를 합치면 마침내 JWT가 완성이 되는것이다.

 

JWT 공식 페이지 : JSON Web Tokens - jwt.io

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

+ Recent posts