출저: http://iilii.egloos.com/3791596
자바 디자인 패턴 3Factory Method
1. Factory Method패턴은..
factory는 공장이죠. 객체를 막 찍어내는 놈입니다. 객체 선언은 보통 new 객체() 이런식으로 하죠. factory는 내부에서 그런 일을 해줍니다. 즉 factory를 가져다가 쓰는 부분에서는 new 객체()와 같은 식으로 변수를 선언할 필요가 없습니다.Abstract class나 인터페이스에 대해서 다양한 하위 구현체가 있을 경우에 사용하면 좋습니다. 사용법은 Factory.create(인자는 맘대로) 와 같이 됩니다.
2. 예제
package chap03_StaticFactory;
public interface Animal {
public void printDescription();
}
package chap03_StaticFactory;
public class AnimalFactory {
public static Animal create(String animalName){
if (animalName == null) {
throw new IllegalArgumentException("null은 안 되지롱~");
}
if (animalName.equals("소")) {
return new Cow();
}else if (animalName.equals("고양이")) {
return new Cat();
}else if (animalName.equals("개")) {
return new Dog();
}else{
return null;
}
}
}
package chap03_StaticFactory;
public class Cat implements Animal {
public void printDescription() {
System.out.println("쥐잡기 선수");
}
}
package chap03_StaticFactory;
public class Cow implements Animal {
public void printDescription() {
System.out.println("우유 및 고기 제공");
}
}
package chap03_StaticFactory;
public class Dog implements Animal {
public void printDescription() {
System.out.println("주로 집 지킴");
}
}
package chap03_StaticFactory;
public class Test {
public static void main(String[] args) {
Animal a1= AnimalFactory.create("소");
a1.printDescription();
Animal a2= AnimalFactory.create("고양이");
a2.printDescription();
Animal a3= AnimalFactory.create("개");
a3.printDescription();
}
}
이번 것은 소스가 좀 깁니다. 일단 Animal이라는 인터페이스가 있습니다. Cat, Cow, Dog 는 이 인터페이스의 구현체들입니다.
그리고 AnimalFactory가 있는데, 여기서 Animal의 구현체를 돌려줍니다.
Test에서 new Cow()와 같이 하지 않고, AnimalFactory.create("소")를 호출하는 게 일반적인 방법과의 차이입니다.
Animal의 구현체가 더 늘어나면 어떻게 될까요? 전부 new AnotherAnimal()과 같이 생성하는 것보다는 Facotry의 create()메쏘드만 수정하는 게 좀 편하겠죠?
3. Factory 의 유용성
Animal a1 = AnimalFactory.create("소"); 와 같은 코드에서 a1이 Cow라는 것을 굳이 신경쓰지 않겠다는 겁니다. Test클래스 안에는 new 라는 구문 자체가 없습니다. 정확히 어떤 클래스의 인스턴스인지 신경쓰지 않고 구현할 수 있는 장점이 있습니다. 객체 타입이 굉장히 유연해 질 수 있죠.
4. JAVA API에 있는 Factory Method
Factory 패턴의 중요한 특징 중 하나는 Factory에서 리턴할 때는 매번 객체를 새로 만들지 않을 수도 있다는 겁니다.
Boolean.valueOf(boolean) 을 먼저 살펴 보죠.
Boolean a = Boolean.valueOf(true);
Boolean b = Boolean.valueOf(true);
System.out.println(a==b);
이 코드를 실행시키면 어떤 결과가 나올까요? true 가 나옵니다. 왜냐하면 Boolean.valueOf(true) 는 Boolean.TRUE 라는 상수를 리턴합니다. 즉, 인스턴스를 새로 만드는 것이 아니라 기존에 있는 것을 그냥 리턴합니다. 매번 새로 만들지 않는다는 거죠. 각종 Wrapper 클래스에 있는 많은 메쏘드 들이 이렇게 구현되어 있습니다.
Calendar.getInstance() 를 호출하면, 사용자 환경에 맞는 Calendar 객체가 리턴됩니다. 보통은 GregorianCalendar가 리턴된죠.
(이 메쏘드의 이름은 좀 잘못지어진 것 같습니다. 보통 getInstance()는 singleton 패턴에서 쓰이는 이름입니다.)
5. Factory Method의 종류
예제에서는 Factory의 인스턴스를 만들지 않고, static 메쏘드인 create()만을 호출했습니다. 이런 방식을 static factory method라고 합니다.
그냥 factory method라고 하면, factory의 인스턴스를 만들어서 쓰는 방식입니다. static factory에 비해 사용 빈도는 좀 떨어지지만, factory의 인스턴스에 귀속되는 객체를 생성해야 할 때는 이런 방식을 씁니다.(static factory에 비해 많이 쓰지 않으므로 자세한 것은 생략합니다.
'좋은 설계자 & 좋은관리자 & 좋은개발자 > Design Pattern & Modeling' 카테고리의 다른 글
Builder pattern (0) | 2014.04.24 |
---|---|
Arraylist vector 공통점/ 차이점 (0) | 2014.01.02 |
Java System.getProperty() (0) | 2013.12.23 |
Servlet 파일 업로드 (MultipartRequest) (0) | 2013.12.20 |
Java 4대 중첩 클래스 (instance class, static class, local class, anonymous class) (0) | 2013.12.19 |
제가 알고 있는 장점은thread context switching을
제가 알고 있는 장점은
thread context switching을 줄일 수 있다는 겁니다.
프로세스 보다야 낫겠지만 쓰레드도 컨텍스트 스위칭에 오버 헤드가 있기 때문에 이걸 줄일 수 있다면 좋습니다. 특히 소켓 수가 많고, 소켓 통신이 빈번하게 이루어지는 상황이라면 이 오버 헤드도 무시 못할 게 되죠.
대신에 코딩하기 귀찮아진다는 (무시 못할 ㅋㅋ) 단점이 있지만요.
추가로 소켓을 쓰레드에 분배하거나, 쓰레드끼리 데이타를 주고 받을 필요가 발생해서 생기는 오버 헤드도 있을 수 있습니다.
select나 poll을 사용하였을 때의 장점은 performance나
select나 poll을 사용하였을 때의 장점은 performance나 scale면에서는 큰 장점은 없는 것 같습니다.
하지만,
- thread를 여러개 만드는 것보다는 select를 사용하는 것이 메모리 사용면에서 효율 적이고
- 다른 io event와 같이 기다릴 수 있다
는 장점이 있을 것 같습니다.
저 같은 경우에는 두번째의 용도로 많이 씁니다. 예를 들어 소켓 통신 중 중단 시키려는 경우 빨리 깔끔하게 뒷처리를 하도록 하기 위해서는 blocking인 경우 thread를 바로 깨워줘야 하는데 이를 위한 방법이 없어서요.
제가 주로 사용하는 것이 RTOS인데 unix는 이런 경우에 깨울수 있는 방법이 있나요?
throughput 과 response time 간 trade off 관
throughput 과 response time 간 trade off 관계인데요.
일단 이거 단일 프로세스라는 가정에서 이야기를 하면
throughput 은 select 가 좋습니다.
kane 님께서 말씀 하셨듯이 컨텍스트 스위칭, 쓰레드 스케줄링, 크리티컬섹션의 뮤텍스 처리등이 쓰레드를 이용하면 생기는 부하들인데 이런 것들이 없기때문에 전체 성능은 좋아집니다.
하지만 select 는 (쓰레드와 비교해 상대적으로) response time 이 떨어집니다. 클라이언트 입장에서는 다른 클라이언트가 서버에 먼저 뭔가 요구했다면 그 작업이 끝날때까지 기다렸다가 내 차례가 오기때문이죠.
위와 같은 상황은 커널이 프로세스 스케줄링할때 어떤 알고리즘을 사용하느냐 그리고 한 프로세스에 한번에 주는 cpu 시간의 크기에 따라 throughput 과 response time 이 trade off 관계인것 과 같은 것이지요.
또한 쓰레드를 쓰면 각각의 쓰레드 생성 오버헤드도 있고 각 쓰레드의 스택세그먼트 공간을 생각하면 메모리 낭비가 문제지요.
그럼 쓰레드는 뭐가 좋냐? 위에 말씀 드린 것 처럼 response time 이 짧고 (클라이언트 입장에서 보면 서버의 throughput 은 자기완 전혀 상관없고, response time 이 중요하죠), 크리티컬섹션을 제외한다면 코드도 select 보다 간단하고, 멀티 프로세서일때 필요하다면 모든 프로세서를 동시에 병렬로 이용해서 단일 프로세서의 select 보다 더 좋은 throughput 을 낼 수도 있습니다.
Context Switch 의 Overhead 가 있었군요!!이런이런
Context Switch 의 Overhead 가 있었군요!!
이런이런~ 가장 기본적인것을 놓치다니.. 역시 내공이 부족합니다.
답변주신 세분 감사합니다.
삽질의 대마왕...
NonBlock IO를 쓰는 가장 큰 이유는 소켓의 데이터 처리에 대한
NonBlock IO를 쓰는 가장 큰 이유는 소켓의 데이터 처리에 대한 스케쥴링을 OS나 일반적인 라이브러리에 맡기지 않고, 스스로 구현한 스케쥴링을 사용하겠다는 것입니다.
그리고, OS의 다른 overhead인 process/thread의 스케쥴링 비용(요것이 소켓 100개정도만 넘어가도 상당한 비용이 됩니다.)을 없애겠다는 것입니다.
윗분들이 언급하지 않은 것 하나는 select 또한 소켓수가 100개 이상되면 비용이 작은 것이 아닙니다. select는 각 소켓의 버퍼에 WATER MARK 이상의 값이 있는지에 대해 반응하는 것입니다. 대개 WATER MARK 값은 1로 설정되어 있고, 그 값보다 크게 데이터들이 들어와 있는지를 일일이 비교합니다. 즉 data의 level에 따라 select되는 것이고, 매번 I/O로부터 데이터가 올라왔을 때 바로 반응하는 epoll 을 사용하는 것이 좋습니다.
---
coolengineer.com