Clean Code that Works.

jqGrid의 gridData 들을 JSON 형식으로 서버에 전달해야 하는데..
이게 좀 햇갈려서 -.,-

스프링 팀 블로그 보기

위 블로그를 보면 $.postJSON이라는 함수를 써서 submit 하는데,
jQuery에는 이게 없으니깐, 이것을 구현한게 있나 구글링 해 보니.
postJSON 보기
이렇게 해주더라..

$.postJSON = function (url, data, callback) {
$.ajax({
'url': url,
'type': 'post',
'processData': false,
'data': JSON.stringify(data),
contentType: 'application/json',
success: callback,
});
};

삽질 중에 contentType을 'application/json'으로 주는것 까지는 생각했었는데, data를 json으로 바꿔줘야하는것은 생각을 못했다. json 형식으로 직접 만들어 줘도 안되길래..
음 뭐 내가 잘못 생각 한건가.. -,.-;;

아무튼 jqGrid data 가지고 excelView 만들어 주는 작업 계속 진행 중.


네이버 지도 OPEN API 사용하는데...
위치 검색 해서 좌표 구하는 부분에서.. 네이버에서는 XML을 리턴한다.

그러므로.. 크로스 도메인 문제로 jQuery로는 사용이 불가 하다.(JSON으로 리턴해주면 되는데!!!!)
하여 서버사이드에서 처리를 해 줘야 한다.

서버에서 URL 로 콜 해서 데이터들을 가져온 다음..
(이걸 XML로 변환한 다음에 JSON으로 변환해야 될줄 알았는데 그냥 데이터(XML 형식의 TEXT)를 JSON으로 변환 시켜도 된다)

그럼 이런 결과가 찍힌다.
<?xml version="1.0" encoding="euc-kr" ?><geocode xmlns="naver:openapi"><userquery><![CDATA[경기도성남시정자1동25-1]]></userquery><total>1</total><item><point><x>321063</x><y>529727</y></point><address>경기도 성남시 분당구 정자1동 25-1</address><addrdetail><sido><![CDATA[경기도]]><sigugun><![CDATA[성남시 분당구]]><dongmyun><![CDATA[정자1동]]><rest><![CDATA[25-1]]></rest></dongmyun></sigugun></sido></addrdetail></item></geocode>

이것을 JSON으로 변경 해야 하는데
이미 공개된 API들이 있으므로 그것을 사용하자. ㅋ

org.json(maven) 과 net.sf.json

org.json의 경우 XML이라는 클래스에 toJSONObject() 메서드를 제공 한다. 하여 결과를 찍어 보면,
깔끔한 JSON 코드가 나온다.
{"geocode":{"total":1,"userquery":"경기도성남시정자1동25-1","item":{"point":{"y":529727,"x":321063},"address":"경기도 성남시 분당구 정자1동 25-1","addrdetail":{"sido":{"sigugun":{"content":"성남시 분당구","dongmyun":{"content":"정자1동","rest":"25-1"}},"content":"경기도"}}},"xmlns":"naver:openapi"}}


net.sf.json 에서는 XOM이라는 jar 파일이 필요하다.
XMLSerializer에서 의존하고 있는것이 있다.
하여 실행을 해 보면 아래와 같이 표시된다.
{"geocode":{"total":1,"userquery":"경기도성남시정자1동25-1","item":{"point":{"y":529727,"x":321063},"address":"경기도 성남시 분당구 정자1동 25-1","addrdetail":{"sido":{"sigugun":{"content":"성남시 분당구","dongmyun":{"content":"정자1동","rest":"25-1"}},"content":"경기도"}}},"xmlns":"naver:openapi"}}
{"@xmlns":"naver:openapi","userquery":"경기도성남시정자1동25-1","total":"1","item":{"point":{"x":"321063","y":"529727"},"address":"경기도 성남시 분당구 정자1동 25-1","addrdetail":{"sido":{"#text":"경기도","sigugun":{"#text":"성남시 분당구","dongmyun":{"#text":"정자1동","rest":"25-1"}}}}}}

약간 틀리다.
org.json에서는 text 값들을 content로
net.sf.json은 #text로 표시해준다.

왼지 org.json이 깨끗해 보이긴 하나.. 이미 net.sf.json을 사용중이므로..
아래것으로 해야겠다.

테스트 코드는 아래 것.

@Test
    public void getXmlData() {
        URL naverUrl;
        StringBuffer sb = new StringBuffer();
        try {
            naverUrl = new URL(
                    "http://map.naver.com/api/geocode.php?key=키입력&query=경기도성남시정자1동25-1");
           
            BufferedReader in = new BufferedReader(new InputStreamReader( naverUrl.openStream()));
            String inputLine;

            while ((inputLine = in.readLine()) != null)
                sb.append( inputLine.trim());
           
            in.close();
           
            System.out.println( sb.toString());
           
            org.json.JSONObject jsonObj = XML.toJSONObject( sb.toString());
            System.out.println(jsonObj);
            JSONObject obj = (JSONObject) new XMLSerializer().read( sb.toString());
            System.out.println( obj);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }





see this site 
http://www.queness.com/post/212/10-jquery-and-non-jquery-javascript-rich-text-editors


10가지 jQuery와 jQuery가 아닌 자바스크립트 rich text editor.
간단한 게시판이나 방명록에 활용해도 좋다.

오랜만에 jQuery 사이트에 들어가보니 1.4버전의 출시가 임박했다고 한다.
1.4버전에 맞추어 14일 단위로 1.4버전에 관한 내용을 설명하는 컬럼이 게시되고 있는 중.

몇가지 메서드가 추가되고, 변경 되었다고 한다.

전체 용량도 약간 상승 하였다.

성능 향상을 위하여 자주 쓰이는 메서드들을 점검(Overhaul) 했다고 한다.

메서드 성능

차트만 보면 엄청난 성능 향상.



사이트 가기 ( http://jquery14.com/)

동영상 강좌도 올라왔으니 보면 좋을듯. 




첨부파일은 안올라가서 집에가서 올려야징

이번에는 간단히 미투데이 오픈 API를 이용하여
자신의 글 목록 및 댓글 목록을 가져오고,
글을 작성 하는 방법을 알아 보도록 하겠습니다.
 
    ※ 미투데이(http://me2day.net/)란? 트위터와 같은 국산 마이크로 블로그(150자 제한)
 
미투데이 인증 방식은 두 가지 방식이 있습니다.(바뀔수도 있어요)
1. 비밀키 조합을 통한 인증 방식(파라미터를 통한 인증 방식)
2. HTTP Basic Authentication(플리커에서 이 방식을 통해 인증하고 사진을 올릴 수 있습니다 - 업로드시만 적용)
 
이 중에서 비밀키 조합을 통한 인증 방식을 사용해서 미투데이에 게시글을 등록해 보도록 하겠습니다.
 
    ※ 미투데이 API(http://codian.springnote.com/pages/86001)
 
비밀키(ukey) 생성 방법
 - nonce + md5(nonce + user_key)
여기서 nonce는 8자리 임시 알파벳을 지정 하면 됩니다.
이를 md5인코딩을 위와 같은 방법으로 해서 ukey를 생성합니다.
 
플러그인에는 고정 값으로 nonce를 생성하도록 되어있고, md5 인코딩은 http://pajhome.org.uk/crypt/md5/ 에서 하였습니다. md5인코딩을 플러그인 내에서 하고 싶으면 라이브러리를 추가하여 플러그인 내에서 md5인코딩을 수행 하시면 됩니다.
user_key는 me2API 사용자 키 입니다. 미투데이 회원 가입 하시면 자동으로 발급이 됩니다.
 
이를 조합하여 ukey를 생성합니다.
 
me2API 애플리케이션 키(akey)는 미투데이 회원 가입 후 발급 요청을 하면 발급 받을 수 있습니다.
이렇게 ukey와 akey를 생성 후 이를 파라미터로 날려주면 인증이 필요한 API 메서드를 사용 할 수 있습니다.
 
    ※ 테스트 URL : http://me2day.net/api/noop?uid=codian&ukey=XXXXXXXXXXXXXXXX&akey=XXXXXXXXXXXXXXXX
 
이제 미투데이에서 제공 하는 API에 대해서 알아 보겠습니다.
  • create_post : 지정한 회원의 미투데이 페이지에 글을 작성합니다.   
  • get_latests : 지정한 회원의 최근글을 가져옵니다.
  • get_posts: 지정한 회원의 글을 가져옵니다.
  • create_comment : 지정한 글에 댓글을 작성합니다.
  • delete_comment: 지정한 댓글을 삭제합니다.
  • get_comments : 지정한 글의 댓글을 가져옵니다.
  • track_comments: 회원이 최근 작성한, 회원의 미투페이지에 최근 작성된 댓글을 가져옵니다.
  • get_person : 지정한 회원 정보를 가져옵니다.
  • get_friends : 지정한 회원의 친구목록을 가져옵니다.
  • get_settings : 개인 설정 사항을 가져옵니다.
  • get_tags:  태그와 태그를 포함하는 글 수를 가져옵니다.
  • noop : 사용자인증 테스트를 하거나 서버 동작상태를 검사합니다.
  • get_friendship_requests : 지정한 회원에게 요청된 친구신청 내역을 가져옵니다.
  • accept_friendship_request : 지정한 회원에게 요청된 친구신청을 수락 합니다.
여기서 get_posts, get_person, get_comments, create_post 만 사용할 수 있도록 했습니다.
다른 메서드들은 플러그인에 직접 추가하여 구현 할 수 있습니다.
 
사실 플러그인 이긴 하지만 워낙에 간단 하기 때문에, 소스 설명이 그다지 없습니다.
 
기본적인 user-key, ukey, akey 설정을 하는 변수가 있고,
 
var defaults = {
   apiKey :   '',
   userKey :  '',
   authKey :  '',
   userID :   ''
  };
 
메서드를 표한 하는 url
var urls = {
   baseUrl :   'http://me2day.net/api/',
   getPosts :   'get_posts/',
   getPerson :  'get_person/',
   getComments :  'get_comments/',
   createPost : 'create_post/'
  };
여기에다가 메서드를 추가하여 확장 할 수 있습니다.
 
그리고 자신의 글 목록 및 댓글을 가져오는 ajax 요청과, 글을 등록하는 ajax 요청이 있습니다
 
function createPosts() {
   $.ajax({
    url : urls.baseUrl + urls.createPost + defaults.userID + '.json',
    method : 'post',
    data : { 'post[body]' : contents.val(), 'uid' : 'reperion', 'ukey': defaults.authKey, 'akey' : defaults.apiKey},
    dataType : 'jsonp',
    jsonp : 'callback',
    error : function( error) {
     // error has code, message, description
    },
    success : function( data) {
     articleList.prepend( getArticleDiv( data));
     contents.val( '');
    },
    complete : function() {
    }
   });
  }
 
이런 형식으로 REST 방식으로 URL을 호출 하게되면 응답 결과를 XML, JSON으로 리턴해줍니다.
이번에도 역시 JSON이 편하기 때문에 JSON 형식으로 리턴 받아서 사용하게 했습니다.
이 JSON 을 파싱해서 사용 하면 됩니다.
   ※ get_posts  API : http://codian.springnote.com/pages/386176 
 


실행 결과
 
사용 방법은 플러그인을 사용할 DIV를 생성후 .meToday()를 호출 하면 됩니다.

<script type="text/javascript">
$(function() {
 $( '#target').meToday();
});
</script>
</head>
<body>
<div id="target">
 <div class="inputArea">
   <textarea id="contents"></textarea>
   <button id="btnAddArticle">등록</button>
 </div>
 <div class="articleList">
 </div>
</div>
</body>
</html>

 


IE 8에서 가끔 106번째 라인인가 elem[object] ... 어쩌구 하면서
없는 오브젝트라고 표시될 때가 있다.

왜 그러느냐 하면..
.class( 'height')를 하면 FF 는 숫자를 IE 는 숫자px를 리턴한다.

이렇게 서로 값이 틀려서.. 오류를 -ㅅ-
걍 변하게 .height() 쓰자. -_-;;


뭘까..

가장 핵심은 Selector를 이용하여 element를 찾고 이것에다가 작업을 하는것이 아닌가 싶다.
일단 무슨 작업을 할려면 작업을 할 대상 element를 찾아야 한다!!
그러므로 Selector는 기본 -ㅁ-.. CSS 셀렉터를 기본으로 하기 때문에 잘 알아두면 CSS에서도 그대로 쓸 수 있다.

그 다음이 API에 대해서 얼마나 아는가다.
사실 jQuery 사이트의 API 설명이 거의 완벽에 가깝기 때문에
모를때 마다 찾아가서 보는게 완전 좋다. 하하하.

거기다가 더하여 javascript에 대한 이해가 있으면 금상 첨화.

그럼 jquery 플러그인 개발 정도는 껌이라규!!!
수학적인거 빼고 ㅋ

하지만 난 아직 멀었다 OTL.

이번에는 오픈 API은 Flickr를 활용하여 이미지 갤러리를 만들어 보도록 하겠습니다.

오픈 API 란? 영문 , 한글
공개 API(Open Application Programmer Interface, Open API, 오픈 API)는 누구나 사용할 수 있도록 공개된 API를 말한다.
웹 2.0에 대한 관심이 넓어 지면서 점차 기업들이 API를 공개하고 이를 한대 묶어서 매쉬업 하는 웹 애플리케이션들에 대한 관심이 점진적으로 늘어 나고 있습니다. 개발자들도 매쉬업에 관련해서 많은 관심을 가지고 있습니다. ( 거의 최초의 매쉬업이라고 할 수 있는 구글 맵을 활용한 부동산 매쉬업 APP는 처음에 구글맵 API가 공개되어 있지 않았을 때 이를 한 개발자가 분석해서, APP를 만들었는데.. 이를 본 구글에서 이 사람을 고소 하지 않고 오히려 자사에 채용하고, 구글 맵 API를 공개했다고 합니다. - open api를 활용한 매쉬업 가이드)

우리들이 가장 많이 접했던 오픈 API는 지도(네이버, 구글, 야후, 다음 등), 이미지(플리커, ) 등 일 것입니다.

Flickr에 대한 소개

마이크로 블로그로 유명한 미투데이에서는 이미지를 플리커에 업로드하고 사용했었는데, 이를 최근(11월 초) 플리커에서 다 지워 버렸다고 합니다. 아마도 대부분의 사람들이 생각하기를 미투데이가 네이버에 인수되면서 사용량이 폭팔적으로 증가하자(플리커에 미투데이 계정을 가지고 사진을 업로드) 플리커에서 미투데이 계정과 관련된 사진을 다 삭제해 버렸다고 합니다. 아마 플리커에다가 이미지를 저장하면서 네이버에 인수 되니 야후(플리커소유)에서 뿔났나 보죠. ^^
사용으로 사용할 것이 아니면 무료로 사용가능 하고, 작은 규모의 기업에서는 그냥 사용해도 된다고 라이센스 규정에서 본 것 같습니다. 플리커를 이용해 수익을 발생시킬려면 라이센스 관련해서 읽어 보는것은 필수 겠네요!!! (API든 뭐든 일단 라이센스읽는게 필수)

이 플러그인은 플리커를 통해 이미지를 검색 하고, 이를 갤러리 형식으로 보여주는 것입니다.
파프리카에서는 사이트 Thumbnail 및 사용자 이미지를 위하여 이것을 사용 했습니다.

플리커 API : http://www.flickr.com/services/api/

Flickr API를 사용하여 조치를 수행하려면, 호출 규약을 선택하고, 끝점에 메소드 및 몇몇 인수를 지정하는 요청을 보내야 하며 그러면 포맷된 응답을 받게 됩니다.

  • API 색인 페이지에 나열된 모든 요청 형식은 명명된 매개 변수 목록을 사용합니다.

  • REQUIRED 매개 변수 method이(가) 호출 메소드를 지정하는 데 사용됩니다.

  • REQUIRED 매개 변수 api_key이(가) API 키를 지정하는 데 사용됩니다.

  • 선택적 매개 변수 format이(가) 응답 형식을 지정하는 데 사용됩니다


Flickr API를 사용하여 검색하기 위해서는 api_key가 필요 합니다.
api_key를 얻기 위해서는 회원가입을 하여야 합니다. 이외 API를 통해 업로드를 진행 하기 위해선 비밀 키 값도 회원가입을 통해서 얻어야 합니다.


플리커 검색 요청 형식에는 (REST, XML-RPC, SOAP) 방식이 있습니다.
이중에서 가장 사용법이 간단하고 쉬운 REST방식을 사용하도록 하겠습니다.

REST 요청 형식

REST는 사용하기에 가장 단순한 요청 형식입니다. 이는 단순한 HTTP GET 또는 POST 조치입니다.

REST 끝점 URL은 http://api.flickr.com/services/rest/입니다.

flickr.test.echo 서비스를 요청하려면 다음과 같이 호출하십시오.

http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value

기본적으로 REST 요청은 REST 응답을 보냅니다.

JSON 응답을 받기 위한 URL

http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value&format=json


응답 형식 역시 가장 사용하기 쉬운 JSON 방식을 사용하도록 하겠습니다.

기본적으로 요청을 받기 위한 URL입력하고,
결과(JSON)을 가지고 결과 화면을 구성 하면 됩니다.
이것을 생각하면서 보면 이해가 확실히 쉬어 집니다!!!

Flickr API에서는 다양한 API Method 를 지원합니다.
Activity, Blogs, Auth, Collection, Favorite, Search, People, Geo
여기서는 search API를 가지고 이미지 검색을 하도록 하겠습니다.

flickr.photo.search
search api를 살펴보면 다향한 종류의 parameter들이 존재하는 것을 확인 할 수 있습니다.
이 중에서 필요한 것은 method(flickr.photo.search), format(json), api_key, text(검색어), per_page(페이지당 가져올 결과 수)입니다.

검색 URL
 "http://api.flickr.com/services/rest/?method=" +
            options.method+"&format=" + options.format + "&api_key=" + options.api_key + "&text=" + options.text +"&per_page=" + options.perpage

위의 URL로 검색을 하게 되면, 검색 결과가 담긴 JSON Object를 반환하여 줍니다.
그러면 우리는 이 Object를 가지고 결과 image를 구성하면 됩니다.

그러면 반환 JSON의 형식을 알아 보도록 하겠습니다.
JSON 응답 샘플보기
성공적으로 응답에 성공 했을 경우 아래의 결과를 보내줍니다.
{"photos":{"page":1, "pages":7, "perpage":12, "total":"78", , "photo":[{}]}, "stat":"ok"})
각각의 요소에 대해서 알아 보면.
  • page : 현재 페이지
  • pages : 총 페이지
  • perpage : 페이지당 가져오는 건 갯수
  • total : 전체 건의 갯수
  • photo : 가져온 image의 정보
  • stat : 실패인지 성공인지 확인
이 요소들에서 page 속성들을 가지고, Page Navigator를 구성 할 수 있습니다.
사용자에게 검색 결과로 보여주는 이미지들의 photo요소의 값에서 추출하여 url을 구성 할 수  있습니다.
"photo":[{"id":"3782755242", "owner":"14698775@N08", "secret":"72162a6c9e", "server":"2474", "farm":3, "title":"Vancuber", "ispublic":1, "isfriend":0, "isfamily":0}
이 값들을 가지고 url을 구성하게 됩니다.
URL 설명서
샘플
http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg


플리커 검색 방법을 요약 하여 보면
  1. URL을 구성하여 검색을 요청 한다.
  2. 응답 결과를 확인 한 후, 응답결과를 가지고 이미지 URL을 구성한다.
  3. 구성항 URL을 조작 하여 사용자에게 보여준다.
이러한 형식으로 된 것을 확인할 수 있습니다.

파프리카에서 사용한 Flickr 갤러리도 이러한 방법으로 개발 되었습니다.

사용 방법 
$( '#searchResult').favoriteFlicker( {
            method :     'flickr.photos.search',
            api_key :     'api-key',
            format :     'json',
            text :        $( '#textSearch').val()
        });

이렇게 검색 결과를 보여줄 영역(searchResult)에 favoriteFlicker()를 사용하면 flickr검색을 수행 할 수 있습니다. 검색을 수행 하기 위해서 검색 값(textSearch)의 값을 포함해야 합니다.

이렇게 하여 수행 하게 되면
Flickr Plug-in Result

Flickr Plug-in 검색 결과


이렇게 표시 됩니다.

모든 소스를 확인해 볼 수는 없고, 검색 URL을 호출 하여 응답 JSON을 가지고 결과를 구성하는 방법을 확인해 보도록 하겠습니다.

function getList( page) {
            refresh();
            $( '.flickrThumbnail').addClass( 'flickrIndicator');
            $.ajax({
                url : url+"&page="+page,
                type : 'get',
                dataType : 'jsonp',
                jsonp : 'jsoncallback',
                success : function(data) {
                      $.each(data.photos.photo, function( index, val){
                        var imgUrl = getImgUrl(val.farm, val.server, val.id, val.secret, null),
                            nextImgUrl = getImgUrl(val.farm, val.server, val.id, val.secret, 'default');
                        target.find( '.flickrResultImgs').append( "<a rel='group' title='"+nextImgUrl+"' href='#'>"+
                                "<img src='"+imgUrl+"' class='flickrImg' width='100' height='65'></a>");

                    });
                      makeNavigation( data.photos);
                      $( 'a').click( function(){
                          $( this).find( 'img').addClass( 'flickrImgSelected');
                          $( '.flickrDetail').empty();
                        imgurl = $( this).attr( 'title');
                        img = new Image();
                        img.src = imgurl;
                        $( '.flickrDetail').append( img);
                    }).mousedown( function(){
                          $( '.flickrImgSelected').removeClass( 'flickrImgSelected');
                    });
                },
                complete : function() {
                      $( '.flickrThumbnail').removeClass( 'flickrIndicator');
                }
            });
        };

위 소스 코드를 살펴보면 jQuery에서 해당 URL을 AJax형식으로 요청을 하고, 이 결과를 'jsonp'형식으로 사용하는 것을 볼 수 있습니다. 결과 data형식에 'json'이 있는데 왜 'jsonp'형식으로 사용하였느냐 하면
내부 url로 요청을 할 떄는 'json'형식이 가능 하지만 외부 url로 요청을 할때는 'jsonp' 형식을 사용해야 합니다. 이렇게 해야 외부 응답 json을 가져 올 수 있습니다.

응답 결과(json)을 가지고 success에서 이 결과를 조작하여 img url을 생성하면 검색 결과를 화면에 보여줄 수 있습니다. 여기서는 $.each를 사용하여 검색 결과를 보여주고 있습니다.

makeNavigation()함수는 페이지 네비게이션을 만드는 함수 입니다.

자세한 소스 코드는 샘플 파일을 확인하세요.



아하하핫. 공부 합시다.

내용을 살펴 보기 전에 관점지향 프로그래밍(Aspect Oriented Programming, 이하 AOP)이란
무엇인가에 대하여 간단히 알아 보도록 하겠습니다..

(AOP의 핵심, 횡단 관심사를 코드에서 분리)

AOP의 필요성을 이해하는 가장 기초가 되는 개념은‘관심의 분리(Separation of Concerns)’이다. 관심의 분리는 컴퓨터 프로그래밍의 가장 기초가 되는 원리 중 하나이다. 거의 모든 프로그래밍 패러다임은 바로 이 관심의 분리 과정을 통해 문제 영역(problem domain)을 독립적인 모듈로 분해한다. 절차적 프로그래밍에서는 분리된 관심을 프로시저로 구성하고 OOP에서는 이를 클래스로 작성한다. 여기서 AOP는 OOP를 적용한다고 할지라도 충분히 분리해 낼 수 없는 부분이 있다는 문제 제기에서 출발한다.

AOP에서 주목하고 있는 부분은 OOP와 같은 모듈화가 뛰어난 방법을 사용하더라도 결코 쉽게 분리된 모듈로 작성하기 힘든 요구사항이 실제 애플리케이션 설계와 개발에서 자주 발견된다는 점이다. AOP에서는 이를 횡단 관심(crosscutting concerns)이라고 한다. 이에 대비해서 해당 시스템의 핵심 가치와 목적이 그대로 드러난 관심 영역을 핵심 관심(core concerns)이라고 부른다. 이 핵심 관심은 기존의 객체지향 분석/설계(OOAD)를 통해 쉽게 모듈화와 추상화가 가능하다. 하지만 횡단 관심은 객체지향의 기본 원칙을 지키면서 이를 분리해서 모듈화하는 것이 매우 어렵다.

- http://www.zdnet.co.kr/ArticleView.asp?artice_id=00000039147106 기사 발췌-

자세한 내용은 위 기사를 확인 해 보시면 AOP가 무엇인지에 대하여 감을 잡으실 수 있습니다.

저도 감만 잡았지 확실하게 이해 하지는 못했습니다. -,.-
하지만 관심사의 분리가 가장 중요한 개념이라는 생각만 가지고 계시면 될 것 같습니다. ㅎㅎ;;;

 

그럼 AOP에 대해선 이정도만 알아 보고,
jQuery AOP에 대하여 알아보도록 하겠습니다. 

사이트 : http://code.google.com/p/jquery-aop/
레퍼런스 : http://code.google.com/p/jquery-aop/wiki/Reference

레퍼런스를 확인해 보시면 알겠지만, 사용법이 대단히 간단 합니다.
before, after, around등을 지원 합니다.

그럼 샘플 코드를 살펴 보면서 AOP를 어떻게 적용 했는지 보도록 하겠습니다.

As-Is Script

$( '.moveFirst').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  getFavorite( publicUserType, 0);
});

$( '.moveLast').click( function(){
  if ( isClickAble( this))
   return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() + 1) * $( this).parent().find( '#limit').val();
  getFavorite( publicUserType, page);
});

$( '.movePrev').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() - 1) * $( this).parent().find( '#limit').val();  getFavorite( publicUserType, page);
});

$( '.moveNext').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() + 1) * $( this).parent().find( '#limit').val();
  getFavorite( publicUserType, page);
});


 

음.. 이 Script를 보시면.. 뭔가 마틴 파울러란 사람이 말했던 bad smells in codes(http://en.wikipedia.org/wiki/Code_smell)...인가 그게 생각나지 않습니까?

-,.-;; 저도 생각나다 말았습니다. ㅋ_ㅋ
리팩토링 관점으로 본다면야, 아래 코드가 중복되어 있기 때문에 메서드로 추출해서 쓰면 되겠다.. 싶으실 껍니다. 하지만 이번엔 AOP적인 마인드로 생각을 해 보면.  

아래의 코드는 비즈니스 로직과 관련이 없는 횡단관심사항인것으로 판단 할 수 있습니다.
그러니까 이 코드가 바로 AOP를 적용할 조인포인트(joinpoint)로 생각할 수 있습니다.

// 클릭 가능한지 않는지 판단( 페이징에서 처음 페이지일때 처음 버튼 클릭 못하게 할 경우)
if ( isClickAble( this))
    return;
// 페이징시 이전 페이징된 리스트들을 삭제.  
$( '#FavoriteList').children().remove();

 

그럼 AOP를 적용하여 보도록 하겠습니다.

To-Be Script 

// 메서드에 AOP를 적용하기 위에 이벤트 안의 내용들을 메소드로 추출 했습니다.
$( '.moveFirst').click( function(){
  movePageFirstHandler( this);
 });

 $( '.moveLast').click( function(){
  movePageLastHandler( this);
 });

 $( '.movePrev').click( function(){
  movePagePrevHandler( this);
 });

 $( '.moveNext').click( function(){
  movePageNextHandler( this);
 });

jQuery.aop.around({ target: window, method: /movePage*/},
  function( invocation){
   if ( isClickAble( invocation.arguments)) {
    return null;
   }  else {
    $( '#FavoriteList').children().remove();
    invocation.proceed();
   }
  }
 );

 

이렇게 바뀌게 됩니다!!
이 AOP 플러그인은 특정 메서드를 지정하거나, 정규 표현식을 사용해서 AOP를 걸 수 있습니다.

위 코드에서는 /movePage*/를 사용(정규식)해서 movePage로 시작하는 메서드들에 해당
around aop를 위빙(weaving)하고 있습니다.(정규식 테스트 사이트)

오우 사용 방법이 생각보다 어렵진 않습니다. AspectJ 나 SpringAOP에 비하면.. 쉬운것 같습니다.

Plus.
AOP를 적용하지 않았을 경우 발생할 수 있는 문제점.




AOP의 구성 요소
- AOP에는 새로운 용어가 많이 등장한다. 이 중에서 특히 AOP를 이용해서 개발하는데 필요한 중요한 구성요소들에 대한 정의를 정확히 이해해야 한다.


참고 할 것.
http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

Plug me: Writing your own plugins

Writing your own plugins for jQuery is quite easy. If you stick to the following rules, it is easy for others to integrate your plugin, too.

Plugin Naming

Find a name for your plugin, lets call our example "foobar". Create a file named jquery.[yourpluginname].js, eg. jquery.foobar.js

Adding a Custom Method

Create one or more plugin methods by extending the jQuery object, eg.:

 jQuery.fn.foobar = function() {
// do something
};

Which will then be accessible by performing:

 $(...).foobar();

Default Settings:

Create default settings that can be changed by the user, eg.:

 jQuery.fn.foobar = function(options) {
var settings = jQuery.extend({
value: 5, name: "pete", bar: 655
}, options);
};

You can then call the plugin without options, using the defaults:

 $("...").foobar();

Or with some options:

 $("...").foobar({ value: 123, bar: 9 });

Documentation

If you release your plugin, you should provide some examples and documentation, too. There are lots of plugins available as a great reference.

Now you should have the basic idea of plugin writing. Lets use this knowledge and write one of our own.

Checkbox Plugin

Something lots of people, trying to manipulate forms with jQuery, ask for, is checking and unchecking of radio buttons or checkboxes. They end up with code like this:

 $(":checkbox").each(function() {
this.checked = true;
this.checked = false; // or, to uncheck
this.checked = !this.checked; // or, to toggle
});

Whenever you have an each in your code, you might want to rewrite that as a plugin, pretty straightforward:

 jQuery.fn.check = function() {
return this.each(function() {
this.checked = true;
});
};

This plugin can now be used:

 $(":checkbox").check();

Now you could write plugins for both uncheck() and toggleCheck(), too. But instead we extend our plugin to accept some options.

 jQuery.fn.check = function(mode) {
// if mode is undefined, use 'on' as default
var mode = mode || 'on';

return this.each(function() {
switch(mode) {
case 'on':
this.checked = true;
break;
case 'off':
this.checked = false;
break;
case 'toggle':
this.checked = !this.checked;
break;
}
});
};

By providing a default for the option, the user can omit the option or pass one of "on", "off", and "toggle", eg.:

 $(":checkbox").check();
$(":checkbox").check('on');
$(":checkbox").check('off');
$(":checkbox").check('toggle');

Optional Settings

With more than one optional setting, this approach gets complicated, because the user must pass null values if he wants to omit the first parameter and only use the second.

The use of the tablesorter in the last chapter demonstrates the use of an object literal to solve this problem. The user can omit all parameters or pass an object with a key/value pair for every setting he wants to override.

For an exercise, you could try to rewrite the Voting code from the fourth section as a plugin. The plugin skeleton should look like this:

 jQuery.fn.rateMe = function(options) {
// instead of selecting a static container with
// $("#rating"), we now use the jQuery context
var container = this;

var settings = jQuery.extend({
url: "rate.php"
// put more defaults here
}, options);

// ... rest of the code ...

// if possible, return "this" to not break the chain
return this;
});

And allowing you to run the plugin like so:

 $(...).rateMe({ url: "test.php" });