1. 메뉴 화면
처음 egov 상의 eclipse 를 실행하면 아래와 같이 기존 메뉴에
합치기 애매한 내용이 eGovFrame 이라는 메뉴로 구성되어 있습니다.
2. 각 기능 설명
1) Start
eGovFrame 에 포함된 quick starter 정도로 이해하면 됩니다.
템플릿 프로젝트의 경우 웹 사이트중 일부 기능이 포함된
형태로 시작이 가능합니다.
어차피 UI는 구리지만 공짜입니다. 이걸로 상품을 만들려면
UI는 차별화 해야하기 때문에 기능 공부용으로는
좋습니다.
프로젝트 생성 후 Implement Add Common Component
기능을 통해 프로젝트에 일부 기능을 추가가능합니다.
db가 있는경우 해당 db에 테이블이 추가되고
없는 경우 소스만 생성 가능합니다.
2) Analysis
프로젝트 안에 usescase Diagram 문서를 추가해주는 역할
을 합니다.
3) Design
Diagram을 추가하는 메뉴입니다.
4) Implementation
batch를 비롯해서 기능 추가시 사용하는 메뉴입니다.
5) Test
batch test 파일 생성 메뉴입니다.
6) Configuration
소스관리 등 구성에 관련된 메뉴입니다.
2015년 10월 8일 목요일
2015년 10월 7일 수요일
Xeplatform 01. 환경 구성
1. 이론
1) RIA(Rich Internet Application) 와 Myplatform
RIA에 대한 위키 설명
플래시 및 RIA 진영에 대한 부정적인 글
결론 : 뭔가 설치를 해야되는 RIA 방식에 대해 회의적이지만
2k 중반 이후 진행되어 성공한 여러 공공 사업 덕택에
쉽고 빠른 툴이라는 인식이 있음.
2. 설치방법
1) Trial 버전 설치
상단 링크로 들어가서 회원가입하고 trial 버전을 다운로드 후
설치하면 끝.
2) db 연동
3)
3. 프로젝트 생성
1) new 프로젝트
new -> project -> 프로젝트명 및 화면 기본 ui 선택 next
-> (문자셋, 언어 등 설정) next
-> (MLM 서브 화면을 등록가능한 메뉴) finish
2) 폴더 구조 확인
4. helloworld 띄우기
1) 화면 추가하기
new -> Item -> form 선택
-> form 이름 입력 next
-> FDL(화면추가한다는 내용임) next
-> 화면 크기 지정 next (여기는 무조건 fixel 단위로만 체크함)
-> (MLM 관련 화면) next
-> (위젯관련 메뉴) finish
2) 실행준비 및 실행
(1) 버튼을 추가
상단 컴포넌트 중 버튼을 클릭 후 장소를 지정하여 생성
(2) 버튼을 선택한 상태에서 우측 Properties 메뉴에서
text 속성을 Hello!! 로 변경
(3) 이벤트 등록 (우측 Propertise 메뉴에서 번개탭선택)
Onclick 항목을 더블 클릭
※ Propertise 버튼의 수정할 수 있는 정보는
속성정보, (번개모양)이벤트, 바인딩정보로 구성됨
(4) 가운데 화면의 script 탭에 함수 하나가 생성되고 그 안에
입력할 수 있도록 셋팅됨.
alert("Hello World!!!");
를 입력
※ 속성은 소문자 검은색, 객체는 앞에 대문자,
함수는 소문자로 시작 붉은색
※ 이벤트 함수 실행시 이벤트 오브젝트 라는
인자가 같이 들어오는데 이벤트관련 부가적인
정보 및 호출 오브젝트 관련 정보가
포함되어 있음.
3) 실행 하기
상단 메뉴중 Quick View (돋보기+번개모양) 를 클릭
작성한 내용을 확인 후(버튼 및 버튼 클릭) 종료.
4) 파일 구조
base 폴더 밑에 아래 화일이 생겼으며 해당 파일을 open시
다음과 같은 내용이 보여짐
1) RIA(Rich Internet Application) 와 Myplatform
RIA에 대한 위키 설명
플래시 및 RIA 진영에 대한 부정적인 글
결론 : 뭔가 설치를 해야되는 RIA 방식에 대해 회의적이지만
2k 중반 이후 진행되어 성공한 여러 공공 사업 덕택에
쉽고 빠른 툴이라는 인식이 있음.
2. 설치방법
1) Trial 버전 설치
상단 링크로 들어가서 회원가입하고 trial 버전을 다운로드 후
설치하면 끝.
2) db 연동
3)
3. 프로젝트 생성
1) new 프로젝트
new -> project -> 프로젝트명 및 화면 기본 ui 선택 next
-> (문자셋, 언어 등 설정) next
-> (MLM 서브 화면을 등록가능한 메뉴) finish
2) 폴더 구조 확인
4. helloworld 띄우기
1) 화면 추가하기
new -> Item -> form 선택
-> form 이름 입력 next
-> FDL(화면추가한다는 내용임) next
-> 화면 크기 지정 next (여기는 무조건 fixel 단위로만 체크함)
-> (MLM 관련 화면) next
-> (위젯관련 메뉴) finish
2) 실행준비 및 실행
(1) 버튼을 추가
상단 컴포넌트 중 버튼을 클릭 후 장소를 지정하여 생성
(2) 버튼을 선택한 상태에서 우측 Properties 메뉴에서
text 속성을 Hello!! 로 변경
(3) 이벤트 등록 (우측 Propertise 메뉴에서 번개탭선택)
Onclick 항목을 더블 클릭
※ Propertise 버튼의 수정할 수 있는 정보는
속성정보, (번개모양)이벤트, 바인딩정보로 구성됨
(4) 가운데 화면의 script 탭에 함수 하나가 생성되고 그 안에
입력할 수 있도록 셋팅됨.
alert("Hello World!!!");
를 입력
※ 속성은 소문자 검은색, 객체는 앞에 대문자,
함수는 소문자로 시작 붉은색
※ 이벤트 함수 실행시 이벤트 오브젝트 라는
인자가 같이 들어오는데 이벤트관련 부가적인
정보 및 호출 오브젝트 관련 정보가
포함되어 있음.
3) 실행 하기
상단 메뉴중 Quick View (돋보기+번개모양) 를 클릭
작성한 내용을 확인 후(버튼 및 버튼 클릭) 종료.
4) 파일 구조
base 폴더 밑에 아래 화일이 생겼으며 해당 파일을 open시
다음과 같은 내용이 보여짐
2015년 10월 5일 월요일
클래스 디자인 패턴 7-2. Facade Pattern_
1. 개념잡기
뭔가 여러가지 기능을 하는 인스턴트들이 있는데 목표로 하는
작업을 위해서 이들 인스턴트의 몇개의 작업이 조합되어야
할때 이를 편하게 묶는 작업정도라고 보면 되겠다.
3. 소스
1) 만들어져 있는 서브 인스턴트들
실제 메서드가 더 많겠지만 watchMovie 메서드를
실행시킬때 에러만 안나게끔 작성함.
여기서 약 8가지 정도되는 인터페이스를 하나의 작업으로
묶어서 관리하고 있다. 이를 퍼사드 패턴으로 보면 됨
3) 테스트 코드
여기서는 팝콘 기계를 켜고 할 필요없이
watchMovie(영화제목) 메서드를 통해서
하단의 여러 메서드를 한번에 실행시킬 수 있음.
3. 다이어그램
뭔가 여러가지 기능을 하는 인스턴트들이 있는데 목표로 하는
작업을 위해서 이들 인스턴트의 몇개의 작업이 조합되어야
할때 이를 편하게 묶는 작업정도라고 보면 되겠다.
3. 소스
1) 만들어져 있는 서브 인스턴트들
실제 메서드가 더 많겠지만 watchMovie 메서드를
실행시킬때 에러만 안나게끔 작성함.
package homeMeterial;
public class Amplifier {
public void on() {
System.out.println("앰프를 켠다.");
}
public void setDvd(DvdPlayer dvd) {
System.out.println("입력단자를 dvd로 연결한다.");
dvd.getInputClient();
}
public void setSurroundSound() {
System.out.println("앰프 모드를 서라운드로 설정한다.");
}
public void setVolumn(int i) {
System.out.println("앰프 음악 볼륨을 조절한다. 볼륨값은 max10중 "+i);
}
}
package homeMeterial;
public class CdPlayer {
}
package homeMeterial;
public class DvdPlayer {
public void getInputClient() {
// TODO Auto-generated method stub
System.out.println("DVD 음향 입력단자를 연결완료");
}
public void on() {
System.out.println("DVD를 켠다.");
}
public void play(String movie) {
System.out.println("DVD로 영화를 플레이한다 영화제목은 :"+movie);
}
}
package homeMeterial;
public class Projector {
public void on() {
System.out.println("프로젝트 on");
}
public void wideScreenMove() {
System.out.println("프로젝트 모드를 와이드 모드로 변환");
}
}
package homeMeterial;
public class PrpcornPopper {
public void on() {
System.out.println("팝콘 기계 on");
}
public void pop() {
System.out.println("팝콘이 튀겨지는걸 감상한다.");
}
}
package homeMeterial;
public class Screen {
public void down() {
System.out.println("스크린을 내린다.");
}
}
package homeMeterial;
public class TheaterLights {
public void dim(int i) {
System.out.println("전등 밝기 조절 밝니는 max100중에 "+i);
}
}
package homeMeterial;
public class Tuner {
}
2) 목표로 하는 작업 인터페이스 작성
묶어서 관리하고 있다. 이를 퍼사드 패턴으로 보면 됨
package runTheater;
import homeMeterial.Amplifier;
import homeMeterial.CdPlayer;
import homeMeterial.DvdPlayer;
import homeMeterial.Projector;
import homeMeterial.PrpcornPopper;
import homeMeterial.Screen;
import homeMeterial.TheaterLights;
import homeMeterial.Tuner;
public class HomeTheaterFacade {
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PrpcornPopper popper;
public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd,
CdPlayer cd, Projector projector, TheaterLights lights,
Screen screen, PrpcornPopper popper) {
this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
this.projector = projector;
this. screen= screen;
this.lights=lights;
this.popper=popper;
}
public void watchMovie(String movie){
System.out.println("집에서 영화를 보려면 이렇게 준비하고 봐야지");
popper.on();
popper.pop();
lights.dim(10);
screen.down();
projector.on();
projector.wideScreenMove();
amp.on();
amp.setDvd(dvd);
amp.setSurroundSound();
amp.setVolumn(5);
dvd.on();
dvd.play(movie);
System.out.println("준비가 끝났으니 영화를 봅시다.");
}
}
3) 테스트 코드
여기서는 팝콘 기계를 켜고 할 필요없이
watchMovie(영화제목) 메서드를 통해서
하단의 여러 메서드를 한번에 실행시킬 수 있음.
package testFacade;
import runTheater.HomeTheaterFacade;
import homeMeterial.Amplifier;
import homeMeterial.CdPlayer;
import homeMeterial.DvdPlayer;
import homeMeterial.Projector;
import homeMeterial.PrpcornPopper;
import homeMeterial.Screen;
import homeMeterial.TheaterLights;
import homeMeterial.Tuner;
public class HomeTheaterTestDrive {
public static void main(String[] args) {
Amplifier amp = new Amplifier();
Tuner tuner= new Tuner();
DvdPlayer dvd=new DvdPlayer();
CdPlayer cd=new CdPlayer();
Projector projector=new Projector();
TheaterLights lights=new TheaterLights();
Screen screen=new Screen();
PrpcornPopper popper=new PrpcornPopper();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, lights , screen, popper);
homeTheater.watchMovie("Prison Breaker");
}
}
3. 다이어그램
php 사용중 이슈들
1. APM 하고 XAMPP 하고는
<?PHP를 승인하거나 안하는 차이점이 있습니다.
(좀더 보완예정)
pmsetup 하다가 갈아탄 xampp
http://phpschool.com/gnuboard4/bbs/board.php?bo_table=qna_function&wr_id=362345&sca=&sfl=mb_id&stx=bihon&sop=and
pmsetup 에서는 <? ~~?>만으로도 php 구문으로 허용하지만
xampp 는 허용하지 않습니다. 여기서는 <?php ~~ ?> 로
명시해 줘야 합니다.
2. 보통 90프로 이상 쿼리 구문 상 에러
mysql_fetch_array() expects parameter 1 to be resource, boolean given in
xampp 문제인지 mysql 문제인지 다른 문제인지 원인은 모르겠지만
테이블명을 표시할 때
꼭 이렇게 명시를 해줘야 했다.
구분해서 작성해줘야 에러가 없었음
<?PHP를 승인하거나 안하는 차이점이 있습니다.
(좀더 보완예정)
pmsetup 하다가 갈아탄 xampp
http://phpschool.com/gnuboard4/bbs/board.php?bo_table=qna_function&wr_id=362345&sca=&sfl=mb_id&stx=bihon&sop=and
pmsetup 에서는 <? ~~?>만으로도 php 구문으로 허용하지만
xampp 는 허용하지 않습니다. 여기서는 <?php ~~ ?> 로
명시해 줘야 합니다.
2. 보통 90프로 이상 쿼리 구문 상 에러
mysql_fetch_array() expects parameter 1 to be resource, boolean given in
xampp 문제인지 mysql 문제인지 다른 문제인지 원인은 모르겠지만
테이블명을 표시할 때
꼭 이렇게 명시를 해줘야 했다.
`pnt_station`테이블명을 둘러산 문자가 ' 가 아니라 ` 이기 때문에
구분해서 작성해줘야 에러가 없었음
2015년 9월 24일 목요일
daum 지도 api key 발급 방법(2015)
사이트가 개편되면서 사용방법이 쉬워졌는데
이전에 설명 페이지를 보고 하려니 잘 안되서 작성함
1. https://developers.daum.net/
2. 상단 메뉴중 서비스를 클릭
3. 좌측의 메뉴 중 지도를 클릭
4. 그러면 새창이 열리고 확인하기를 누른뒤 좌측 메뉴에서
열쇠 모양 아이콘 클릭
5. 앱 만들기 클릭 - 앱 이름 입력
6. 하나의 앱이 만들어지고 하위 메뉴가 뜨는데
그중 api 키를 클릭
7. api 메뉴에서 REST/JS 및 Oauth 두가지 방식이 있는데 REST
선택후
8. 패키지명이나 혹은 웹에서 쓰면 주소 입력하고 엔터
9. api 키 확인
이전에 설명 페이지를 보고 하려니 잘 안되서 작성함
1. https://developers.daum.net/
2. 상단 메뉴중 서비스를 클릭
3. 좌측의 메뉴 중 지도를 클릭
4. 그러면 새창이 열리고 확인하기를 누른뒤 좌측 메뉴에서
열쇠 모양 아이콘 클릭
5. 앱 만들기 클릭 - 앱 이름 입력
6. 하나의 앱이 만들어지고 하위 메뉴가 뜨는데
그중 api 키를 클릭
7. api 메뉴에서 REST/JS 및 Oauth 두가지 방식이 있는데 REST
선택후
8. 패키지명이나 혹은 웹에서 쓰면 주소 입력하고 엔터
9. api 키 확인
2015년 9월 22일 화요일
클래스 디자인 패턴 12. Compound Pattern (복습)
1. 스트리티지 패턴 적용(일부만)
처음 진행했던 duck 예제를 처음부터 작성합니다.
하나의 인터페이스를 두어 행동 active 에 대해서
다른 동작을 하고 이를 수정코저 할때 그 부분만
수정할 수 있도록 떼어 냈습니다.
다이어그램은 아래와 같습니다.
행동 quackable 를 4개 클래스가 implements 하고 있습니다.
1) Quackable interface 작성
package quackable_1;
public interface Quackable {
public void quack();
}
2. 어댑터 패턴
여기에 비슷한 기능을 하지만 엄연이 다른 메서드를
보유하고 있는 '거위' 라는 클래스를 생성합니다.
하지만 여기 실행에 포함하고 싶습니다.
구별없이 진행하려면 거위 클래스에 어댑터를 달아서
duck와 구별 없이 동작하도록 변경합니다.
1) 거위 클래스 작성 이는 interface를 참고하지 않는
duck 계열과는 다른 클래스 입니다.
package honkable_2;
public class Goose {
public void honk(){
System.out.println("----Honk im honk honk honk----");
}
}
이를 위해서 오리 생성자를 다른 객체로 감싸서
기존 기능을 + count 를 할 수 있는 기능을 추가합니다.
추가 내용에 대한 다이어그램은 아래와 같습니다.
1) QuackAble를 참고하는 QuackCount를 생성합니다.
여기서는 quack 를 구현할때 count를 체크하게끔하고
count는 static 선언하여 인스턴트와 상관없이
count가 쌓이게끔 합니다.
추가로 getQuacks에서 count를 반환하도록 작성합니다.
package quackCountDeco_4;
import quackable_1.Quackable;
public class QuackCount implements Quackable {
Quackable duck;
static int numberofQuacks;
public QuackCount(Quackable duck) {
this.duck = duck;
}
@Override
public void quack() {
duck.quack();
numberofQuacks++;
}
public static int getQuacks(){
return numberofQuacks;
}
}
2) 테스트 코드를 수정합니다. 여기서 각 duck 인스턴스 생성시
가자의 구현체를 QuackCount 객체에 넣어서 생성합니다.
new QuackCount(new MallardDuck());
package simulator;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
private void simulate() {
Quackable mallardDuck = new QuackCount(new MallardDuck());
Quackable redheadDuck = new QuackCount(new RedheadDuck());
Quackable duckCall = new QuackCount(new DuckCall());
Quackable rubberDuck = new QuackCount(new RubberDuck());
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
이렇게 하면 다른 비슷한 클래스를 추가할때 공통 부분을
건들지 않고 팩토리만 수정하면 추가되며
사용 하는 부분은 test 부분에서 수정하도록 일부 떼어내기가 가능
해집니다.
구현하고자 하는 팩토리 패턴의 다이어그램입니다.
1) DuckFactory 작성을 위한 추상 클래스를 하나 작성합니다.
여기에 오리를 추가하면 구현부에 오류가 뜨기 때문에 쉽게
구현이 가능합니다.
package duckFactory_5;
import quackable_1.Quackable;
public abstract class AbstractDuckFactory {
public abstract Quackable createMallarDuck();
public abstract Quackable createRedheadDuck();
public abstract Quackable createDuckCall();
public abstract Quackable createRubberDuck();
}
2) DuckFacotry를 상속받아 구현체인 CountDuckFacory를
구현합니다. 이때 QuackCounter 도 포함하여 구현토록
작성합니다.
package duckFactory_5;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class CountingDuckFactory extends AbstractDuckFactory {
@Override
public Quackable createMallarDuck() {
// TODO Auto-generated method stub
return new QuackCount(new MallardDuck());
}
@Override
public Quackable createRedheadDuck() {
// TODO Auto-generated method stub
return new QuackCount(new RedheadDuck());
}
@Override
public Quackable createDuckCall() {
// TODO Auto-generated method stub
return new QuackCount(new DuckCall());
}
@Override
public Quackable createRubberDuck() {
// TODO Auto-generated method stub
return new QuackCount(new RubberDuck());
}
}
3) 여기에 맞춰 테스트 코드를 수정합니다.
package simulator;
import duckFactory_5.AbstractDuckFactory;
import duckFactory_5.CountingDuckFactory;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
private void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallarDuck();
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
굳이 한 객체씩 관리해야 하는 점 때문입니다.
Iterator에 객체 생성부분을 통합시키고 array로만
해당 부분을 관리하면 simulator를 한번만
돌릴 수 있습니다.
그리고 오리나 거위나 상관없이 add 함수만으로 객체를
simulator 상에 추가할 수 있습니다.
구현하고자 하는 팩토리 패턴의 다이어그램입니다.
1) Iterator 를 생성합니다.
package iterator_6;
import java.util.ArrayList;
import java.util.Iterator;
import quackable_1.Quackable;
public class Flock implements Quackable{
ArrayList quackers = new ArrayList();
public void add(Quackable quacker){
quackers.add(quacker);
}
@Override
public void quack() {
Iterator iterator = quackers.iterator();
while(iterator.hasNext()){
Quackable quacker = (Quackable) iterator.next();
quacker.quack();
}
}
}
2) 테스트 코드를 수정합니다.
package simulator;
import iterator_6.Flock;
import duckFactory_5.AbstractDuckFactory;
import duckFactory_5.CountingDuckFactory;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.Quackable;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
private void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallarDuck();
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
Flock flockOfCucks = new Flock();
flockOfCucks.add(mallardDuck);
flockOfCucks.add(redheadDuck);
flockOfCucks.add(duckCall);
flockOfCucks.add(rubberDuck);
flockOfCucks.add(gooseDuck);
simulate(flockOfCucks);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
5번까지 진행 결과 : 3,4번 결과와 동일합니다.
처음 진행했던 duck 예제를 처음부터 작성합니다.
하나의 인터페이스를 두어 행동 active 에 대해서
다른 동작을 하고 이를 수정코저 할때 그 부분만
수정할 수 있도록 떼어 냈습니다.
다이어그램은 아래와 같습니다.
행동 quackable 를 4개 클래스가 implements 하고 있습니다.
1) Quackable interface 작성
package quackable_1;
public interface Quackable {
public void quack();
}
2) Quackabel 기능을 상속받은 다른 구현체들을 작성
(1)
package quackable_1;
public class MallardDuck implements Quackable {
@Override
public void quack() {
System.out.println("Quack Quack * 3");
}
}
(2)
package quackable_1;
public class RedheadDuck implements Quackable {
@Override
public void quack() {
System.out.println("Quack * 2");
}
}
(3)
package quackable_1;
public class DuckCall implements Quackable {
@Override
public void quack() {
System.out.println("Kwak");
}
}
(4)
package quackable_1;
public class RubberDuck implements Quackable {
@Override
public void quack() {
System.out.println("Squeak");
}
}
3) test 구현체 작성
package simulator;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
private void simulate() {
Quackable mallardDuck = new MallardDuck();
Quackable redheadDuck = new RedheadDuck();
Quackable duckCall = new DuckCall();
Quackable rubberDuck = new RubberDuck();
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
}
private void simulate(Quackable duck) {
duck.quack();
}
}
1차 실행 결과 :
2. 어댑터 패턴
여기에 비슷한 기능을 하지만 엄연이 다른 메서드를
보유하고 있는 '거위' 라는 클래스를 생성합니다.
하지만 여기 실행에 포함하고 싶습니다.
구별없이 진행하려면 거위 클래스에 어댑터를 달아서
duck와 구별 없이 동작하도록 변경합니다.
1) 거위 클래스 작성 이는 interface를 참고하지 않는
duck 계열과는 다른 클래스 입니다.
package honkable_2;
public class Goose {
public void honk(){
System.out.println("----Honk im honk honk honk----");
}
}
2) Goose를 duck처럼 동작하기 위해서 adapter를 생성합니다.
package adapterQuack_3;
import honkable_2.Goose;
import quackable_1.Quackable;
public class GooseAdapter implements Quackable{
Goose goose ;
public GooseAdapter(Goose goose){
this.goose=goose;
}
@Override
public void quack() {
goose.honk();
}
}
3) 정상적으로 동작하는지 보기 위해 test 소스를 수정합니다.
중요한 부분은 인스턴스 생성시 어댑터를 통해서 goose를
생성하였다는 점이며 이후 동일한 메서드를 통해서
goose의 honk() 메서드를 실행할 수 있었습니다.
Quackable gooseDuck = new GooseAdapter(new Goose());
simulate(gooseDuck);
package simulator;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
private void simulate() {
Quackable mallardDuck =new MallardDuck();
Quackable redheadDuck = new RedheadDuck();
Quackable duckCall = new DuckCall();
Quackable rubberDuck = new RubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
}
private void simulate(Quackable duck) {
duck.quack();
}
}
package adapterQuack_3;
import honkable_2.Goose;
import quackable_1.Quackable;
public class GooseAdapter implements Quackable{
Goose goose ;
public GooseAdapter(Goose goose){
this.goose=goose;
}
@Override
public void quack() {
goose.honk();
}
}
3) 정상적으로 동작하는지 보기 위해 test 소스를 수정합니다.
중요한 부분은 인스턴스 생성시 어댑터를 통해서 goose를
생성하였다는 점이며 이후 동일한 메서드를 통해서
goose의 honk() 메서드를 실행할 수 있었습니다.
Quackable gooseDuck = new GooseAdapter(new Goose());
simulate(gooseDuck);
package simulator;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
private void simulate() {
Quackable mallardDuck =new MallardDuck();
Quackable redheadDuck = new RedheadDuck();
Quackable duckCall = new DuckCall();
Quackable rubberDuck = new RubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
}
private void simulate(Quackable duck) {
duck.quack();
}
}
3. 데코레이터 패턴
오리울음 횟수를 체크하는 counter 를 추가하고자 합니다.이를 위해서 오리 생성자를 다른 객체로 감싸서
기존 기능을 + count 를 할 수 있는 기능을 추가합니다.
추가 내용에 대한 다이어그램은 아래와 같습니다.
1) QuackAble를 참고하는 QuackCount를 생성합니다.
여기서는 quack 를 구현할때 count를 체크하게끔하고
count는 static 선언하여 인스턴트와 상관없이
count가 쌓이게끔 합니다.
추가로 getQuacks에서 count를 반환하도록 작성합니다.
package quackCountDeco_4;
import quackable_1.Quackable;
public class QuackCount implements Quackable {
Quackable duck;
static int numberofQuacks;
public QuackCount(Quackable duck) {
this.duck = duck;
}
@Override
public void quack() {
duck.quack();
numberofQuacks++;
}
public static int getQuacks(){
return numberofQuacks;
}
}
2) 테스트 코드를 수정합니다. 여기서 각 duck 인스턴스 생성시
가자의 구현체를 QuackCount 객체에 넣어서 생성합니다.
new QuackCount(new MallardDuck());
package simulator;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
private void simulate() {
Quackable mallardDuck = new QuackCount(new MallardDuck());
Quackable redheadDuck = new QuackCount(new RedheadDuck());
Quackable duckCall = new QuackCount(new DuckCall());
Quackable rubberDuck = new QuackCount(new RubberDuck());
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
3번까지 진행 결과 :
4. 팩토리 패턴
오리 생성하는 부분을 따로 떼어서 팩토리로 감싸는걸 생각해봅니다.이렇게 하면 다른 비슷한 클래스를 추가할때 공통 부분을
건들지 않고 팩토리만 수정하면 추가되며
사용 하는 부분은 test 부분에서 수정하도록 일부 떼어내기가 가능
해집니다.
구현하고자 하는 팩토리 패턴의 다이어그램입니다.
1) DuckFactory 작성을 위한 추상 클래스를 하나 작성합니다.
여기에 오리를 추가하면 구현부에 오류가 뜨기 때문에 쉽게
구현이 가능합니다.
package duckFactory_5;
import quackable_1.Quackable;
public abstract class AbstractDuckFactory {
public abstract Quackable createMallarDuck();
public abstract Quackable createRedheadDuck();
public abstract Quackable createDuckCall();
public abstract Quackable createRubberDuck();
}
2) DuckFacotry를 상속받아 구현체인 CountDuckFacory를
구현합니다. 이때 QuackCounter 도 포함하여 구현토록
작성합니다.
package duckFactory_5;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class CountingDuckFactory extends AbstractDuckFactory {
@Override
public Quackable createMallarDuck() {
// TODO Auto-generated method stub
return new QuackCount(new MallardDuck());
}
@Override
public Quackable createRedheadDuck() {
// TODO Auto-generated method stub
return new QuackCount(new RedheadDuck());
}
@Override
public Quackable createDuckCall() {
// TODO Auto-generated method stub
return new QuackCount(new DuckCall());
}
@Override
public Quackable createRubberDuck() {
// TODO Auto-generated method stub
return new QuackCount(new RubberDuck());
}
}
3) 여기에 맞춰 테스트 코드를 수정합니다.
package simulator;
import duckFactory_5.AbstractDuckFactory;
import duckFactory_5.CountingDuckFactory;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.DuckCall;
import quackable_1.MallardDuck;
import quackable_1.Quackable;
import quackable_1.RedheadDuck;
import quackable_1.RubberDuck;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
private void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallarDuck();
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
simulate(mallardDuck);
simulate(redheadDuck);
simulate(duckCall);
simulate(rubberDuck);
simulate(gooseDuck);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
4번까지 진행 결과 : 3번 항목과 일치합니다.
5. 컴포지트 패턴+이터레이터 패턴
오리를 하나씩 생성하는데 그부분이 눈에 거슬립니다.굳이 한 객체씩 관리해야 하는 점 때문입니다.
Iterator에 객체 생성부분을 통합시키고 array로만
해당 부분을 관리하면 simulator를 한번만
돌릴 수 있습니다.
그리고 오리나 거위나 상관없이 add 함수만으로 객체를
simulator 상에 추가할 수 있습니다.
구현하고자 하는 팩토리 패턴의 다이어그램입니다.
1) Iterator 를 생성합니다.
package iterator_6;
import java.util.ArrayList;
import java.util.Iterator;
import quackable_1.Quackable;
public class Flock implements Quackable{
ArrayList quackers = new ArrayList();
public void add(Quackable quacker){
quackers.add(quacker);
}
@Override
public void quack() {
Iterator iterator = quackers.iterator();
while(iterator.hasNext()){
Quackable quacker = (Quackable) iterator.next();
quacker.quack();
}
}
}
package simulator;
import iterator_6.Flock;
import duckFactory_5.AbstractDuckFactory;
import duckFactory_5.CountingDuckFactory;
import honkable_2.Goose;
import adapterQuack_3.GooseAdapter;
import quackCountDeco_4.QuackCount;
import quackable_1.Quackable;
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
private void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallarDuck();
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
System.out.println("\n Duck Simulator");
Flock flockOfCucks = new Flock();
flockOfCucks.add(mallardDuck);
flockOfCucks.add(redheadDuck);
flockOfCucks.add(duckCall);
flockOfCucks.add(rubberDuck);
flockOfCucks.add(gooseDuck);
simulate(flockOfCucks);
System.out.println("The Duck quacked "+ QuackCount.getQuacks()+"times.");
}
private void simulate(Quackable duck) {
duck.quack();
}
}
5번까지 진행 결과 : 3,4번 결과와 동일합니다.
2015년 9월 21일 월요일
클래스 디자인 패턴 11. proxy pattern_
1. 개념잡기
1) 의미 및 구현방법
현재 상태를 다른 프로그램에서 요청하여 볼 수 있도록
하는 기능입니다.
다른 프로그램을 엿보기 위해서 클라이언트(요청하는곳) 과
서비스(요청에 대한 응답) 기능을 두고 그 사이에 통신 기능을
넣어서 서로 정보를 주고 받을 수 있도록 해야 합니다.
이를 위해서 통신 기능을 넣어야 하지만
java의 RMI 클래스를 통해서
이를 쉽게 프록시로 생성하여 관리 가능합니다.
관련 클래스
java.rmi.Remote : interface
import java.rmi.RemoteException : class 오류 관리
2) 참고자료
RMI 클래스는
http://www.javadom.com/tutorial/rmi-idl/
http://java.ihoney.pe.kr/54
2. 소스
소스는 기본적으로 디자인 패턴 10번을 가지고 진행합니다.
1) rmi.Remote를 상속받아서 interface를 구현
3) 다이어그램
역시 하단 링크를 참고바랍니다.
하단 링크에서도 자세하게 설명하고 있습니다.
state 및 이를 implements 한 구현체 클래스는 스트리티지
패턴과 비슷하나 이를 밖에서 조합하여
쓰는 과정에서 약간 차이가 있음.
http://secretroute.tistory.com/entry/Head-First-Design-Patterns-%EC%A0%9C11%EC%9E%A5-Proxy-%ED%8C%A8%ED%84%B4-1
1) 의미 및 구현방법
현재 상태를 다른 프로그램에서 요청하여 볼 수 있도록
하는 기능입니다.
다른 프로그램을 엿보기 위해서 클라이언트(요청하는곳) 과
서비스(요청에 대한 응답) 기능을 두고 그 사이에 통신 기능을
넣어서 서로 정보를 주고 받을 수 있도록 해야 합니다.
이를 위해서 통신 기능을 넣어야 하지만
java의 RMI 클래스를 통해서
이를 쉽게 프록시로 생성하여 관리 가능합니다.
관련 클래스
java.rmi.Remote : interface
import java.rmi.RemoteException : class 오류 관리
2) 참고자료
RMI 클래스는
http://www.javadom.com/tutorial/rmi-idl/
http://java.ihoney.pe.kr/54
2. 소스
소스는 기본적으로 디자인 패턴 10번을 가지고 진행합니다.
1) rmi.Remote를 상속받아서 interface를 구현
package instances;
import java.rmi.Remote;
import java.rmi.RemoteException;
import stateI.State;
public interface GumballMachineRemote extends Remote {
public int getCount() throws RemoteException;
public String getLocation() throws RemoteException;
public State getState() throws RemoteException;
}
2) GumballMachine 은 rmi.server 의 UnicastRemoteObject를
상속받도록 수정한다.
3) State 객체는 직렬화가 가능토록 직렬화 상속을 받아서
진행한다.
4) 기존 testDrive 는 아래와 같이 처리한다.
5) GumballMonitor에 예외처리를 해준다.
6) GumballMonitorTestDrive 를 구현하여 요청하는 client 단의
내용을 test 할 수 있도록 한다.
package instances;
import java.rmi.Naming;
public class GumballMonitorTestDrive {
public static void main(String[] args) {
String[] location = {"rmi://santafe.mightygumball.com/gumballmachine","rmi://boulder.mightygumball.com/gumballmachine","rmi://seattle.mightygumball.com/gumballmachine"};
GumballMonitor[] monitor = new GumballMonitor[location.length];
for(int i=0; i<location.length;i++){
GumballMachineRemote machine;
try {
machine = (GumballMachineRemote) Naming.lookup(location[i]);
monitor[i] = new GumballMonitor(machine);
System.out.println(monitor[i]);
} catch (Exception e) {
e.printStackTrace();
}
}
for(int i=0; i<monitor.length;i++){
}
}
}
결과 :
실행순서 :
(1) rmiRegistry
.....
(2) GumballMachineTestDrive
이걸 실행시 인자 값을 줘야함 String int
java GumballMachineTestDrive seattle.mightygumball.com 100
java GumballMachineTestDrive boulder.mightygumball.com 100
run - configration 에서 Argument 부분에서 인자값을 넣어줘야 함.
.....
(3) GumballMonitorTestDrive
상속받도록 수정한다.
public class GumballMachine extends UnicastRemoteObject implements GumballMachineRemote {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state = soldOutState;
int count =0;
public GumballMachine(String locatrion, int numberGumballs) throws RemoteException {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
this.count =numberGumballs;
if(numberGumballs>0){
state = noQuarterState;
}
}
3) State 객체는 직렬화가 가능토록 직렬화 상속을 받아서
진행한다.
package stateI;
import java.io.Serializable;
public interface State extends Serializable {
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
4) 기존 testDrive 는 아래와 같이 처리한다.
package tsstmain;
import java.rmi.Naming;
import instances.GumballMachine;
import instances.GumballMachineRemote;
public class GumballMachineTestDrive {
public static void main(String[] args) {
GumballMachineRemote gumballMachine = null;
int count;
if (args.length < 2) {
System.out.println("GumballMachine ");
System.exit(1);
}
try {
count = Integer.parseInt(args[1]);
gumballMachine = new GumballMachine(args[0], count);
Naming.rebind("//" + args[0] + "/gumballmachine", gumballMachine);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5) GumballMonitor에 예외처리를 해준다.
package instances;
import java.rmi.*;
public class GumballMonitor {
GumballMachineRemote machine;
public GumballMonitor(GumballMachineRemote machine) {
this.machine = machine;
}
public void report() {
try{
System.out.println("뽑기 기계위치:"+machine.getLocation());
System.out.println("현재 재고:"+machine.getCount()+" 개");
System.out.println("현재 상태:"+machine.getState());
} catch(RemoteException e){
e.printStackTrace();
}
}
}
6) GumballMonitorTestDrive 를 구현하여 요청하는 client 단의
내용을 test 할 수 있도록 한다.
package instances;
import java.rmi.Naming;
public class GumballMonitorTestDrive {
public static void main(String[] args) {
String[] location = {"rmi://santafe.mightygumball.com/gumballmachine","rmi://boulder.mightygumball.com/gumballmachine","rmi://seattle.mightygumball.com/gumballmachine"};
GumballMonitor[] monitor = new GumballMonitor[location.length];
for(int i=0; i<location.length;i++){
GumballMachineRemote machine;
try {
machine = (GumballMachineRemote) Naming.lookup(location[i]);
monitor[i] = new GumballMonitor(machine);
System.out.println(monitor[i]);
} catch (Exception e) {
e.printStackTrace();
}
}
for(int i=0; i<monitor.length;i++){
}
}
}
7) 이를 테스트 하려면 rmi Registry 플러그인이 필요하다.
하단 링크 참고
http://blog.bagesoft.com/646
%java GumballMonitorTestDrive
뽑기 기계 위치 : seattle.mightygumball.com
현재 재고 : 100 개
현재 상태 : 동전 투입 대기중
뽑기 기계 위치 : seattle.mightygumball.com
현재 재고 : 100 개
현재 상태 : 동전 투입 대기중
2. 다이어그램
3) 다이어그램
역시 하단 링크를 참고바랍니다.
하단 링크에서도 자세하게 설명하고 있습니다.
state 및 이를 implements 한 구현체 클래스는 스트리티지
패턴과 비슷하나 이를 밖에서 조합하여
쓰는 과정에서 약간 차이가 있음.
http://secretroute.tistory.com/entry/Head-First-Design-Patterns-%EC%A0%9C11%EC%9E%A5-Proxy-%ED%8C%A8%ED%84%B4-1
피드 구독하기:
글 (Atom)
















