출처: http://theeye.pe.kr/entry/serializable-warning%EC%97%90-%EB%8C%80%ED%95%B4

이클립스에서 열심히 작업을 하다 보면 보는 경고가 있다.

JDK 5.x대에서 새롭게 추가된 점인듯 하다.

The serializable class XXX does not declare a static final serialVersionUID field of type long

이 문제를 해결하기 위해 찾아보던중 다음과 같은 내용을 발견하였다.

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.


사실 무슨 말인지 정확히 모르겠지만, serializable class를 사용할 경우 serialVersionUID 를 등록하여야 한다는 말인듯 하다.

보안적인 측면에서인듯 하다.

static final long serialVersionUID = 42L;

를 클래스안에 추가해 주면 된다.
Posted by Jake Kim
원 출처: http://pmguda.com/208
출처: http://helloboy.tistory.com/entry/%EC%9D%B4%ED%81%B4%EB%A6%BD%EC%8A%A4-Web-Tools-WTP-%EC%82%AC%EC%9A%A9%EB%B2%95



1. WTP 구하기
http://www.eclipse.org/webtools/

2. WTP 선택
최신 jdk를 사용하다면 1번에 나온 download페이지를 이용하면 될것이고
만약 jdk1.4를 이용한다면 구버전이 들어있는 download를 이용하면 된다.

사용자 삽입 이미지

WTP 다운로드 페이지


압축만 풀면 바로 eclipse에 WTP가 적용된  wtp-all-in-one 파일을 다운로드 받아서 사용하길 권장한다. 아니면 수동으로 WTP가 필요한 기타등등의 plugin 파일을 설치해야된다.

3. WTP 기능 활용하기.
글쓴이는 dynamic web project만 사용한다. 나머지도 많은데 차차알게되면 써볼것이다.
준비물: jdk 1.4.x
           tomcat 5.5(1.4버전 사용가능한것)
           wtp-all-in-one-sdk-R-1.5.5-200708291442-win32.zip

이클립스 실행
메뉴에서
file -> new -> project -> web -> dynamic web project -> NEXT 클릭
-> Project Name을 넣고 -> New 버튼 클릭
사용자 삽입 이미지

- 톰켓서버 잡아주기.
Apache 트리를 열어 5.5 버전을 선택한다. Next 클릭
사용자 삽입 이미지

톰켓서버 잡아주기


- 톰켓이 설치된 경로를 잡아주고, JRE 선택.
본인이 원하는 jre 선택한다. 1.4대를 사용하고자 하니 default말고 명확하게 1.4버전을 선택하자.
사용자 삽입 이미지

톰켓경로설정, JRE선택


그리고 Finish 클릭 -> Finish 또 클릭 하면 J2EE Perspective 화면 이동 하겠냐고 물어보는 NO를 하고 Java Perspective 화면을 이용한다.

사용자 삽입 이미지

Dynamic Web Project 완성

왼쪽에보면 JRE도 보이고 톰켓 관련 라이브러들도 연결된게 보일것이다.
EAR, Web App Libraries는 아무것도 들어있지않다. 자세한 사항은 J2EE 공부를해야할꺼 같다.
src 폴더는 java 파일이 위치하고 build폴더에 class들이 쌓인다.
WebContents 폴더는 jsp 파일이 위치할 것이다.
WebContents 폴더에 우클릭 -> New -> Other -> Web -> JSP 파일을 선택 Next
file name을  적고 finish 클릭.
<body></body> 테그 사이에 Hello World! 적고 저장한다.

그럼 이제 실행을 해보자 톰켓을 이용해 jsp를 브라우저에서 봐야된다.
메뉴 -> Run -> Run on Server 클릭.
톰켓 5.5환경으로 세팅이 되었는지 확인하고 Next 클릭.

사용자 삽입 이미지

Run on Server


아래 마지막으로 우측에 프로젝트가 존재하는지 확인하고 Finish 클릭.
사용자 삽입 이미지

그럼 브라우저에 Hello World! 가 나타나는것을 확인할 수 있다.
eclipse 안에서 브라우저가 나타날땐 메뉴 -> Windows -> Web Browser -> Default System Web Browser 를 선택하면 된다.
사용자 삽입 이미지


* 디버그 활용하기 *
System.out.println(); 으로 디버깅도 하지만 더 편하게 할 수 있는 방법이 있다.
Run on Server 말고 Debug on Server를 이용하는것이다.

먼저 간단한 debug를 위해 사전에 준비해야 할 작업이 있다. 아래 그림처림
1. test 페키지를 생성하고 첨부된 TEST.java 파일을 넣는다.
2. WebContent 밑에 첨부된 debug.jsp 파일을 넣는다.
사용자 삽입 이미지

debug 연습



3. BreakPoint 찍기
프로그램은 간단하다 10번 카운트 세면서 10번째에 발사! 하는 프로그램이다.
값이 어떻게 변화하는지 debug 를 이용해서 추적할 수 있다면 기초적인 디버그는 완료.
참고로 jsp debug는 톰켓 5.x 이상부터 지원된다고 한다. 4.1 대로 jsp debug를 시도했으나 실패하고 5.5를 설치하고 나서 jsp 디버깅에 성공하였다. (JSP 디버깅은 5.5를 이용하자)

본격적으로 디버깅을 해보자.
디버깅을 하는 이유는 우리가 원하는 값을 변수가 제대로 가지고 있는지 맞게 변화하는지 예외는 어떤 시점에서 발생하는지에 대한 수정을 좀더 쉽고 빠르게 접근하기 위함이다.

다음은 cnt 값의 변화를 살펴보기 위해 BreakPoint를 찍는 화면이다. 찍는 방법은 화면에 표시된 위치 즉 cnt += 1; 구문이 있는 라인에 빨간박스 안을 더블 클릭 하는 방법이다. 그럼 포인트가 찍히게 된다.
사용자 삽입 이미지

BreakPoint


다음은 서버를 디버그 모드로 실행 시키는 것이다.
메뉴 -> Run -> Debug As -> Debug on Server 클릭.
서브창에서 Finish 클릭. 브라우저가 실행되며 이클립스에서 디버그 모드 전환을 물어보는 메시지 박스가 나타나며 Ok 눌러서 디버그 모드로 전환한다.
사용자 삽입 이미지

디버그 모드 전환


화면 우측 상단에 Variables 텝을 보면 cnt 값이 0으로 들어있는게 확인이된다.
하단의 jsp 에디터에는 아까 찍어놓은 BreakPoint에 화살표가 되어있는게 보인다.
마지막으로 브라우저를 살펴보면 연결중 상태로 응답을 기다리는 상태가된다.

위의 화면에서 F6 키를 눌러보도록 하자 그럼 jsp 에디터에서 화살표가 아래로 한줄 내려온다. 그리고 Variables 탭을 살펴보면 값이 1증가되어 Value는 1이 되어 있는게 확인된다.

cnt 값이 10 될때까지 F6을 여러번 눌러면서 cnt 값의 변화와 jsp 에디터에서 화살표의 이동을 살펴보도록 하자. 아래와 같은 화면이 나오면 jsp페이지에서 처리해야할 작업들은 완료되고 서버로 브라우저에서 오는 요청에 대한 응답을 하기위한 작업이라 보면되겠다.
화면 상단의 Resume 버튼을 눌러 프로세스를 진행시킨다.
사용자 삽입 이미지
마지막으로 브라우저를 살펴보면 세상아 안녕! 이란 글자가 나타날 것이다.

지금까지 디버깅의 가장 기초적인 기능을 해봤다고 생각한다. 다른 기능들은 여기저기 BreakPoint를 찍어가며 (java 소스에도 물론) 값이 어떻게 변화하는지 확인해보기 바란다.
Posted by Jake Kim

거두절미 하고 자바스크립트에서도 this라는 키워드가 있다. 보통 this라고 하면 자신 내부의 변수를 참조 한다는 의미이다.

즉,

class test
{
int a = 100;
public void test(int a)
{
출력(a) -> 10
출력(this.a) -> 100
}
test(10);
}

이처럼 변수로 넘어온 값과 내부 변수의 이름이 같을 경우 this를 사용하여 구분한다.

그렇다면 자바스크립트에서의 this란 무엇일까?

<script>
var a=100;
function test(a)
{
alert(a) -> 10
alert(this.a) -> 100
}
test(10);
</script>

여기까지는 일반적인 프로그래밍과 동일하다. 그렇다면 html 페이지 안에서 계속 자바스크립트로 프로그래밍을 한다고 치자... 다음과 같은 자바스크립트 함수가 있을때 나오는 값을 생각해보자...

<script>
var a=100;
function test(a)
{
alert(a) 문제1
alert(this.a) 문제2
}
test(10);
</script>
html.....코딩
<script>
a = 김도진
function fun1()
{
alert(a) 문제3
alert(this.a) 문제4
}
test(10);
fun1();
</script>
html 코딩....
<script>
a = 150
function fun2()
{
alert(a) 문제5
}
</script>
<script>
function test(10)
function fun1()
function fun2()
</script>

문제1: 10
문제2: 150

문제3:150
문제4:150

문제5:150

왜 이런 값이 나오는지 이해가 가는가???

자바스크립트의 this는 자신이 속한곳의 변수를 참조한다. 하지만 위 와 같이 변수 a가 계속 선언된다면 결국 함수를 호출 하는 마지막 변수의 값을 사용하게 된다.
 


아래 내용은 this에 관해 설명이 잘나온곳이 있어 참고삼아 올린다.
url: http://www.quirksmode.org/js/this.html

The This Keyword

One of the most powerful JavaScript keywords is this. Unfortunately it is hard to use if you don't exactly know how it works.

Below I explain how to use it in event handling. Later on I'll add some information about other uses of this.

Owner

The question that we'll discuss for the remainder of the page is: What does this refer to in the function doSomething()?

function doSomething() {
   this.style.color = '#cc0000';
}

In JavaScript this always refers to the “owner” of the function we're executing, or rather, to the object that a function is a method of. When we define our faithful function doSomething() in a page, its owner is the page, or rather, the window object (or global object) of JavaScript. An onclick property, though, is owned by the HTML element it belongs to.

This "ownership" is the result of JavaScript's object oriented approach. See the Objects as associative arrays page for some more information.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------

If we execute doSomething() without any more preparation the this keyword refers to the window and the function tries to change the style.color of the window. Since the window doesn't have a style object the function fails miserably and produces JavaScript errors.

Copying

So if we want to use this to its full extent we have to take care that the function that uses it is "owned" by the correct HTML element. In other words, we have to copy the function to our onclick property. Traditional event registration takes care of it.

element.onclick = doSomething;

The function is copied in its entirety to the onclick property (which now becomes a method). So if the event handler is executed this refers to the HTML element and its color is changed.

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

The trick is of course that we can copy the function to several event handlers. Each time this will refer to the correct HTML element:

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------          |            |
|                                           |            |
|   -----------------------                 |            |
|   | another HTML element| <-- this        |            |
|   -----------------------     |           |            |
|               |               |           |            |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

Thus you use this to the fullest extent. Each time the function is called, this refers to the HTML element that is currently handling the event, the HTML element that "owns" the copy of doSomething().

Referring

However, if you use inline event registration

<element onclick="doSomething()">

you do not copy the function! Instead, you refer to it, and the difference is crucial. The onclick property does not contain the actual function, but merely a function call:

doSomething();

So it says “Go to doSomething() and execute it.” When we arrive at doSomething() the this keyword once again refers to the global window object and the function returns error messages.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------

The difference

If you want to use this for accessing the HTML element that is handling the event, you must make sure that the this keyword is actually written into the onclick property. Only in that case does it refer to the HTML element the event handler is registered to. So if you do

element.onclick = doSomething;
alert(element.onclick)

you get

function doSomething()
{
	this.style.color = '#cc0000';
}

As you can see, the this keyword is present in the onclick method. Therefore it refers to the HTML element.

But if you do

<element onclick="doSomething()">
alert(element.onclick)

you get

function onclick()
{
	doSomething()
}

This is merely a reference to function doSomething(). The this keyword is not present in the onclick method so it doesn't refer to the HTML element.

Examples - copying

this is written into the onclick method in the following cases:

element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">

Examples - referring

In the following cases this refers to the window:

element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">

Note the presence of attachEvent(). The main drawback of the Microsoft event registration model is that attachEvent() creates a reference to the function and does not copy it. Therefore it is sometimes impossible to know which HTML currently handles the event.

Combination

When using inline event registration you can also send this to the function so that you can still use it:

<element onclick="doSomething(this)">

function doSomething(obj) {
	// this is present in the event handler and is sent to the function
	// obj now refers to the HTML element, so we can do
	obj.style.color = '#cc0000';
}
Posted by Jake Kim

XMLHttpRequest Object


이번에는 웹 서버와 통신하는데 핵심 기능을 제공하는 XMLHttpRequest 객체를 사용하는 방법에 대해 알아보고,
해당 속성들을 이용하여 실제로 사용할 수 있는 예제를 만들어 보자.

XMLHttpRequest 프로그래밍 순서


XMLHttpRequest를 사용한 Ajax 프로그램은 다음과 같이 세 과정을 거치게 된다.
1. XMLHttpRequest 객체 생성
2. 웹 서버에 요청 전송하기
3. 웹 서버에서 응답이 도착하면 화면에 반영하기

위의 과정에 맞게 차례대로 살펴보자.

1) XMLHttpRequest 객체 생성


XMLHttpRequest 객체를 생성하는 방식은 브라우저마다 서로 다르다.
따라서 크로스 브라우징을 위한 코드를 작성하게 되면 아래와 같다.
var req;

if(window.XMLHttpRequest){                          // IE 이외에서  XMLHttpRequest 생성
	req = new XMLHttpRequest();
}else if(window.ActiveXObject){                     // IE에서  XMLHttpRequest 생성
	req = new ActiveXObject("Microsoft.XMLHTTP");
}



2) 웹 서버에 요청 전송하기


XMLHttpRequest 객체를 생성한 다음에는 생성한 XMLHttpRequest 객체를 사용해서 웹 서버에 요청을 전송할 수 있따.
웹 서버에 요청을 전송할 때 사용되는 함수는 다음과 같다.

•open() 함수 : 요청의 초기화. GET/POST 선택. 접속할 URL 입력
•send() 함수 : 웹 서버에 요청 전송

위의 두 함수를 이용하는 방식은 아래와 같다.
req.open("GET", "/test.txt", true);
req.send(null);


open() 함수는 세 개의 인자를 입력받는데, 다음과 같은 의미를 가지고 있다.
1번 인자는 HTTP 메소더를 지정한다.대개 "GET", "POST" 등을 사용한다. 이외에 서버에서 지원하는 HTTP 메서드인 PUT, DELETE,
HEAD 등이 되기도 한다.
2번 인자는 접속할 URL을 입력한다. 보안상 이유로 접속할 URL은 현재 페이지와 같은 도메인에 있어야 한다.
3번 인자는 동기/비동기 방식을 지정한다. 이 값이 'true'일 경우, 이 상태에서는 요청이 처리되는 도중에 사용자가 다른 작업을
할 수 있다. 반대로 'false'이면 요청은 동기적으로 처리되어서 요청이 종료될 때까지 사용자는 차단될 것이다.


3) 서버 응답 처리하기


open()함수와 send()함수를 사용하여 웹 서버에 데이터를 전송한 다음에 할 작업은 서버로부터 응답이 도착하면 알맞게 처리하는 것이다.
XMLHttpRequest 객체의 속성 중 하나인 onreadystatechange는 응답이 도착하면 특정 자바스크립트 함수를 호출하게 한다.

하지만 우선 이를 처리하기 전에 요청한 응답이 XMLHttpRequest객체에 전달 될 때까지의 상태를 나타낸 readyState에 알아보자.
각 상태에 따라 readyState 속성의 값이 아래와 같게 된다.
의미 설  명
0  UNINITIALIZED  객체만 생성되고 아직 초기화되지 않은 상태
1  LOADING  open 메서드가 호출되고 아직 send 메서드가 불리지 않은 상태
2  LOADED  send 메소드가 불렸지만 status와 해더는 도착하지 않은 상태
3  INTERACTIVE  데이터의 일부를 받은 상태
4  COMPLETED  데이터를 전부 받은 상태. 완전한 데이터의 이용 가능


이렇듯 상태에 맞는 작업을 아래의 코드처럼 사용하여 처리하는 것이 가능해진다.
function callback(){
     if(req.readyState == 1 || req.readyState == 2 || req.readyState == 3){
          // 화면에 서버에서 작업 중이라는 메시지 출력
     }else if(req.readyState == 4){
          // 서버에서 완전한 응답이 도착한 경우
          // 응답 결과에 따라 알맞은 작업 처리
     }
}


XMLHttpRequest 객체의 또 다른 속성인 status는 웹 서버에서 전달한 상태코드를 저장하게 된다.
status 속성에 저장되는 주요 상태 코드는 아래와 같다.
텍스트 설  명
200  OK  요청 성공
403  Forbidden  접근 거부
404  Not Found  페이지 없음
500  Internal Server Error  서버 오류 발생


따라서 서버로부터 응답이 도착하면 status 속성을 사용해서 요청이 성공적으로 수행되었는지 확인해야 한다.
다음과 같이 콜백 함수를 작성하는 것이 좋을 것이다.
function callback(){
     if(req.readyState == 4){
     	if(req.status == 200){
     	     // 정상적으로 수행하는 부분
     	}else{
     	     alert("문제 발생:"+req.statusText);
     	}
     }
}


마지막으로 responseText 속성에 대해 알아보자.
웹 서버로부터 정상적으로 요청이 들어오게 될 경우 웹 서브는 단순 텍스트 또는 XML의 두가지 형식으로 데이터를 전송하게 된다.
이 중 단순 텍스트로 응답이 왔을 때 사용하는 예제는 다음과 같다.
function callback(){
     if(req.readyState == 4){
     	if(req.status == 200){
     	     var txt = req.responseText;
     	     // txt 변수에 응답 데이터가 저장된다.
     	}
     }
}


이를 바탕으로 예제를 하나 살펴보자. 바로가기 소스보기


소스보기
exam.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<script type="text/javascript" src="exam.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
<body>
입력창에 입력 후 '확인'버튼을 누르시면 글이 바뀌게 됩니다.
<a href="source.html" target="_blank">소스보기</a> 
<br/><br/>
<div id="head">Hello, Guest!</div>
<input id="name" type="text" value="이름을 입력하시오." onkeyup="change()"/>
</body>
</html>

exam.js
var req;

// input에 문장을 넣었을 때 정답을 확인하기 위한 XHR 객체 생성
function change(){
     var name = document.getElementById('name').value;
     var url = "exam.jsp?name=" + name;
     if(window.XMLHttpRequest){
          req = new XMLHttpRequest();
     }else if(window.ActiveXObject){
          req = new ActiveXObject("Microsoft.XMLHTTP");
     }
     req.open("Get",url,true);
     req.onreadystatechange = callback;
     req.send("");
}
// callback 함수
function callback(){
     if(req.readyState == 4){
          if(req.status == 200){
               var txt = req.responseText;
               document.getElementById('head').innerHTML = txt;
          }
     }
}

exam.jsp
<%@ page contentType="text/plain; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%
     String name = request.getParameter("name");
     String a = new String(name.getBytes("ISO-8859-1"),"euc-kr");
     out.print("Hello," + a + "!");
%>


출처: http://compstat.chonbuk.ac.kr/JavaScript/
Posted by Jake Kim

이클립스를 사용해서 개발을 하는 것은 기존 텍스트 에디터를 이용해서 작업하는 것과 많은 차이를 갖고 있다. 특히 웹 애플리케이션 개발에서는 더 많은 차이가 있게 되는데, 우선 언급해 볼 것이 서비스에 구성된 디렉토리와 개발에 사용되는 디렉토리의 차이점이다.

웹 애플리케이션은 서블릿 스펙에 따라서 디렉토리가 정해진 규칙을 갖고 있다.

/WEB-INF/ 브라우저를 통해서 접근이 불가능한 웹 애플리케이션 핵심정보들을 포함하고 있는 디렉토리
/WEB-INF/classes/ 패키지에 따른 디렉토리별 class파일과 properties 파일이 위치하는 곳
/WEB-INF/lib/ 웹 애플리케이션에서 사용되는 jar 파일이 존재하는 곳
/META-INF/context.xml 톰캣에서 사용되는 manager를 통한 배포용 웹 애플리케이션 Context정보 파일
브라우저를 통해서 접근 가능한 리소스들은 그 외의 디렉토리에 놓으면 된다.
특히 브라우저의 JVM 위에서 돌아가는 애플릿 class와 관련 jar 들은 /WEB-INF/ 밖에 위치해야 한다.
이 디렉토리들을 묶어서 Context 라고 얘기한다.

서비스와 관련된 디렉토리 구조가 위와 같고, 개발용 디렉토리 구조는 java 파일이라는 특징 때문에 다음과 같이 구성한다.

/src 패키지에 따른 디렉토리별 java 파일과 properties 파일이 존재하는 곳
/WebContent/ 앞에 언급한 브라우저를 통해서 접근 가능한 리소스들. 웹 애플리케이션의 컨텍스트 루트 디렉토리에 해당.
/WebContent/WEB-INF/ 앞에 언급했던 /WEB-INF/ 디렉토리와 같은 성격
/build/classes  /src 하위 자바파일의 컴파일된 class 들이 놓이는 곳. properties 파일은 자동 복사되는 곳.


개발 디렉토리와 WAS의 서비스되는 디렉토리의 매핑 즉 자연스런 연결은 빌드 툴인 ant를 통하거나 Eclipse같은 IDE에서 자동으로 해준다.

이클립스의 경우 Servers 라는 프로젝트가 웹 프로젝트와 별개로 생성이 된다. 여기에서 설정되는 서버의 세팅은 기본적으로 설치된 세팅과 별도로 운영된다. 즉 톰캣이 설치된 디렉토리의 conf 에 있는 설정과는 별개로 Servers하위의 서버별 server.xml 의 파일에 설정된 내용으로 동작이 된다는 뜻이다.
<%= request.getRealPath("/") %> 를 통해서 확인해 보면 이클립스에서 운영하는 디렉토리가 완전히 엉뚱한 곳에 존재함을 알 수 있다. 웹 프로젝트에서 파일을 변경하면 자동으로 파일이 해당 위치로 복사된다.

Posted by Jake Kim


Interface 라는 게 OOP에서 가장 중요한 개념인 class를 추상화 한 것이라 더욱 개념잡기가 힘듭니다.

일반적으로 interface라는 용어는 "상이한 시스템간의 계약 정보를 표현하는 것" 이라고 정의할 수 있습니다.

 
C#의 예약어이면서, OOP의 기본개념으로 자리잡고 있는 Interface는 형태상으로 몇 가지 특징이 있습니다.

 
1. 선언(Declaration)은 있고, 정의(Definition)은 없다. (Abstract class도 같은 의미)

2. 접근자는 쓸 수 없고, 모두 public 이다. (계약사항이 투명해야 하고, 명확해야 하므로)

3. 다중 상속이 가능하다.

 
특징은 더 있겠지만... 생각나는 게 이 정도이고...

 
Interface를 사용해야 하는 이유에 대해서 몇 가지 서술해보자.

 
1.        외부 시스템에 제공할 서비스 또는 객체 정보를 직접적인 class가 아닌 "선언" 만을 제공한다.

2.       다중 상속에 따른 class의 표현을 여러 가지로 가능케 한다.

3.        의도하지 않은 속성/메소드 공개를 막기 위해

4.       실제 object 의 class 정보를 제공하고 싶지 않을 때 ( 또는 명확히 하고 싶을 때)

5.        OOP의 상속에 억매이지 않고, 구현할 수 있도록 개방성을 제공할 때...

                                                                                 

 
Interface 설계시의 주의점.
 
1. 속성, 메소드의 변화가능성이 많다면, 아예 사용하지 마라.
 
interface에 변경이 일어난다면, 아주 위험한 상황이 올 수 있다. (OOP와 마찮가지로) 계약이 변경된다는 뜻은, 모든 구현이 변경되어야 함을 뜻하고, 이는 전체적인 Class 의 상속 체계에 위험을 줄 수 있다.

즉 Interface라는 것이 OOP의 Abstract Class와 같이 상속(엄밀히 구현)의 원형이 되는 것이므로,       원형이 변경되면 자손들도 변경이 일어나야 한다는 뜻인데, interface의 경우, 전혀 다른 제품으로의 확장도 지원할 수 있으므로, Interface 설계 시 아주 조심해야 한다.

 
2. 너무 많은 속성, 메소드를 노출시키지 마라 (5개 이하) - 인터페이스의 성격이 명확해야 한다.
 
    너무 많은 정의가 있다는 것은, 계약이 다른 뜻으로 해석될 수도 있고, 명확한 의미를 이해하거나, 구현하는 데 방해가 될 수 있다. 보통의 경우는 5개 이하로 하고, 더 많아질 경우에는 Interface 상속으로 해결해야 한다.

                 

                  예:

                 

                  public interface IVertex
                  {
                                   Guid Id {get;set;}
                                   IList InLinks { get; }
                                   IList OutLinks { get; }
                  }
                 
                  public interface INamedVertex : IVertex
                  {
                                   string Name { get; set;}
                  }
 
3. Interface의 name은 xxx-able, xxx-er, xxx-tion 등 실제 복합 기능을 하는 class와는 달리 단품의 성격을 나타내도록 한다.
 
   Interface 명명시에는 몇가지 방식이 있는데, Interface가 표현하고자 하는 것에 따라 몇가지 형태로 사용할 수 있다.

  

   -able (예: ISerializable, ICloneable 등) 동작할 수 있는 메소드가 있음을 나타낸다.

   -er    (예 : ISerializer, IComposer, ICompressor, IFormatter, IStringProvider 등) 동작 자체에 의미가 있는 경우

   -tion 또는 Class 원형 이름 (예: IUserType, IGraph, IProcess 등) 객체의 가장 추상화 단계를 표현하는 Interface

  

  

인터페이스를 정의한 경우, 인터페이스를 구현하는 방식에는 크게 2가지로 나뉜다.

 
1.        인터페이스를 직접 구현

2.       클래스는 보통 Abstract class로 기본 동작을 표현하고, Abstract class를 상속 받아, Concrete class를 구현을 하는 방식

 
 
직접 구현하는 방식에는 ICompressor <- GZipCompressor, DeflateCompressor, SevenZipCompressor 등과 같이 Algorithm 자체가 상이하고, 추상화할 정보가 없을 경우이다.

이 방식은 Abstract class에 의한 상속의 사슬에 얽매이지 않기 때문에, 외부 개발자가 제공되는 Interface로 다양한 구현이 가능토록 한다.

 
Abstract class를 정의한 후, Concrete class로 상속하는 경우는 폐쇄적인 방식으로 유용하다. 즉 외부에는 interface로 노출하여 다양한 구현이 가능토록 제공은 하지만,

내부에서는 OOP 상속 및 다형성을  계속 가져가겠다는 의도인 것이다.

 
보통의 경우 2번이 1번의 모든 경우를 포함하기 때문에 2번 방식이 주를 이룬다. 패턴으로 말한다면 Abstract Factory Pattern이 2번 방식을 사용한다고 보면 된다.

 
마지막으로 인터페이스를 구현하지 않고, OOP 기능만을 이용하여 Abstract class, Concrete class 상속 체계만 정의하여 쓰는 경우가 있는데,

이는 인터페이스가 없으므로 Abstract class가 외부에 노출 시켜서 사용할 수 있다. 다만, 문제는 C#, Java의 경우 다중상속이 허용되지 않기 때문에,

다양한 Interface 다중상속 (결합) 또는 분리로 표현하고자 한다면, 문제가 될 수 있다.

 
 
다음번 글에서는 RCL, RealAdmin에서 사용한 Interface를 가지고, 실전에서 사용하는 방식을 설명하겠습니다.


원본 글: http://debop.blogspot.com/2009/06/interface-part-1.html

Posted by Jake Kim

VB.NET과 C#소스를 서로 변환시켜주는 사이트가 있네요.

http://www.developerfusion.com/tools/convert/vb-to-csharp/

오픈소스 프로젝트인 #develop editor(Visual Studio를 대체할 수 있는 IDE)의 소스 코드를 기반으로 만들었답니다.

Posted by Jake Kim