[완료] C의 feature와 비슷한 걸, 자바에서도 쓰고 싶은 고민남....
글쓴이: snowavalanch / 작성시간: 월, 2011/03/07 - 2:00오후
하나의 소스로 모든 제품 소스를 뽑으려니 문제가 있어 문의드립니다.
A제품 소스, B제품 소스, C제품 소스 모두 하나의 소스에 넣어 두고,
make 시점에서 A, B, C를 각각 뽑을 수 있는 구조를 원합니다.
C언어로 개발하면, feature 사용하면 쉽게 됩니다.
문제는 자바네요.
일단 feature의 개념이 없으니, 이건 못 쓰고요.
자바야 상속받아서 짜면 될 것 같은데요,
Product class하나 만들어서,
A_Product, B_Product, C_Product class들이
Product class를 extends하면 될 것 같습니다.
그리고, 이들 class를 호출하도록 호출자쪽을 수정하면 됩니다.
Settings 패키지를 extends한
A_Settings를 호출하도록 수정할 수가 없습니다.
(뭐 고칠려면 고치겠지요... 흠....)
이러니, 기껏 Product class에 if 조건문 걸어서,
A, B, C제품별로 분기하도록 작업하는데,
코드가 그지 같게 되네요.
자바에서 함수 포인터를 사용할 수도 없고,
이거 뭐 C처럼 feature할 수 없나용?
Forums:
원하시는 답인지 모르겠지만 일단 설명을 드리겠습니다.
Android 같은 리소스가 적은곳은 적당하지 않을수있습니다.
원하시는 답이지도 모르겠지만 일단 설명을 드리겠습니다.
팩토리 패턴의 정형적인 예는
(1) AbstractProduct productA = FactoryProduct.getInstance("A");
(2) productA.메소드(...);
이런식이죠.
여기서 FactoryProduct.getInstance 구현을 보면
static synchronized AbstractProduct instance(productType) {
if (productType.equals("A")) {
return new ProductA();
} else if (productType.equals("B")) {
return new ProductB();
} else if (productType.equals("C")) {
return new ProductC();
} else {
throw unknown.
}
}
이지요.
이것을 이렇게 하면 if 문 없이 가능합니다.
static synchronized AbstractProduct instance(productType)throws ClassNotFoundException {
Class productClass=null;
StringBuffer sb = new StringBuffer("Product");
sb.append(productType);
productClass = Class.forName(sb.toString());
Object productObj = null;
try {
productObj = productClass.newInstance();
} catch(Exception e) {
log.severe("fail new install");
System.exit(1);
}
return productObj;
}
이렇게 하시면 나중 ProductD가 신규 추가되어도
ProductD 가 AbstractProduct를 상속받고 인터페이스를 구현하기만 하면,
잘 동작하시라 생각합니다.
함수 포인터를 사용하시는 이유가 위에 제가 예시한것의 목적과 유사하지 않을까?
혼자 독단적으로 생각해서 말씀드린겁니다.
원하시는건지는 아직도 잘 모르겠네요.
주의점) 몇개 안되는 if 문으로는 Class.forName의 오버헤드를 상쇄 시킬수 없습니다.
따라서, Android 같은 1 ms가 중요한곳은 신중한 고려가 필요하며,
만약 적용해야 한다면 나름대로의 최적화가 필요합니다.
댓글 감사합니다.
우선, 제 고민에 관심을 가져 주셔서 감사드립니다.
Factory pattern 적용이 정형적이라는 것에는 저도 100% 동의합니다.
문제는 Anrdoid에서 이미 Factory pattern을 적용하여 있는 상태입니다.
현상태는 AbstractProduct를 extends한 ProductA가 존재합니다.
여기서 일반적으로는 ProductB, ProductC...들을 그냥 만들면 되겠지만,
저에게 주어진 조건은,
ProductB, ProductC...들은 만들지 말고,
ProductA 소스 만을 이용한 ProductA-1, ProductA-2, ProductA-3을 뽑아내야 한다는 겁니다.
이 경우, 방법은 ProductA를 또 extends한 ProductA-1, ProductA-2, ProductA-3를 만들고, caller쪽에서 이들을 호출하도록 수정하거나(해보지는 못함),
지금하고 있는 것처럼 ProductA 내에서 if조건문으로 분기하는 방법이 있네요.
(C처럼 pre-processor가 없으니, function 밖에 #ifdef하지도 못하고, function 내에서 if 조건문 분기 해야 하네요.)
음 그런데, caller 수정도 용납되지 않는 상태입니다.
C의 feature가 딱인데, 우짤꼬 하고 있네요....
p.s. 어떻게 보면, 개발 방법은 C에 어울리게 정해놓고, 자바를 끼워 맞출려고 하니, 그지 같은 거 아니야 하실 텐데, 정말 그렇습니다.그냥 if 분기하는 수 밖에 없겠죠...--;
컴파일러 만들면서 Visitor 패턴으로 함수 포인터
컴파일러 만들면서 Visitor 패턴으로 함수 포인터 비슷한 기능 만든적 있는데
이 경우도 적용이 되는지는 잘 모르겠습니다.
------------------------------
How many legs does a dog have?
preprocessor 쓰고 싶으시면 자바 소스에
preprocessor 쓰고 싶으시면 자바 소스에 #ifdef 등을 그대로 사용하고, makefile 에서 C preprocessor 적용한 결과물을 javac 로 컴파일 하면 됩니다.
Orion Project : http://orionids.org
preprocessor 어떤 걸 쓰시는지 알 수 있을까요?
preprocessor 어떤 걸 쓰시는지 알 수 있을까요?
리눅스* 환경이라면 "cpp -P
리눅스* 환경이라면 "cpp -P Preprocessor.pjava Preprocessor.java"처럼 하시면 될 것 같습니다.
감사합니다.
감사합니다.
댓글 달기