Groovy/gradle2014.09.11 21:46


gradle을 이용하여 의존성 관리 스크립트를 짜면

보통 다음과 같은 형태의 스크립트로 구성한다.

apply plugin: 'java' repositories { mavenCentral() } dependencies { compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' testCompile group: 'junit', name: 'junit', version: '4.+' }

출처 - gradle.org 문서의 Example 8.1


하지만 종종 위와 같은 형태가 아닌

repositories{} 와 dependencies{} 를 buildscript{} 로 감싸는 경우가 있다.

import org.apache.commons.codec.binary.Base64

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

task encode << {
    def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
    println new String(encodedString)
}

출처 - gradle.org 문서의 Example 60.7


위의 코드를 보면

외부 라이브러리 의존관계 설정에 compile, 이나 testCompile 등이 아닌 classpath를 사용 하고 있다.


어떤차이가 있을까?

전자의 경우엔 명시된 상황에서만 의존 라이브러리를 참조 할 수 있다.

즉 compile 로 명시된 라이브러리의 경우 자바 컴파일 시에 라이브러리를 참조한다는 이야기이다.(이때는 testCompile의 라이브러리를 참조하지 않는다.)

위 의존관계에 대한 자세한사항은 다음을 참조

http://www.gradle.org/docs/current/userguide/java_plugin.html#tab:configurations


이번엔 후자를 보자.

gradle을 사용할 때 task를 많이 사용 하게 될 것이다. 그리고 종종 스크립트 안에서 바로 외부 라이브러리의 특정 메소드를 사용해야 하는 경우가 있다. 그럴 경우 후자처럼 코드를 작성해야 한다.

예제에서는 apache commn codec 라이브러리의 Base64.encode() 메소드를 사용하기 위한 방법을 보여준다.

즉 후자와 같은 경우는 gradle의 스크립트에서 바로 외부 라이브러리를 참조해야 할 경우에 사용하는 방법이다.



참고자료

http://www.gradle.org/docs/current/userguide/organizing_build_logic.html#sec:external_dependencies

http://stackoverflow.com/questions/13923766/gradle-buildscript-dependencies

http://chimera.labs.oreilly.com/books/1234000001741/ch04.html#_buildscript_dependencies

'Groovy > gradle' 카테고리의 다른 글

[gradle] buildscript dependencies 와 dependencies 의 차이  (0) 2014.09.11
Posted by 하품 - yawn 하품 - yawn
JAVA2014.07.24 21:50

checked Exception & unchecked Exception

checked Exception

컴파일러 수준에서 인지할 수 있는 예외

try{}catch(){} 의 사용을 강제

 

unchecked Exception

runtimeException을 상속한 모든 Exception

Runtime(실행시)에 인지 할 수 있는 예외

try{}catch(){}문이 선택적

예외 처리의 유의 사항

이펙티브 자바에서 제시하는 예외처리의 유의점은 다음과 같다(항목 57 ~ 65)

항목. 57 - 예외 상황에서만 예외를 사용하자

다음과 같은 코드는 작성하면 안된다

try {
    int i = 0;
    while(true)
       range[i++].climb();
} catch(ArrayIndexOutOfBoundsException e) {       
}

항목. 58 - 복구 가능 상황에는 checked 예외를 사용하고 런타임 예외는 프로그램 예외에 사용하자

즉 해당 메소드를 호출한 곳에서 try ~ catch문을 이용하여 예외를 복구 할 수 있는 상황에만 사용되는 예외만을 checked 예외를 사용한다.

항목. 59 - checked 예외의 불필요한 사용을 피하자

항목. 60 - 표준 예외를 사용하자

항목. 61 - 하위 계층의 예외 처리를 신중하게 하자

무작정 상위계층으로 에러를 던지지 말자, 상위 계층으로 예외를 던질때는 상위계층이 알아 볼 수 있는 예외로 변환하여 던져야 한다.

항목. 62 - 메소드가 던지는 모든 예외를 문서하 하자

항목. 63 - 실패 상황 정보를 상세 메시지에 포함하자

항목. 64 - 실패 원자성을 갖도록 노력하자

호출된 메소드가 실행에 실패하더라도 객체 상태는 메소드 호출 전과 같아야 한다.

항목. 65 - 예외를 묵살하지 말자

다음과 같은 예외처리가 예외 묵살의 좋은 예이다.

try {
    ....
} catch(someException e) {}
 try {
    ....
} catch(someException e) {
    e.printStatckTrace();
}

Checked Exceptoin의 문제점

코드가 너무 많이 생긴다

깨지기 쉬운 메소드 원형

끝없는 예외 wrapping

checked exceptoin이 인터페이스에서 잘 동작하지 않는다

http://bleujin.tistory.com/30

 

checked Exception은 OCP(개방 폐쇄 원칙)을 위반한다

http://cleancodes.tistory.com/5

어떤 때 예외 처리를 해야 하는가?

이 글을 쓰게 된 취지는 이 의문에 대한 답을 찾아보기 위함이었다.

하지만 예외 처리 관련하여 자료를 찾고 공부를 할 수록 이에 대한 '명확한 답은 없다' 는 점만 더 확실해 졌다.

 

결론적으로, 예외처리는 개발자가 알아서 판단하여야 한다.

 

그래도 개인적으로 다음과 같은 가이드라인 정도는 제시할 수 있지 않을까 생각한다.

예외가 발생하는 상황이라면 예외가 발생하여야 한다.

예외가 발생한다는건 코드의 문제이건, 외부 요인의 문제이건 어떠한 문제가 존재한다는 이야기 이다.

그렇다면 예외 발생하였음을 인지해야 문제를 고치고 넘어가지, 예외가 발생했는데도 마치 프로그램이 멀쩡히 돌아가는 것 처럼 보여선 안된다. (대표적으로 항목 65 - 예외 묵살하기)

여러 예외가 발생하였는데도 모르고 그냥 지나가 버리면 오히려 더 큰 문제를 발생시키기위한 요인이 되어 버린다.

 

외부 요인으로 인한 예외가 발생하는 경우

예를 들어 외부 서버와의 통신을 하는 sdk 제공받아 개발을 진행중이라고 가정하자.

사용하는 메소드 중

coupang.getCoupangUserList(args1, args2);

같은 것이 있고, 위 메소드가 외부 서버와 통신을 하여 데이터를 가져온다면, 인터넷 환경등의 문제로 연결이 끊기는 등의 문제가 발생할때를 대비하여 

몇초이상 응답이 없을 경우 TimeOutException 등을 던지도록 개발되었을 것이다.

이런 경우는 필히 사용자가 상황을 인지해야하고, 또한 예외로 인한 프로그램다운등을 막기 위하여 

try ~ catch 등을 이용하여 예외처리를 해 주어야 할 것이다.

 

비지니스 로직 상에서 발생하여 사용자에게 인지시킬 필요가 있는 경우

간단한 예로 회원가입 등의 경우 필수 파라미터가 있다.

이런것들이 어떠한 이유로 누락되거나, 엉뚱한 값이 넘어오거나 했을 때 예외를 발생시키고 이를 사용자가 인지할 수 있도록 예외처리를 할 수 있다.

 

그외 개발자 판단하에 필요하다 싶은 부분에 예외 처리 로직을 작성한다.

참고자료

http://www.nextree.co.kr/p3239/

http://blog.benelog.net/1901121

http://homo-ware.tistory.com/161

http://b4you.net/blog/tag/Unchecked%20Exception

http://slipp.net/questions/259

http://kwonnam.pe.kr/wiki/java/exception?s[]=checked&s[]=exception

Posted by 하품 - yawn 하품 - yawn
개발툴...2014.06.09 22:00

3. SourceTree 를 이용한 Pull & Merge


Git에는 Fetch와 Pull이 있습니다. 이 둘은 조금다른데 공식[?] 설명은 Fetch는 원격서버의 정보를 가져오지만 merge를 하지 않고, Pull은 정보를 가져와서 merge를 한다 라고 되어 있습니다.


쉽게 말해 Fetch는 원격서버의 정보를 새로고침 하는 것이고 Pull은 원격서버 정보를 로컬에 반영하는 것 입니다.


스샷을 봅시다.

지난화 마지막에서 파일 하나를 수정한 후 커밋한 모습입니다. 원격서버는 다른 브랜치를 가리키고 있습니다.

우선 변경점을 원격에 푸시하기전에 먼저 페치를 해 봅시다.(중간의 Fetch 아이콘을 누릅시다. 점화살표)


무언가 변화가 생겼습니다. Pull에 1 아이콘이 생기고 Push에도 1 아이콘이 생겼네요(빨간박스)

깃 로그도 무언가 달라졌습니다. 트리그래프도 분기가 되었습니다.


이는 다른 누군가가 서버에 푸시를 해놓았단 이야기 입니다. 원격 서버에 변경이 일어났다는 것이죠.

이런 상황에서는 Pull을 해서 로컬의 파일을 원격 파일들과 싱크를 맞춰주기 전에는 푸시가 불가능 합니다.

자 Pull을 눌러 이제 변경된 사항을 로컬에 반영하도록 합시다.


무언가 심각한 것 같은 상황이 보입니다(빨간박스)

이는 Conflict가 생겼다는 표시인데요. 동일 파일의 동일 라인을 나도 수정하고, 다른 사람도 수정했다는 소리입니다.

같은 곳을 건들였으니 충돌이 일어난 것이죠.  직접 파일에 가 확인해봅시다



꺽쇄와 = 표시로 충돌난 부분이 잘 나와 있습니다.

======= 윗부분의 HEAD 까지가 현 로컬에 작성되어 있는 부분이고

밑부분의 커밋 해시 값 까지가 원격에서 가져온 코드 입니다.


여기서 원하는걸 선택하고 버릴걸 지운후 기존에 Commit 하듯이 합시다.


화살표로 눌러 Staged Changes 로 올리면 변경되었단 표시가 나오고...


커밋을 하면 위와같이 소스트리에서 자동으로 생성한 커밋메세지가 들어가 있습니다.

팀의 컨벤션이나, 취향에 따라 커밋메세지를 바꾸시면 됩니다. (안바꿔도 되구요)

그리고 커밋을 완료합시다.


자 이제 서버로부터 Pull도 하였고 충돌도 해결하고 Merge도 완료되었습니다.

즉 원격서버의 변경점이 내가 사용하는 로컬에 merge되었습니다


그럼 로컬에선 2가지 변경점이 생겼습니다. 내가 본래 커밋한 것 하나, 원격의 변경점을 머지 한 것 하나.

빨간박스를 확인하면 푸시 버튼에 2가 표시된걸 보실 수 있습니다.



Posted by 하품 - yawn 하품 - yawn
개발툴...2014.06.08 23:11

소스트리 사용법 소개 두번째 시간입니다.

간단한건데 매우 오랜만에 올리네요 ㅠㅠ


2. SourceTree 를 이용한 Commit & Push

소스트리를 이용해서 커밋과 푸시를 진행하는 방법을 스샷을 보면서 간략하게 소개하겠습니다.


우선 프로젝트에서 파일을 변경후 세이브를 합니다.(예시로 간단하게 파일 하나반 면경하였습니다)


그리고 소스트리를 틀어보면 아래와 같은 화면이 나옵니다.


파란박스에는 커밋되지 않은 변경점이 있다고(영어로 쓰인)부분이 보이시죠?

그리고 녹색박스를 보면 정확히 어떤 파일이 바귀었는지 나옵니다. 지금은 파일 하나만 변경하여 하나만 보입니다.(우측엔 상세 변경내역이 표시 됩니다)

이전에 깃에 대해 설명할때, 깃은 커밋 직전 staging 이라는 한단계를 더 거친다고 했습니다.


현재는 파일이 변경된 상태일 뿐입니다.

빨간박스에 보이는 화살표를 눌러 stage 상태를 만들어 줘야 커밋이 가능해 집니다.

아래와 같이요.



staged changes에 파일이 올라간게 확인되면 좌측 상단 두번째 아이콘 Commit을 눌러줍니다.



그럼 위와 같은 화면이 보입니다.(사실 파일을 stage 공간에 넣는 작업을 여기서 해도 됩니다.)

커밋되는 파일은 Staged Changes에 보이는 파일만이 커밋이 됩니다. 즉 일부 파일은 커밋하기 싫다면 Working Copy Changes에 그대로 두거나, 다시 돌려보내도 된다는 소리이지요.


그리고 우측 하단의 커밋 버튼을 누르기전에 꼭 커밋 메세지(빨간박스)를 작성해야 합니다.

작성하였다면 커밋을 누릅시다.




커밋이 완료된 상황입니다.

깃 히스토리를 보여주는 화면에서 uncomminted changes가 사라지고 새로운 커밋이 하나 타나났습니다.(파란박스)

보시면 1ahead란 아이콘과 두개의 master 아이콘이 보이실 겁니다.

이는 원격 저장소와 몇개의 커밋이 차이가 있는지 를 보여주는 것 입니다.


그리고 현재 변경된건 로컬뿐이죠?

그렇기에 로컬의 master헤드는 새로운 커밋을 가르키고 있고, 아직 변경점이 반영이 안된 원격 저장소의 헤드(origin/master)는 이전 커밋을 가르키고 있습니다.


이제 원격저장소에도 변경점을 저장하기 위해 푸시를 해야 합니다. 푸시 버튼을 누릅시다.(빨간박스)




그럼 위처럼 로컬 브랜치와 그와 연결된 마스터 프랜치의 리스트가 나옵니다.

지금은 다 한개밖에 없어서 하나밖에 안나오지만요.

왼쪽에서 푸시할 로컬 브랜치를 선택하고, 오른쪽엔 푸시받을 원격저장소의 브랜치를 선택합니다. 즉, 로컬 브랜치 명이 마스터라도 원격의 다른 브랜치에 푸시할 수도 있습니다.


선택 완료 후 ok 를 눌러주면 프로그레스바가 뜨고, 인증이 필요하면 인증창도 뜨고 합니다.




에러 없이 완료되었다면 이 화면을 보실 수 있습니다.

원격의 origin/master와 로컬의 master가 같은 커밋을 가리키고 있는 것이 보이시죠?


이렇게 변경점의 커밋과 푸시가 완료되었습니다.




Posted by 하품 - yawn 하품 - yawn
OS/Linux2014.05.16 16:49

http://devday.tistory.com/entry/%EC%9E%90%EB%B0%94-Java%EC%97%90%EC%84%9C-GC-Garbage-Collection-%EB%A1%9C%EA%B7%B8-Log-%EB%82%A8%EA%B8%B0%EA%B8%B0



Posted by 하품 - yawn 하품 - yawn
개발툴...2014.05.11 20:58

Git GUI 도구인 소스트리에 대한 소개와, 소스트리를 이용해서 깃을 이용하는 방법을 소개합니다.

소스트리에 대해서는 사용하는 사람마다 호불호가 많이 갈리지만 전 이쁜[?] GUI로 인해서 좋아하는 편입니다.


소스트리 다운로드 사이트

http://www.sourcetreeapp.com/


소스트리는 위 사이트에서 받아서 설치하시면 됩니다.

설치는 정말 받아서 설치하면 끝납니다



1. 깃 저장소 연동하기 (GitHub 이용)

깃허브의 깃 저장소와 소스트리를 연동하는 예제를 먼저 진행합니다.


소스트리 설치가 끝났으면 실행을 합니다.


실행시 다음화면이 나오는데 여기서는 Mecurial을 사용하지 않을 것이기에 맨 아래

I don't want to Mecurial 을 눌러주세요

짚고가기 : Git 과 Mecurial



그리고 깃에서 사용할 사용자 정보를 입력합니다.

만일 git config 명령을 이용하여 글로벌 설정을 해 두었다면 자동으로 입력됩니다.




그 외의 설정들은 입맛에 맞는대로 쭉쭉 지나가시면 됩니다. 잘 모르겠으면 스킵해도 무방합니다.

아래의 여러 깃 저장소들의 계정을 입력하지 않아도 상관 없습니다.



위의 기본적인 설정을 마치고 나면 아래와 같은 화면이 나타납니다.

이제 깃 저장소와 연동, 정확히는 깃 저장소에서 소스코드를 클론해 오기위하여 아래의 빨간 박스(Clone / New) 를 클릭합니다.



그럼 아래와 같은 새 창이 뜹니다.

두번째 탭은 이미 있는 저장소를 소스트리에 인식 시키는 것이고, 세번째는 아예 새로운 깃 로컬 저장소를 만드는 것 입니다.

여기서는 GitHub 의 코드를 클론 하는 것이기에 첫번째 탭을 이용합니다.


Source Path 에는 깃헙 저장소 주소를 넣고

ex> https://github.com/{id}/{storageName}.git

Destination Path 에는 소스를 저장한 자신의 컴퓨터 경로를 입력합니다.




자 이제 Clone을 누르면 소스코드를 복사하는 프로그레스 바가 보여지고, 문제가 없다면 다음과 같은 화면이 뜨면서 소스트리를 이용하여 깃 원격저장소와 로컬 저장소의 연동이 끝나게 됩니다.



부가적으로 위 하면에 대해 설명하겠습니다.

빨간 박스 : 자신이 생성한 깃 저장소에 대한 북마크 목록이 나타납니다.

파란 박스 : 파일의 상태, 브랜치목록, 태그, 원격 저장소 등 현 저장소의 정보가 나타납니다.

녹색 박스 : 커밋 로그입니다. 간단한 메세지와 각 HEAD가 어딜 바라보고 있는지 등이 나타나며 TreeGrapth가 보여집니다. 위 예제는 첫 커밋밖에 없는 지라 그래프가 보이지는 않습니다.

노랑 박스 : 선택된 커밋에 대한 자세한 커밋로그, 변경된 파일과 변경된 소스코드들이 상세하게 나타납니다.


소스트리를 이용하여 깃을 다루기위한 기본 상태[?]는 이것으로 마치고, 이제 포스팅을 하나하나 추가하며 사용법을 작성하도록 하겠습니다.




Posted by 하품 - yawn 하품 - yawn
javascript2014.04.08 19:51


이전 포스팅인 [HTML] HTML Attribute와 javascript Property 에서 HTML Attribute 와 javascript의 Property에 대해 좀더 제대로 정리를 하기위해 남깁니다.


우선 w3school 에서 얻을 수 있는 HTML Attribute에 대한 설명은 다음과 같습니다.

HTML Attributes
HTML elements can have attributes
Attributes provide additional information about an element
Attributes are always specified in the start tag
Attributes come in name/value pairs like: name="value"

- attributes(속성) 는 elements(요소) 에 포함 되는 것
- element 에 대한 추가적인 정보를 제공한다
- attribute는 항상 시작tag 에 저장되어 있다.
- attribute는 name = "value" 의 형태로 나타난다.

JavaScript Properties
Properties are the values associated with a JavaScript object.
A JavaScript object is a collection of unordered properties.
Properties can usually be changed, added, and deleted, but some are read only.

property는 javascript object와 연관되어진 값들 입니다.
javascript object는 정렬되지 않은 property 의 콜렉션 입니다.
property는 바뀔 수 있고, 추가되고 지워질 수 있습니다. 단 어떤 것은 읽기만이 가능 합니다.

property는 코드를 보며 이해하는게 좀더 명확 할텐데요.
자바스크립트의 object는 다음과 같은 형태를 가지고 있습니다.

var foo = function() {
    this.name = "hello";
}

위의 코드에서 foo 는 javascript object 이며 name 이 property 가 됩니다.
즉, property는 javascript object 에서 key="value" 형태로 구성된 것들 입니다.

요약하자면, attribute는 html element의 정보를, property는 자바스크립트 object의 정보들을 가져온다고 이해하면 될 듯 합니다.


이제 jQuery의 .attr()과 .prop()의 차이를 더 명확히 알 수 있을 것 같습니다.
.attr()은 HTML element의 정보를 기술하는 것들(name, value, class 등등)의 값을 가져오는 것입니다.

.prop()는 설명이 길어지는데...
HTML element들은 DOM 으로 표현되어 집니다. 그리고 이 DOM 은 javascript 를 이용하여 핸들링이 가능합니다.
이는 하나의 DOM object를 javascript 에서 마치 javascript object로 취급이 가능하다는 이야기 입니다.
실제로 document.getElementById 메소드를 이용하여 가져온 DOM object를 typeof 연산자를 사용해 보면 "object"를 반환합니다.
그리고 위에서 보았듯이 이 object는 key="value" 형태를 띈 property들로 구성되어 집니다.
여기서 .prop() key의 값, value를 가져오는 것입니다.

요약하면 DOM object의 property 값을 가져온다고 할 수 있겠습니다.

다음은 이와 관련하여 추가적으로 이해하면 좋을 내용들에 대한 링크 입니다.

The DOM and JavaScript


ps. 잘못되거나 추가해야될 내용등에 대한 지적은 언제나 환영합니다.


Posted by 하품 - yawn 하품 - yawn
javascript/jQuery2014.03.18 17:27

현재 jQuery버전은 2.1.0 등이 릴리즈 되고 있는 상황이지만... 한번 정리를 하고 넘어가고자 글을 남깁니다.


jQuery 1.6 부터 .prop() 메소드가 추가되었습니다.

즉 본래 다른 속성인 attribute와 property를 .attr() 메소드로 가져오던 것을 1.6부터는 구분하기 시작했습니다.


그럼 .attr()과 .prop()는 어떻게 다를까요?

.attr()은 attribute 정보를, .prop()는 property 정보를 가져 옵니다.

즉 먼저 attribute와 property 의 차이를 알아야 하는데요.

명확하게 설명하기가 힘들지만 설며을 하자면 (더 명확한 설명을 아시는분 꼭 이야기 해 주세요)


attrubute는 HTML Element 의 속성들을 뜻하며

property는 자바스크립트의..... (마땅히 번역할 말을 모르겠으니 그냥 프로퍼티로 하겠습니다)

자바스크립트의 프로퍼티를 뜻합니다.


즉 attribute는 HTML Element에서 사용되고, property는 자바스크립트에서 사용되는 정보라고 보시면 됩니다.

이 둘은 비슷한거 같지만 생각보다 굉장히 큰 차이를 가지고 있습니다.


jQuery 사이트에 올라와 있는 차이를 본다면...


Attributes vs. Properties

The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr()method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

For example, selectedIndextagNamenodeNamenodeTypeownerDocumentdefaultChecked, and defaultSelected should be retrieved and set with the .prop() method. Prior to jQuery 1.6, these properties were retrievable with the .attr() method, but this was not within the scope of attr. These do not have corresponding attributes and are only properties.

Concerning boolean attributes, consider a DOM element defined by the HTML markup <input type="checkbox" checked="checked" />, and assume it is in a JavaScript variable named elem:

elem.checkedtrue (Boolean) Will change with checkbox state
$( elem ).prop( "checked" )true (Boolean) Will change with checkbox state
elem.getAttribute( "checked" )"checked" (String) Initial state of the checkbox; does not change
$( elem ).attr( "checked" )  (1.6)"checked" (String) Initial state of the checkbox; does not change
$( elem ).attr( "checked" ) 
(1.6.1+)
"checked" (String) Will change with checkbox state
$( elem ).attr( "checked" )  (pre-1.6)true (Boolean) Changed with checkbox state


According to the W3C forms specification, the checked attribute is a boolean attribute, which means the corresponding property is true if the attribute is present at all—even if, for example, the attribute has no value or is set to empty string value or even "false". This is true of all boolean attributes.

Nevertheless, the most important concept to remember about the checked attribute is that it does not correspond to the checked property. The attribute actually corresponds to the defaultChecked property and should be used only to set theinitial value of the checkbox. The checked attribute value does not change with the state of the checkbox, while the checkedproperty does. Therefore, the cross-browser-compatible way to determine if a checkbox is checked is to use the property:

  • if ( elem.checked )
  • if ( $( elem ).prop( "checked" ) )
  • if ( $( elem ).is( ":checked" ) )

The same is true for other dynamic attributes, such as selected and value.


영어 해석은 힘드니 ㅠㅠ 주요 차이만 짚고 넘어가겠습니다.

확실히 보아야 할 부분은...


$( elem ).attr( "checked" ) (1.6)

$( elem ).attr( "checked" ) (1.6.1+)

$( elem ).prop( "checked" )


요 세가지 입니다.

보시는는 바와같이 .attr()을 사용 할 경우 "checked" 라는 스트링 값 이 넘어옵니다.

하지만 .prop()에선 체크박스의 체크 상태가 true, false 값으로 넘어옵니다.


정리하자면

.attr()을 사용할 경우, 해당 HTML attribute의 값이 모두 String으로 넘어오며, 

.prop()를 사용할 경우 자바스크립트의 프로퍼티값이 넘어오기에 boolean, date, 혹은 function 까지도 넘어 올 수 있습니다.



좀더 확실한 차이를 보자면, onclick, onchange등의 본래 자바스크립트 메소드들의 경우라면

onclick="someFunction()"  이라고 작성되었다고 볼때

.attr() 의 경우 "someFunction()" 이라는 스트링이

.prop() 의 경우onclick  펑션이 넘어오는걸 보실 수 있습니다.

(물론 요런 요상한 코드를 작성할 일이 있을진 모르겠지만...)



이상의 차이가 있으니 앞으로는 .attr()과 .prop()가 사용될 부분을 잘 구분하여 버그로인한 스트레스를 줄이도록 노력합시다~







Posted by 하품 - yawn 하품 - yawn
JAVA/Spring2014.02.20 22:28

해당 글에 사용된 토비의 스프링 3의 그림 및 소스 등에 대한 저작권은 이일민 님께 있습니다. 문제가 발생시 해당 글은 언제든지 내려질 수 있습니다.

해당 글은 이일민 님의 허락하에 작성되었습니다.

덧. 본인의 복습과 정리를 목적으로 작성하였기에 토비의 스프링을 읽지 않으셨다면 잘 안맞는 부분이 있을 수 있습니다.




토비의 스프링 2장은 테스트에 관한 이야기 입니다.


단위테스트

한가지의 관심에만 집중할 수 있도록 작성한 작은 단위의 테스트 코드.

개발자가 설계하고 만든 코드가 의도한 대로 작동하는지 개발자 스스로 빠르게 확인하기 위해 사용.


포괄적인 테스트

전반적인 기능의 동작을 모두 테스트하는 것이라 볼 수 있다.

예를 들어 Dao를 테스트 한다면 CRUD기능들과 예외발생 부분 등을 모두 검증 하는 것이다.



1장에선 초난감 Dao를 개선하였다면, 이번 장에서는 UserDaoTest라는 테스트케이스를 개선하는 작업이 이루어진다.

UserDaoTest 의 

기능

  • main() 메소드를 이용

  • 테스트할 대상인 UserDao의 오브젝트를 가져와 메소드를 호출

  • 테스트에 사용할 입력 값을 직접 코드에서 만듬

  • 테스트 결과를 콘솔에 출력

  • 각 단계가 에러없이 끝나면 콘솔에 성공메세지 출력

문제점

  • 수동 확인 작업의 번거로움

    • 일일히 실행하고 직접 확인하여야 함

  • 실행 작업의 번거로움

    • 테스트할 클래스가 많아질 수록 실행할것도 많아짐


UserDaoTest 개선하기

main() 메소드를 jUnit 메소드로 전환

  -> 수행 부담 감소

테스트 메소드 전환, jUnit 제공 메소들 검증코드 전환

  -> 코드 검증 자동화

사용자 정보가 없는 예외조건에 대한 테스트 

  -> 예외처리 검증

스프링 컨텍스트 사용을 위해 @RunWith, @ContextConfigration 어노테이션 사용 

  -> 스프링을 이용한 DI 가 가능해진다.

@before 어노테이션을 이용하여 초반에 항상 테이블을 초기화 해 줌으로써 동일한 결과의 보장

@Autowired 어노테이션을 이용하여 간편한 DI - 차후 설명

ApplicationContext는 자기 자신도 Spring Bean으로 만든다.

테스트를 위한 별도의 ApplicationContext 설정 파일 

  -> 실제 코드와 테스트 코드의 관리 용이 및 실수 방지(실서버 디비가 날라간다던가...)


jUnit ?

자바 개발자를 위한 테스팅 프레임워크


jUnit 이 테스트 클래스를 가져와 테스트를 수행하는 방식


  1. 테스트 클래스에서 @Test가 붙은 public void 형, 파라미터가 없는 테스트 메소드를 모두 찾는다.

  2. 테스트 클래스 오브젝트를 하나 만든다.

  3. @Before가 붙은 메소드가 있으면 실행

  4. @Test 가 붙은 메소드를 하나 호출하고 테스트 결과 저장

  5. @After 가 붙은 메솓가 있으면 실행

  6. 나머지 테스트 메소드에 대해 2~5번 반복

  7. 모든 결과를 종합하여 돌려줌



TIP

침투적 기술과 비 침투적 기술

침투적 기술은 기술을 적용 했을 때 코드에 기술관련 api가 등장하거나, 특정 인터페이스나 클래스를 사용하도록 강제하는 기술.

침투적 기술을 사용하면 코드가 해당 기술에 종속되는 결과를 가져온다.

비침투적 기술은 어플리케이션 로직을 담은 코드에 아무런 영향을 주지 않고 적용이 된다. 따라서 기술에 비 종속적인 순수한 코드를 유지할 수 있게 해준다. 스프링은 이런 비침투적 기술의 대표적인 예다.


동등분할(equivalence partitioning)

같은 결과를 내는 값의 범위를 구분해서 각 대표 값으로 테스트를 하는 방법. 어떤 작업 결과가 총 세가지라면(true, false, exception) 각 결과를 내는 입력 값이나 상황에 따른 조합을 만들어 모든 경우에 대한 테스트를 하는 것이 좋다.


경계값 분석(boundary value analysis)

에러는 동등분할 범위의 경계에서 주로 발생하는 특징을 이용하여 경계의 근처에 대한 값을 이용해 테스트 하는 방법. 숫자의 경우 0이나 그 주변 값, 혹은 정수의 최대값 최소값 등으로 테스트를 하면 도움이 된다.




샘플 코드

https://github.com/maximinhan/mytobyspring3/tree/master/spring02


'JAVA > Spring' 카테고리의 다른 글

[spring] 2. 테스트  (0) 2014.02.20
[Spring] 1. 오브젝트와 의존관계  (0) 2013.10.17
[Spring] 스프링 정리 시작합니다.  (0) 2013.10.17
Posted by 하품 - yawn 하품 - yawn
개발툴...2014.02.14 17:52

Selenium WebDriver에 관련된 정리 글들


셀레니움 - http://docs.seleniumhq.org/


솔웅님의 셀레니움관련 글 - http://coronasdk.tistory.com/727


셀레니움을 이용한 웹 어플리케이션 테스트 프로세스 - http://www.nextree.co.kr/selenium%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9B%B9%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%8B%9C%ED%97%98/


[구루비] 셀레니움을 이용한 UI 테스트 - http://wiki.gurubee.net/pages/viewpage.action?pageId=6259762



Posted by 하품 - yawn 하품 - yawn
개발툴...2014.02.06 11:03

쭈욱 읽어보니 소스트리등의 Git GUI툴이나

이클립스, 인텔리j의 Git 플러그인에서의 머지는 Commit Merge를 기본으로 하고 있다.

Fast-Froward Merge를 위해선 따로 체크를 해주어야 한다.


Git의 Merge 정책을 세울때 참고하면 꽤 좋은글.



http://dogfeet.github.io/articles/2011/git-merge.html



Posted by 하품 - yawn 하품 - yawn
개발 단상2013.11.10 22:24



현재 한국에 거의 유일한 소프트웨어 관련 정기 간행물!(내가 아는게 마이크로 소프트웨어 밖에 없는지도..)

마이크로 소프트웨어가 벌써 30 주년 이군요.

나보다 나이가 많아...


대학생 시절 도서관 정기 간행물 코너에 들어온 마소를 종종 보면서 처음 접했었죠.

여러모로 도움이 많이되는 잡지 마이크로 소프트웨어.

30주년 축하드립니다. 앞으로도 힘써 주세요!




책장의 마소들... 몇권은 어디로 갔지 -_-;;

Posted by 하품 - yawn 하품 - yawn
JAVA/Spring2013.10.17 16:24

해당 글에 사용된 토비의 스프링 3의 그림 및 소스 등에 대한 저작권은 이일민 님께 있습니다. 문제가 발생시 해당 글은 언제든지 내려질 수 있습니다.

해당 글은 이일민 님의 허락하에 작성되었습니다.

덧. 본인의 복습과 정리를 목적으로 작성하였기에 토비의 스프링을 읽지 않으셨다면 잘 안맞는 부분이 있을 수 있습니다.




토비의 스프링 1장은 초난감 DAO라 칭하는 하나의 DAO클래스를 보여주며 시작한다.


왜 초난감 DAO일까?

소스코드를 보면 기능 자체는 잘 작동한다. 하지만 잘 살펴보면 객체지향 설계원칙이 전혀 지켜지지 않았다.

특히나 (본인이 생각하기에) 객체지향 프로그래밍시 가장 먼저 우선되어야 할 '단일 책임의 원칙'이 완전히 깨져 있다.


1장의 내용은 이 초난감 DAO를 리팩토링 하면서 스프링의 중심철학(IoC 와 DI)을 설명하고 있다.

우선 다음을 기억하자.

관심사의 분리

관심이 같은 것기리는 하나의 객체안으로, 관심이 다른 것은 가능한 따로 떨어져서 서로 영향을 주지 않게 분리 하는 것.


관계설정 책임의 분리

특정한 동작을 하기위해선 여러 클래스끼리 관계를 맺어야 한다. 하지만 그런 관계를 맺는 메소드 등이 특정 클래스 안에 들어가 있다면 관계가 맺어진 클래스가 변경될 경우 수많은 클래스를 뜯어고쳐야 하는 일이 발생한다. 그렇기에 이러한 관계설정을 따로 분류한다.


토비의 스프링3를 예로 들자면 1장의 UserDao가 DB 커넥션을 하기위해 DConnectinoMaker와 클래스간 관계를 맺고 있다. 이는 ConnectionMaker 가 변경될경우 UserDao도 코드를 수정해야 하는 상황을 불러온다. 

이 클래스간 관계를 없애고 두 클래스간의 관계는 런타임시에 맺어지도록 하기위해 UserDao의 클라이언트(UserDaoTest)에 관계를 맺어주는 코드를 작성하였다. 즉 두 클래스간의 관계를 설정하는 관계설정 책임이 클라이언트(UserDaoTest)에 부과되었다.


개방페쇄 원칙

클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀있어야 한다.

코드는 변경하지 않으면서도 확장이 가능해야 한다.


높은 응집도와 낮은 결합도

응집도는 하나의 책임만을 담당하고 있는가를 뜻하고 결합도는 '하나의 오브젝트가 변경이 일어날 때 관계를 맺고 있는 다른 오브젝트에게 변화를 요구하는 정도' 라 말할 수 있다.

소프웨어 설계에서는 자신의 책임에 대한 응집도는 높고, 다른 객체와 맺은 관계에서는 결합도가 낮아야 한다.


1차적으로 리팩토링이 완료된 초난감 DAO의 다이어그램은 다음과 같다


(ConnectionMaker는 인터페이스)


UserDao에서 데이터베이스 커넥션 생성 책임이분리 되었다.

UserDaoTest란 클라이언트가 커넥션을 생성하여 UserDao에게 제공해 준다.

ConnectionMaker에는 전략 패턴이 적용되어 DConnectionMaker 뿐만 아니라 NConnectionMaker등도 사용 할 수 있다.

UserDao는 ConnectionMaker만 알고 있으면 된다.


언듯 보면 객체지향 원칙들이 잘 적용된 것 같지만 한가지 문제가 남아있다.

UserDaoTest가 테스트 책임 이외에 어떤 ConnectionMaker 구현 클래스를 사용할지 결정하는 책임이 같이 들어가 있다.

여기서 '객체의 생성 방법을 결정하고 그렇게 만들어지는 오브젝트를 돌려주는 팩토리 클래스'를 만들어 해결함으로써 리팩토링을 완료 한다.

이 팩토리 클래스(책의 DaoFactory 클래스)는 사용할 ConnectionMaker를 결정하고 이 커넥션을 사용하는 UserDao를 리턴한다.



이쯤에서 스프링에서 사용되는 몇가지 용어 및 개념에 대해 알아보자

제어의 역전(IoC)

간단히 설명하면 '모든 종류의 작업을 사용하는 쪽에서 제어하는 구조'를 거꾸로 뒤집은 것이다. 

제어의 역전에서는 모든 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않으며, 자신도 어떻게 만들어지고 어디서 사용되는지 알 수 없다. 모든 제어 권한을 자신이 아닌 다른대상에서 위임한다.

이 개념에 대한 자세한 내용은 역시 마틴 파울러의 글을 보는 것이 가장 좋다고 생각한다. 아래 링크는 그에 대한 포스팅이다.

http://vandbt.tistory.com/43

토비의 스프링에 나오는 소스로 이야기 하자면 본래 UserDao 에게 있던 제어권이 DaoFactory에 넘어가있다. DaoFactory가 UserDao가 사용할 오브젝트도 공급해주고, 구현하고 사용할 ConnectionMaker도 선택한다.


빈 bean (호지롷...)

스프링이 IoC 방식으로 관리하는 오브젝트라는 뜻. 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 빈이라고 부른다.


빈 팩토리 bean factory

스프링의 IoC를 담당하는 핵심 컨테이너. 빈의 등록, 생성, 조회 등등... 빈을 관리한다


애플리케이션 컨텍스트 application context

빈 팩토리를 확장한 IoC 컨테이너. 빈 팩토리의 기본적인 기능에 스프링이 제공하는 각종 부가 서비스를 제공한다.

이 용어를 더 많이 사용한다

애플리케이션에서 IoC를 적용해서 관리할 모든 오브젝트에 대한 생성과 관계설정을 담당한다.




설정정보/설정 메타정보 configuration metadate

애플리케이션 컨텍스트 혹은 빈팩토리가 IoC 적용을 위해 사용하는 메타정보.


싱글톤 빈 스코프

스프링에서 기본적인 빈의 스코프는 싱글톤 스코프를 가진다. 즉 하나의 빈 오브젝트만이 생성되며 계속 재사용 된다는 의미 이다.



의존관계 주입(Dependency Injection)

  위의 블로그 포스팅 링크에서도 잠시 언급되었지만 IoC라는 용어는 굉장히 광범위한 용어이다. 그렇기에 스프링이 제공하는 IoC방식의 핵심을 짚어주는 의존관계 주입(DI)라는 의도가 명확한 이름을 사용하는 것이 좋다고 한다.

  그렇다면 의존관계 주입이란 무엇일까. 토비의 스프링 1장에서 작성된 코드를 보면 UserDao는 DConnectionMaker에서 제공하는 Connection을 사용하여야 한다. 즉 UserDao와 DConnectionMaker는 의존관계에 있다고 볼 수 있는데, 이 둘이 직접적인 의존관계를 맺는 것이 아니라 외부에서 이 둘의 의존관계를 맺어주는 것이다. 또한 UserDao는 ConnectionMaker인터페이스에만 의존관계를 만들어두어 낮은 결합도를 유지하고 있다.

  즉 코드만 보아서는 UserDao와 DConnectionMaker와의 의존관계를 알 수가 없으며, 런타임시 UserDaoFactory가 둘의 의존관계를 주입하여 준다. 이러한 사항을 정리하면 의존관계 주입이란 다음의 세가지 조건을 충종하는 작업이라 할 수 있다.


- 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다.

- 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다.

- 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.


  UserDao를 보면 setConnectionMaker 라는 메소드가 존재한다. 이 메소드가 바로 의존관계를 주입받기위한 메소드 이다. 보통 set으로 시작하는 수정자 메소드(setter Method)를 이용하는 방식외애 생성자 메소드, 일반 메소드를 이용하여 의존관계를 주입받을 수 있다.


의존관계 검색(Dependency Lookup)

  외부로 부터 주입받는 DI가 아니라 스스로 의존관계를 검색하는 방식이 있다. 이를 의존관계 검색(DL)이라 부른다. 스프링이 사용된 코드를 보면 getBean() 이란 메소드를 볼 수 있다. 이 메소드가 DL을 이용하는 메소드이다. 

  DL은 언제 사용해야 할까? 스프링의 IoC와 DI컨테이너를 적용했다고 하더라도 어플리케이션의 기동 시점에 적어도 한번은 DL을 사용해 오브젝트를 가져와야 한다.  main()등의 메소드에서는 DI를 통해 오브젝트를 주입받을 방법이 없기때문이다.


스프링

  토비의 스프링 1장에서 만든 스프링이 적용되지 않은 코드만 보아도 충분히 DI가 작성되었다. 스프링은 그 코드중 UserDaoFactory에 작성된 정보들을 어노테이션이나 XML을 이용하여 설정정보로 읽어들여서 스프링이 직접 빈 오브젝트를 관리한다. 이때 사용되는것이 빈 팩토리와 어플리케이션 컨텍스트라 불리는 두가지 핵심적인 기능이다.

  스프링은 DaoFactory가 하는 일을 좀더 일반화 시킨것이며, 그 외에 직접 DaoFactory등을 구현해서는 활용하기 어려운 기능들을 쉽게 이용할 수 있게 해준다고 한다. 앞으로의 공부에서 이제 이런 기능들을 배우며 '왜 스프링을 사용하는가' 에 대해 더욱 정확히 알아갈 것이다.




샘플 코드

기존의 UserDao를 스프링의 코드로 변환한 소스는 다음의 깃허브 저장소를 참조하면 된다.

어노테이션, xml, 데이터소스를 이용하는 방법을 다 넣었다. 사용해보고자 하는 부분의 주석코드를 제거 하고 다른 코드를 주석처리 함으로써 각각의 방법으로 실행해 볼 수 있다.


https://github.com/maximinhan/mytobyspring3/tree/master/spring01


덧. DB는 직접 구현하셔야 합니다.



'JAVA > Spring' 카테고리의 다른 글

[spring] 2. 테스트  (0) 2014.02.20
[Spring] 1. 오브젝트와 의존관계  (0) 2013.10.17
[Spring] 스프링 정리 시작합니다.  (0) 2013.10.17
Posted by 하품 - yawn 하품 - yawn
JAVA/Spring2013.10.17 11:38

토비(이일민)님께 토비의 스프링의 일부 코드 및 그림등에 대해 사용허가도 받아놓고...

스프링 공부도 이미 시작해 놓구선 블로그에 대한 정리는 이제부터 시작합니다 -_-;;;;


준비는 한참전에 다 해놓고 시작이 너무 늦었어 Orz



현재 스프링은 3.2 버전까지 릴리즈가 되어 있고, 대략 내년을 기해 스프링 4가 릴리즈될 예정이라고 합니다.

그러나 제가 구입한 책은 토비의 스프링3 입니다. 구입하고 2주후에 토비의 스프링 3.1이 출시되더군요[.....]

(한참전에 구입했단 소리)


그래도 스프링의 패러다임, 구조 등이 크게 달라지진 않을 것이기에... 토비의 스프링3 를 가지고 하나하나 정리 이후 3.1과 그 이후 버전의 변경점 형태로 블로그에 정리해 나가고자 합니다.


글의 순서는 토비의 스프링3의 목차 순서와 동일합니다.

'JAVA > Spring' 카테고리의 다른 글

[spring] 2. 테스트  (0) 2014.02.20
[Spring] 1. 오브젝트와 의존관계  (0) 2013.10.17
[Spring] 스프링 정리 시작합니다.  (0) 2013.10.17
Posted by 하품 - yawn 하품 - yawn
iOS2013.09.25 18:32

iOS 6.0 부터 오토레이아웃이 적용되었다.

잘만 조정하면 코드한줄도 없이 다양한 상황에 대응되는 레아웃을 만들 수 있다.

하지만 언제나 원하는 대로는 되지 않는 법이고, 종종 코드로 오토레이아웃을 조절해 줘야하는 상황이 생긴다.

오토레이아웃을 코드로 조절하면 사실 코드가 굉장히 길어지고 헛갈리기 마련인데...

그것을 매우 쉽게 할 수 있는 오픈소스 라이브러리가 존재한다.


바로 Keep Layout 이다.

이 라이브러리는 다음의 깃 허브에서 받을 수 있다

KeepLayout


사용은 굉장히 간단한데 위 깃허브에서 source 폴더에 있는 파일을 모두 프로젝트에 포함시킨다.


xxxx.h 

#import <UIKit/UIKit.h>

#import "KeepLayout.h"/KeepLayout 사용을 위해 헤더에 포함


@interface xxxxController : UIViewController

@property (strong, nonatomic) IBOutlet UIView *superview_home;

@property (weak, nonatomic) IBOutlet UIButton *button_m1;

@property (weak, nonatomic) IBOutlet UIButton *button_m2;

@property (weak, nonatomic) IBOutlet UIButton *button_m3;

@property (weak, nonatomic) IBOutlet UIButton *button_m4;


@end


그리고 대략 위와 같이 오토레이아웃 적용을 받는 버튼 4개가 있다고 하자.

여기서 상황에 따라 각각의 버튼별로 Top Space를 변경하는 코드를 작성하고자 한다면

다음과 같이 사용할 수 있다.


xxxx.m

..... 이상 생략 ....

KeepAttribute *m1 = _button_m1.keepTopInset;

KeepAttribute *m2 = _button_m2.keepTopInset;

KeepAttribute *m3 = _button_m3.keepTopInset;

KeepAttribute *m4 = _button_m4.keepTopInset;

        

m1.equal = KeepRequired(90.0); //속한 뷰의 상단에서부터 90pt 간격을 가진다.

m2.equal = KeepRequired(150.0); //속한 뷰의 상단에서부터 150pt 간격을 가진다.

m3.equal = KeepRequired(200.0); //속한 뷰의 상단에서부터 200pt 간격을 가진다.

m4.equal = KeepRequired(300.0); //속한 뷰의 상단에서부터 300pt 간격을 가진다.

..... 이하 생략 .....


* iOS 6.0 부터 허용되는 형태의 코드로 작성되었습니다.

변경하고자 하는 오토레이아웃의 속성을 지정하여 KeepAttribute 라는 객체를 생성한다.

위의 코드에서는 최상단으로부터 떨어진 공간을 조정하기 위해 KeepTopInset메서드를 사용하였다.

넓이나 다른 속성 역시 위와같은형태로 사용하면 된다.

이렇게  KeepAttribute 객체를 생성후 해당 객체에 값을 넣어주면된다.

KeepRequired 등은 오토레이아웃 에서 Priority 값을 가지고 있는 메서드다 Required는 1000에 해당되고 그보다 낮은 high low 등도 존재한다.


이외 더욱 자세한 사항은 깃허브 페이지를 참조하면 된다.




Posted by 하품 - yawn 하품 - yawn