https://colorscripter.com/
'개발 > 기타' 카테고리의 다른 글
이클립스 Eclipse 와 git 서버 연동 (0) | 2017.10.27 |
---|---|
윈도우7(windows7) 다른프로그램을 클릭해도 화면 갱신되지 않으면( explorer.exe 재실행) (0) | 2016.11.14 |
개발언어 순위 확인하기 (0) | 2016.04.07 |
국가코드 (0) | 2016.04.07 |
이클립스 콘솔창 전환 막기 (0) | 2016.04.01 |
https://colorscripter.com/
이클립스 Eclipse 와 git 서버 연동 (0) | 2017.10.27 |
---|---|
윈도우7(windows7) 다른프로그램을 클릭해도 화면 갱신되지 않으면( explorer.exe 재실행) (0) | 2016.11.14 |
개발언어 순위 확인하기 (0) | 2016.04.07 |
국가코드 (0) | 2016.04.07 |
이클립스 콘솔창 전환 막기 (0) | 2016.04.01 |
좋은 포스팅에대한 저장용 자료 입니다.
원문 블로그: http://mainia.tistory.com/4397
요즘 자료를 다운 받기 위해서는 대부분 GitHub 에서 받아야 합니다. 이것도 유행이 있는 것 같습니다. 이전 CSV 에서 SVN을 거쳐 Git 까지 오게 된 것입니다. 간단한 소스를 다운 받으려고 해도 대부분 GitHub 를 이용해야 되는 실정입니다. 오늘은 이클립스로 작업하실 때 어떤 식으로 GitHub 을 통해서 자료를 받을 수 있는지 알아 보도록 하겠습니다.
▼ 만약 자료를 받으라고 링크한 사이트가 GitHub 라면 어떻게 해야 할까요? 우선 알려준 사이트로 접속한 뒤 URI 를 알아야 합니다. URL 이 아니고 URI 입니다. 보통 레파지토리 서버로 접속할 때는 URI 주소를 사용합니다. 자세한 설명은 하지 않겠습니다. URL 의 좀더 큰 개념을 URI 라고 생각하시면 됩니다. GitHub 에서 URI 주소는 HTTPS 버튼 바로 옆 에디터 박스 안에 있습니다. 해당 주소를 복사합니다.
▼ 만약 git 을 통해서 다운로드 받지 않고 압축파일로 전체 프로젝트 파일을 받을 수도 있습니다. HTTPS 주소 제일 왼쪽에 Download ZIP 버튼을 누르면 다운로드가 가능합니다.
◎ 이클립스에서 Git 을 통해 파일 다운 받기 |
▼ 일단 이클립스에 Git 플러그인이 깔려 있다는 전제하에서 작업을 하겠습니다. 현재 사용하는 버전이 Mars 이면 기본적으로 깔려 있습니다. 그럼 작업을 해 볼까요? 오른 마우스를 눌러 Import 메뉴를 선택합니다.
▼ Import 목록에서 Git > Projects from Git 메뉴를 선택합니다. Git 클라이언트 프로젝트를 만들어서 서버 주소에 해당하는 파일을 전부 내려 받기 위해서 입니다.
▼ 두 번째 단계에서는 로컬 PC 에 받아 놓은 파일이냐? 아니면 URI 주소를 통해 받을 것이냐를 결정하게 됩니다. [Clone URI] 를 선택하고 Next 버튼을 눌러 줍니다.
▼ 세 번째 단계에서는 Github 에서 다운받을 파일의 주소를 복사한 후 팝업창 URI 란에 넣어 줘야 합니다. 그럼 나머지 Host 와 Repository path 는 자동으로 들어갑니다. 만약 접속이 안 된다면 Connection 의 Protocol 이 틀렸을 수도 있습니다. HTTPS 인지 다시 한번 확인해 보세요.
▼ 서버에 제대로 접속했다면 파일들이 버전 별로 나타납니다. 처음에는 어떤 것인지 모르기 때문에 모두 체크하고 받습니다.
▼ 다음은 서버에서 받은 파일을 저장할 공간에 대한 설정입니다. 프로젝트가 모여 있는 곳이 관리하기 편하겠죠. Browse 버튼을 눌러 다운받을 곳을 지정한 후 다음으로 넘어 갑니다.
▼ 마지막으로 기존에 존재하는 프로젝트에 포함할 것인지 아니면 새로 만들 것인지 묻는 단계가 나옵니다. 제일 아래에 있는 Import as general project 를 선택해서 새로 추가합니다.
▼ 단계가 끝나면 프로젝트가 생성되고 서버에서 파일을 다운받게 됩니다. 아래 그림은 다운로드를 완성한 후의 모습입니다. 이상으로 이클립스에서 GitHub 에 있는 내용을 Git 플러그인으로 다운로드 받는 방법에 대해 알아 보았습니다.
출처: http://mainia.tistory.com/4397 [녹두장군 - 상상을 현실로]
블로그에 코드작성하기 좋게 복사붙여넣는 사이트 (0) | 2017.12.12 |
---|---|
윈도우7(windows7) 다른프로그램을 클릭해도 화면 갱신되지 않으면( explorer.exe 재실행) (0) | 2016.11.14 |
개발언어 순위 확인하기 (0) | 2016.04.07 |
국가코드 (0) | 2016.04.07 |
이클립스 콘솔창 전환 막기 (0) | 2016.04.01 |
모니터를 4개까지 늘리고난후에 가끔 발생하는 현상이있습니다.
이클립스를 사용하다 인터넷 검색을하려고 크롬을 키면 크롬화면이 화면위로 올라오지 않는일이 발생하네요.
이클립스를 옆으로이동시키면 크롬화면이 아래에있는게 보이는데요.
이러한 현상이 나타나는건 윈도우 explorer.exe 프로세스가 제역활을 하지못했기때문입니다.
컴퓨터를 제부팅하여도 해결되지만 매번제부팅할수는없죠 ㅎ
작업관리자 실행 -> 프로세스탭 -> explorer.exe 프로세스강제종료 ->파일 -> 새작업 -> C:\Windows\explorer.exe
위방법으로 explorer.exe만 다시실행하면 정상작동합니다.
explorer.exe를 종료하면 윈도우 상태표시줄 화면이 사라지는데요 당확하지말고 작업관리자 메뉴의 새작업을 이용하세요 ~
블로그에 코드작성하기 좋게 복사붙여넣는 사이트 (0) | 2017.12.12 |
---|---|
이클립스 Eclipse 와 git 서버 연동 (0) | 2017.10.27 |
개발언어 순위 확인하기 (0) | 2016.04.07 |
국가코드 (0) | 2016.04.07 |
이클립스 콘솔창 전환 막기 (0) | 2016.04.01 |
저는 기술서적을 다른사람한테 추천하는경우가 거이없습니다.
디자인패턴, 리팩토링등의 책을 사서보라고는해도 정확히 어떤책을 사서보라고는 하지않죠
책을사서 보는이유는 개념이해나 신기술등을 미리알고있기 위해서 책을 읽는경우가많고
관련해서 사용할때는 책에서는 이론이나 약간의개념만보고 인터넷이나 API문서 또는 직접해보면서 알게되는게 더많기 때문인데요.
(관련내용도 잘모르고 이해도잘못한사람이 번역만 한책도 많기도하구요..
책내용이 너무부실하면 목자만 보고 인터넷으로 검색해서 따로공부하기도 합니다.)
오랜만에 기본서적을 다시 쭉 읽어보려고 정하고
자주가는 카페에서 판매중인책인 (http://cafe.naver.com/javachobostudy)
JAVA의 정석이란 책을사서 보았는데
꼼꼼하게 정리했을뿐아니라
필자가 독자의 이해를 쉽게하기위해 많은부분을 고민하면서 썻다는게 느껴지더라구요.
얼마나 많은 시간을 이책을 집필하기위해 보냈는지 느껴지더라구요..
개인적으로 개발에대해 가르쳐줄떄 기본서적이나 기술서적등을 보고 어떻게 설명하는게 이해가쉬울지 연구해본경험이 있어서 책을 적게읽지는 않았다고 생각하는 편인데도 이책을 정독하니 놓친부분들이 보이네요..;;
float, double의 정밀도 자리수라던지
10진수에서는 무한대가아닌데 2진수로 변환할때 무한대가발생해서
결과가 무한대로 나올수있다든지에대해서는
책을다시 읽으면서 알게된내용입니다.
책제목은 JAVA의 정석이고
남궁성님이 저자이신 책입니다.
http://cafe.naver.com/javachobostudy
저자님이 직접운영중인 카페시고 관련답변도 매번친절하게 달아주시네요..
사실 자바가 주언어인 사람들한테는 유명한카페이기도하고 자바관련 스터디모임을 구할때도 자주사용하는 카페죠.
개발은 기본의응용이니 이렇게 잘만들어진 기본서적하나는 꼼꼼히 읽어보는것도 도움이 될거같아요.
자바(JAVA) 기본형 (0) | 2016.05.30 |
---|---|
JAVA로 테이블(table)의 기본키 컬럼정보가져오기 (PrimaryKey, pk) (0) | 2016.05.29 |
[디자인패턴] 디자인패턴이란? (0) | 2016.04.08 |
[디자인패턴]singleton(싱글턴, 싱글톤) 이란? (1) | 2016.04.07 |
자바에서의 volatile 키워드 (0) | 2016.04.07 |
변수타입 | 설명 | 기본값 | 리터럴 접미사 | 변수의 범위 | byte | 정밀도 |
boolean | true와 false중에 하나만 저장 | FALSE | false, true | 1 | ||
char | 유니코드(Unicode) 한문자 저장 | '\u0000' | \u0000~\uffff (0~65,535) | 2 | ||
byte | 정수값을 저장 | 0 | -128~127 | 1 | ||
short | 0 | -32,768~32,767 | 2 | |||
int | 0 | -2,147,483,648~2,147,483,647 | 4 | |||
long | 0L | L , l | -9223372036854775808~9223372036854775807 | 8 | ||
float | 실수값을 부동소수점으로 저장 | 0.0f | f, F | 1.4E-45~3.4028235E38 | 4 | 7자리 |
double | 0.0d | d, D, 생략가능 | 4.9E-324~1.7976931348623157E308 | 8 | 15자리 | |
참조형 | 객체의 주소를 저장 | null | 0x0~0xffffffff | 4 |
자바 기본 공부서적 추천 (0) | 2016.05.30 |
---|---|
JAVA로 테이블(table)의 기본키 컬럼정보가져오기 (PrimaryKey, pk) (0) | 2016.05.29 |
[디자인패턴] 디자인패턴이란? (0) | 2016.04.08 |
[디자인패턴]singleton(싱글턴, 싱글톤) 이란? (1) | 2016.04.07 |
자바에서의 volatile 키워드 (0) | 2016.04.07 |
만능유틸을 만들다보니까 java로 DB테이블의 키본키정보를 가져와야할 필요가 생겼습니다.
관련 제공방법을 찾아보니 인터넷에 예제소스가 있더군요.
우선찾은 소스인데 실험해보니
public static Set<String> getPrimaryKeyColumnsForTable(Connection connection, String tableName) throws SQLException {
try(ResultSet pkColumns= connection.getMetaData().getPrimaryKeys(null,null,tableName);) {
SortedSet<String> pkColumnSet = new TreeSet<>();
while(pkColumns.next()) {
String pkColumnName = pkColumns.getString("COLUMN_NAME");
Integer pkPosition = pkColumns.getInt("KEY_SEQ");
out.println(""+pkColumnName+" is the "+pkPosition+". column of the primary key of the table "+tableName);
pkColumnSet.add(pkColumnName);
}
return pkColumnSet;
}
CD_ONTOLOGY is the 3. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
CD_ONTOLOGY is the 3. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
CD_ONTOLOGY_ANALYSIS is the 4. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
CD_ONTOLOGY_ANALYSIS is the 4. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
ID_ARA_ANAL_DOC is the 1. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
ID_ARA_ANAL_DOC is the 1. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
NB_LINE is the 2. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
NB_LINE is the 2. column of the primary key of the table TB_ARA_DOC_ONTOLOGY
이런식으로 결과가 여러번찍히게 됩니다.
위예제소스로는 순서정보가 다르게 넘어올때는 정렬되지 않는 컬럼정보를 넘겨주게되있더군요.
그래서 기본키컬럼정보및 순서정보를 map으로 넘기게 조금변형햇습니다.
중복된 값이 있기때문에 Set이나 Map등 중복을 허용하지 않는 클래스사용이 좋아보이네요
public static Map<String, Integer> getPrimaryKeyColumnsForTable(Connection connection, String tableName) throws SQLException {
try(ResultSet pkColumns= connection.getMetaData().getPrimaryKeys(null,null,tableName);) {
Map<String, Integer> pkMap = new HashMap<String, Integer>();
while(pkColumns.next()) {
String pkColumnName = pkColumns.getString("COLUMN_NAME");
Integer pkPosition = pkColumns.getInt("KEY_SEQ");
pkMap.put(pkColumnName, pkPosition);
}
return pkMap;
}
}
컬럼정보와 컬럼의 순서정보를 맵정보로 넘겨주는 예제소스입니다.
예제소스를 그대로 사용하기보다는 개발상황에맞게 예외상황 코드를적절히넣어서 사용하는게 좋아보입니다.
위소스에는 사용한 ResultSet pkColumns 부분을 pkColumns.close시키는부분이나 connection.close부분이없으니
관련 부분은 개발환경에맞게 예외상황처리를해주세요.
예를들면:)
public static Map<String, Integer> getPrimaryKeyColumnsForTable(Connection conn, String tableName) {
ResultSet pkColumns= null;
Map<String, Integer> pkMap = new HashMap<String, Integer>();
try{
pkColumns= conn.getMetaData().getPrimaryKeys(null,null,tableName);
while(pkColumns.next()) {
String pkColumnName = pkColumns.getString("COLUMN_NAME");
Integer pkPosition = pkColumns.getInt("KEY_SEQ");
pkMap.put(pkColumnName, pkPosition);
}
}catch( java.sql.SQLException se){
//예외상황 로그남기기 또는 특수처리등
}catch(Exception e){
//기타예외상황 로그남기기 또는 특수처리등
}finally{
try{if(pkColumns!=null)pkColumns.close(); pkColumns=null; }catch(Exception e){}
}
return pkMap;
}
이런식으로 작성하는게 좋을것같네요,
위기능은 jre1.7(jdk1.7)이상부터 지원합니다.
자바 기본 공부서적 추천 (0) | 2016.05.30 |
---|---|
자바(JAVA) 기본형 (0) | 2016.05.30 |
[디자인패턴] 디자인패턴이란? (0) | 2016.04.08 |
[디자인패턴]singleton(싱글턴, 싱글톤) 이란? (1) | 2016.04.07 |
자바에서의 volatile 키워드 (0) | 2016.04.07 |
데이터를 셀렉트할떄 아래방법대로 rowid를 추가해서 셀렉트하면
update구문을 만들지않아도 바로 업데이트할 수 있습니다,
SELECT rowid, A.*
FROM EMP A;
위사진은 rowid를 추가해서 쿼리를 보내면 grid에 데이터가 보이는결과입니다
여기에 고치고자하는 컬럼위치에가서 데이터를 수정하고
노란섹으로 동그라미 되어있는 V버튼을 클릭하고 commit명령을 전달하면 바로 업데이트 됩니다.
토드를 사용하는 입장에서 편리한 기능이라 공유해요~
[oracle] select, view 전용계정관리, 테이블 권한 시노님(synonym) 생성 (0) | 2016.05.09 |
---|---|
유저테이블 전체정보 조회(테이블 컬럼 전체정보) (0) | 2016.04.07 |
오라클 테이블 스페이스 변경 (테이블, 인덱스) (0) | 2016.04.07 |
오라클 테이블용량산정(DBA) (0) | 2016.04.07 |
오라클 휴지통 비우기/복원 (0) | 2016.04.07 |
특정테이블 조회를위한
뷰전용계정 생성
create user view계정 identified by view계정패스워드
뷰전용계정 권한
GRANT connect ,create synonym to view계정
이하내용은 잘정리된 포스팅이 있어서 퍼왔습니다.
출저:http://annehouse.tistory.com/424
1. 테이블 조회 권한 주기 [SELECT]
GRANT select ON 권한을줄테이블명 TO 권한을 받을 사용자계정; |
1) scott이라는 계정과 alex라는 계정이 있는 경우, alex에게 scott의 EMP테이블 SELECT 권한을 줄때는 아래와 같이 하면된다.
a. scott 계정으로 접속 [sqlplus scott/비번]
b. GRANT select ON EMP TO alex;
2. 테이블 입력이나 수정 삭제의 권한을 부여 [INSERT , UPDATE , DELETE ]
GRANT INSERT , UPDATE , DELETE ON 권한을주려는테이블 TO 권한 받을사용자계정 |
a. scott 계정으로 접속 [sqlplus scott/비번]
b. GRANT INSERT , UPDATE , DELETE ON EMP TO alex;
3. FUNCTION 실행 권한 주기 [execute]
GRANT execute ON 권한을 줄 함수명 TO 권한을 받을 사용자계정; |
===========================> 여기 까지 처리한 경우,
alex계정에서 select * from scott.EMP;와 같이 접근이 가능하다.
그냥, scott.을 안붙이고 조회하고 싶은 경우, 아래와 같이 synonym을 생성해주면 된다.
3. synonym 생성
CREATE SYNONYM 시노님명 FOR 계정명.테이블명 |
CREATE SYNONYM 시노님명 FOR 계정명.함수명 |
a. alex 계정으로 접속 [sqlplus alex/비번]
b. CREATE SYNONYM EMP FOR SCOTT.EMP;
===========================> 여기 까지 처리한 경우,
alex계정에서 select * from EMP;와 같이 접근이 가능하다.
TOAD에서 셀렉트한 데이터를 edit창에서 업데이트 하기 (0) | 2016.05.12 |
---|---|
유저테이블 전체정보 조회(테이블 컬럼 전체정보) (0) | 2016.04.07 |
오라클 테이블 스페이스 변경 (테이블, 인덱스) (0) | 2016.04.07 |
오라클 테이블용량산정(DBA) (0) | 2016.04.07 |
오라클 휴지통 비우기/복원 (0) | 2016.04.07 |
디자인 패턴이라고하면 특별한 상황에 이렇게 하는게 좋더라 라고 패턴화된 내용입니다.
객체가 하나만 생성되고 생성된 객체를 같이써야할때는 싱글턴
객체의 내용변화를 감시해야할때는 옵저버패턴
이미사용중인 소스의 메소드명 클래스명을 변경하고싶을때는 아답터패턴등이 예입니다.
디자인패턴은 말그대로 그상황에 이렇게 코딩하는 하나의 패턴을 얘기하므로
개발자분들이 이런상황에서 이렇게쓰고있는 패턴이있으면 그것또한 하나의 디자인패턴입니다.
아직이름이 알려져있지 않을뿐이죠.
디자인패턴을 책에 나오는 그대로쓰는경우도 있지만 상황에 맞게 변형해서 쓰는 경우가 더많습니다.
우리보다 선대개발자들은 이런상황에서 이렇게 개발했다고 잘정의해놓은 개발자 필수공부 내용이니까
꼭 공부해보길바래요~
아래는 OOP와 디자인패턴의 관계를 잘설명해놓은 포스팅이있어서 퍼왔어요
http://blog.naver.com/2feelus/220642212134
자바 OOP와 디자인 패턴 - Java OOP and Design Pattern
1. OOP 란?
Object Oriented Programming은 프로그래밍 방법론으로 기존의 절차적, 파일단위의 프로그래밍 스타일에서,
완전히 분리된 프로그래밍의 단위인 Object(객체)라는 개념을 가지고 와서 프로그래밍의 방법을 객체간의 소통의 개념으로 가져왔다.
사실상 우리가 보는 세계는 많은 것들이 분리된 단위로 떨어져 독립적으로 존재하고, 커다란 객체는 여러 객체의 조합으로 나타낼 수 있다.
이런 객체의 개념은 아래의 몇단어로 상징적으로 표현된다.
1) abstraction (추상화)
- 여러 객체들의 공통된 특성을 묶어 상위개념으로 표현하는 것 : 예 ) 남자 와 여자의 추상적 객체 = 사람
2) Polymorphism (다형성)
- 객체를 표현하는 다양한 방식이 존재할수 있다. 예) 자식객체는 자식객체와 부모객체, 혹은 인터페이스로서 참조할수 있다.
3) Encapsulation(캡슐화, 은닉화)
- 숨길 부분과 밖으로 드러낼 부분을 조절할수 있다. 예) private 필드
4) Inheritance (상속성)
- 부모객체를 상속해서 자식객체를 만들수 있다 예) extends 키워드
자세한 설명은 인터넷에 좋은 설명들이 많다.
2. Java와 OOP
Java에서 OOP(객체지향 프로그래밍)은 뗄래야 땔수 없는 이름표와 같다. Java가 OOP의 원조는 아니지만 현재 지구상에서 가장 많은 사람들이 사용하는 객체지향언어이다. 다른 OOP언어로서 대표적으로 C++, LISP, C#,Scala등의 OOP를 기반으로 태어난 언어들, 그리고 여러 스크립트 언어들도 최신버전에서는 OOP의 개념을 지원한다. (PHP, Python,ruby등...)
3. Java은 완벽한 OOP인가?
자바는 '거의' 완벽한 OOP이다. 약간은 OOP에 부족한 면이 있다는 뜻이다.
OOP의 개념중에는 multiple inheritance(다중상속)이라는 개념이 존재한다. 관계가 없는 두 클래스를 상속해서 자식클래스를 만드는 것을 뜻한다.
c++나 LISP, scala등에서는 다중상속을 지원하지만, java나 C#은 이를 지원하지 않는다. 그 이유는 다중상속은 같은 이름을 가진 부모클래스의 메소드들에 대해 어떤 것을 선택할 것인지 애매하기 때문이다. 이는 생성자에 대해서도 마찬가지이다. 이런 모호성(ambiguity)는 좀더 명확한 의미를 가진 클래스디자인을 힘들게 하는 요인이기도 하다. 그래서 언어에 따라 다중상속을 지원하지 않는 경우가 존재하다. 자바의 경우는 강한 타입 캐스팅을 통해, 실제 수행전에 에러를 잡는데에 최적화된 언어이므로, 이를 위해서 가능한 모호함의 요소들은 제외를 하고자 했다. 그래서 자연스럽게 다중상속성은 포기하게 되었다. (1995년에 Java:an Overview" 라는 글에서 자바의 아버지인 James Gosling이 의견을 밝혔다). 앞으로 나올자바에서도 다중상속이 지원될 확률은 거의 없다고 볼수 있다.
주) 참고로 Java 8에서는 Interface 의 default method라는 방식으로 우회적으로 다중상속과 비슷한 방식을 지원하기는 한다. 하지만 이것 또한 진정한 의미의 다중상속은 아니다. 링크참고
4. 디자인 패턴 (Design Patterns) 이란?
오랜동안 많은 사람들에 의해 좋다고 검증된 프로그래밍 패턴. 사람들이 수많은 시간동안 프로그램으로 여러 형태의 문제들을 해결해왔는데,
문제의 타입별로 해결하기 좋은 프로그래밍 패턴들이 있다는 것이 알려졌고, 여기에 이름들이 붙여졌다. 주로 많이 알려진 디자인 패턴은 아래와 같다.
1) 생성 패턴
- 빌더 패턴
- 싱글톤 패턴
2) 구조 패턴
- 어댑터 패턴
- 브리지 패턴
- 컴포지트 패턴
- 데코레이터 패턴
- 파사드 패턴
- 프록시 패턴
3) 행위패턴
- 책임 연쇄 패턴
- 반복자 패턴
- 중재자 패턴
- 전략 패턴
- 커맨드 패턴
- 방문자 패턴
- 인터프리터 패턴
- 메멘토 패턴
- 옵저버 패턴
- 상태 패턴
5. 객체 지향과 디자인 패턴의 관계
디자인 패턴이란 용어자체는 OOP와 직접적인 관련은 없다. 디자인 패턴이라는 말 자체는 어떤 프로그래밍 방법론에도 사용될 수 있다.
그러나 OOP라는 프로그래밍 방식은 Design Pattern이라는 프로그래밍 방식과 매우 잘 어울리며 실제로 거의 함께 쓰이곤 하는 용어이다. 그 이유는 객체(Object)라는 개념이 가진 "변화적인 성질(변이성)" 때문이다. 일반적으로 객체라는 것은 때에 따라 생성되고, 객체의 성질이나 값을 부여받고, 스스로 일들을 수행하고, 다른 객체에게 값을 전달해준뒤, 소멸한다. 즉 메모리에 태어났다가, 변경되고, 소멸된다. 이런 변이성은 Design Pattern에서 가장 많이 언급되는 아래의 방법론과 매우 잘 어울린다.
생성패턴 = 객체의 생성에 대한 방법
구조패턴 = 객체와 객체 사이의 상속/조합 관계설정 방법
행위패턴 = 객체가 특정 행동을 함으로서 다른 객체에 값을 전달하는 방법
사실 디자인 패턴이라는 말이 유명해진 계기가 GOF(Gang Of Four - 4명의 깡패들) 이라는 사람들이
Design Patterns: Elements of Reusable Object-Oriented Software
이라는 책을 내면서 Design Pattern이라는 용어가 급부상해서, 이제는 Design Patterns이라고 하면 OOP를 빼놓고 얘기할 수가 없게 된것이다.
책의 제목에서 Reusable 이라는 말에 주목할 필요가 있다. 디자인 패턴은 효율적이며 가독성이 높은 코드를 지향할 뿐 아니라,
항상 재사용성이 높은 코드를 염두에 두고 있다는 부분이다. 절차적 프로그래밍에서도 효율적이며 가독성이 높을수는 있지만, OOP에서의 디자인 패턴은 재사용성과 그를 바탕으로한 관리용이성 또한 염두를 두고 있다.
자바(JAVA) 기본형 (0) | 2016.05.30 |
---|---|
JAVA로 테이블(table)의 기본키 컬럼정보가져오기 (PrimaryKey, pk) (0) | 2016.05.29 |
[디자인패턴]singleton(싱글턴, 싱글톤) 이란? (1) | 2016.04.07 |
자바에서의 volatile 키워드 (0) | 2016.04.07 |
어노테이션(Annotation) (0) | 2016.04.07 |
프로그래밍 세계에 OOP 의 개념이 생기면서 객체 자체에 대한 많은 연구와 패턴(pattern)들이 생겨났다. singleton pattern은 인스턴스가 사용될 때에 똑같은 인스턴스를 만들어 내는 것이 아니라, 동일 인스턴스를 사용하게끔 하는 것이 기본 전략이다. 프로그램상에서 동일한 커넥션 객체를 만든다던지, 하나만 사용되야하는 객체를 만들때 매우 유용하다. singleton pattern은 4대 디자인 패턴에 들어갈 정도로 흔히 쓰이는 패턴이다. 물론 core java(java.lang.Runtime, java.awt.Desktop 등등)에서도 singleton pattern이 사용된다.
아래가 가장 기본적인 singleton pattern이다. 전역 변수로 instance를 만드는데 private static
을 이용한다. static
이 붙은 클래스변수는 인스턴스화에 상관없이 사용이 가능하게 된다. 하지만 앞의 private
접근제어자로 인해 EagerInitialization.instance
로의 접근은 불가능하다. 이런 상태에서 생성자를 private
로 명시한다. 생성자를 private
로 붙이게되면, new
키워드를 사용할 수 없게된다. 즉 다른 클래스에서 EagerInitialization instance = new EagerInitialization();
이런 방법을 통한 인스턴스 생성은 불가능해진다. 결국 외부 클래스가 EagerInitialization 클래스의 인스턴스를 가질 수 있는 방법은 11번째 라인에 있는 getInstance()
method를 사용하는 수 밖에 없다.
public class EagerInitialization {
// private static 로 선언.
private static EagerInitialization instance = new EagerInitialization();
// 생성자
private EagerInitialization () {
System.out.println( "call EagerInitialization constructor." );
}
// 조회 method
public static EagerInitialization getInstance () {
return instance;
}
public void print () {
System.out.println("It's print() method in EagerInitialization instance.");
System.out.println("instance hashCode > " + instance.hashCode());
}
}
위의 단순한 singleton pattern은 리소스가 작은 프로그램일때엔 고도화 대상이 아니다. 하지만 프로그램의 크기가 커져서 수 많은 클래스에서 위와 같은 singleton pattern을 사용한다고 가정해보자. 3번째 라인의 new EagerInitialization();
으로 인해 클래스가 load 되는 시점에 인스턴스를 생성시키는데 이마저도 부담스러울 수가 있다. 또한 이 소스는 EagerInitialization 클래스가 인스턴스화 되는 시점에 어떠한 에러처리도 할 수가 없다.
public class StaticBlockInitalization {
private static StaticBlockInitalization instance;
private StaticBlockInitalization () {}
static {
try {
System.out.println("instance create..");
instance = new StaticBlockInitalization();
} catch (Exception e) {
throw new RuntimeException("Exception creating StaticBlockInitalization instance.");
}
}
public static StaticBlockInitalization getInstance () {
return instance;
}
public void print () {
System.out.println("It's print() method in StaticBlockInitalization instance.");
System.out.println("instance hashCode > " + instance.hashCode());
}
}
static
초기화블럭을 이용하면 클래스가 로딩 될 때 최초 한번 실행하게 된다. 특히나 초기화블럭을 이용하면 logic을 담을 수 있기 때문에 복잡한 초기변수 셋팅이나 위와 같이 에러처리를 위한 구문을 담을 수 있다. 첫 번째 패턴보다 좋아보이지만 인스턴스가 사용되는 시점에 생성되는 것은 아니다.
이제 클래스 인스턴스가 사용되는 시점에 인스턴스를 만드는 singleton pattern을 배워보도록 하자. 아래 소스의 lazy initialization pattern은 필요할때 인스턴스를 생성시키는 것이 핵심이다.
public class LazyInitialization {
private static LazyInitialization instance;
private LazyInitialization () {}
public static LazyInitialization getInstance () {
if ( instance == null )
instance = new LazyInitialization();
return instance;
}
public void print () {
System.out.println("It's print() method in LazyInitialization instance.");
System.out.println("instance hashCode > " + instance.hashCode());
}
}
new LazyInitialization();
가 어디에 선언되었는지 주목해보자. getInstance()
method 안에서 사용되었다. if문을 이용해 instance가 null 인 경우에만 new
를 사용해 객체를 생성하였다. 최초 사용시점에만 인스턴스화 시키기 때문에 프로그램이 메모리에 적재되는 시점에 부담이 많이 줄게된다. 하지만 여전히 문제는 남아있다. 만약 프로그램이 muilti thread 방식이라면 위와 같은 singleton pattern은 안전하지 않다. 동일 시점에 getInstance()
method를 호출하면 인스턴스가 두번 생길 위험이 있다.
위에서 문제가 되었던 muilit thread문제를 해결하기 위해 synchronized(동기화)를 사용하여 singleton pattern을 구현한다. 여러 thread들이 동시에 접근해서 인스턴스를 생성시키는 위험은 없어졌다. 하지만 수 많은 thread 들이 getInstance()
method 를 호출하게 되면 높은 cost 비용으로 인해 프로그램 전반에 성능저하가 일어난다.
public class ThreadSafeInitalization {
private static ThreadSafeInitalization instance;
private ThreadSafeInitalization () {}
public static synchronized ThreadSafeInitalization getInstance () {
if (instance == null)
instance = new ThreadSafeInitalization();
return instance;
}
public void print () {
System.out.println("It's print() method in ThreadSafeInitalization instance.");
System.out.println("instance hashCode > " + instance.hashCode());
}
}
미국 메릴랜드 대학의 컴퓨터 과학 연구원인 Bill pugh 가 기존의 java singleton pattern이 가지고 있는 문제들을 해결 하기 위해 새로운 singleton pattern을 제시하였다. Initialization on demand holder idiom기법이다. 이것은 jvm 의 class loader의 매커니즘과 class의 load 시점을 이용하여 내부 class를 생성시킴으로 thread 간의 동기화 문제를 해결한다.
public class InitializationOnDemandHolderIdiom {
private InitializationOnDemandHolderIdiom () {}
private static class Singleton {
private static final InitializationOnDemandHolderIdiom instance = new InitializationOnDemandHolderIdiom();
}
public static InitializationOnDemandHolderIdiom getInstance () {
System.out.println("create instance");
return Singleton.instance;
}
}
initialization on demand holder idiom 역시 lazy initialization이 가능하며 모든 java 버젼과, jvm에서 사용이 가능하다. 현재 java 에서 singleton 을 생성시킨다고 하면 거의 위의 방법을 사용한다고 보면 된다.
Joshua Bloch가 작성한 effective java 책에서 enum singleton 방법이 소개 되었다.
public enum EnumInitialization {
INSTANCE;
static String test = "";
public static EnumInitialization getInstance() {
test = "test";
return INSTANCE;
}
}
enum 이 singleton pattern 으로 사용될 수 있는 이유는 아래와 같다.
위에서 여러 방법으로 singleton을 만들어 보았으니 이번엔 java의 reflection을 이용하여 singleton을 깨뜨려 보는법도 배워보자. 누군가 작성한 코드를 원본 수정없이 작업해야 할때 이용될 수 있을 것이다.
public class UsingReflectionToDestroySingleton {
public static void main (String[] args) {
EagerInitialization instance = EagerInitialization.getInstance();
EagerInitialization instance2 = null;
try {
Constructor[] constructors = EagerInitialization.class.getDeclaredConstructors();
for ( Constructor constructor : constructors ) {
constructor.setAccessible(true);
instance2 = (EagerInitialization)constructor.newInstance();
}
} catch (Exception e) {
}
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
}
}
위의 코드를 실행해보면 아래 System.out.println();
의 두 라인에서 찍히는 hachCode()
값이 다른 것을 확인 할 수 있다. java의 reflection은 매우 강력하다. 설령 class 의 생성자가 private 일지라도 강제로 가져와서 새로운 인스턴스 생성이 가능하다. 결국 singleton pattern을 깨뜨리는 것이다. 이 외에도 reflection을 여러곳에서 사용할 수 있으니 알아두는 것이 좋다.
자바(JAVA) 기본형 (0) | 2016.05.30 |
---|---|
JAVA로 테이블(table)의 기본키 컬럼정보가져오기 (PrimaryKey, pk) (0) | 2016.05.29 |
[디자인패턴] 디자인패턴이란? (0) | 2016.04.08 |
자바에서의 volatile 키워드 (0) | 2016.04.07 |
어노테이션(Annotation) (0) | 2016.04.07 |