싱글톤 패턴
- private 생성자를 만든다. 즉, 외부에서 인스턴스를 생성하지 못하게 한다.
- 자기 자신 인스턴스를 참조하는 static한 필드를 선언한다.
- 2번에서 생성한 인스턴스를 반환하는 static한 메서드를 만든다.
public class BeanFactory {
// 2. 자기 자신 인스턴스를 참조하는 static한 필드를 선언한다.
private static BeanFactory instance = new BeanFactory();
// 1. private 생성자를 만든다. 즉, 외부에서 인스턴스를 생성하지 못한다.
private BeanFactory() {
}
// 3. 2번에서 생성한 인스턴스를 반환하는 static한 메서드를 만든다.
public static BeanFactory getInstance() {
return instance;
}
}
팩토리 메서드 패턴
객체가 생성되는 과정을 숨겨주는 패턴. 즉, 복잡한 생산 과정을 숨기고, 완성된 인스턴스만 반환하는 것이다.
다르게 말하면 객체 생성을 대신해주는 패턴이라고 할 수 있다.
public Bus getBus() {
return new Bus();
}
ClassLoader를 이용한 인스턴스 생성하기. Java Reflection
a()라는 메서드를 가지 클래스가 여러 개 있다. 그리고 현재 사용하고자 클래스 이름이 무엇인지 아직 모른다. 클래스 이름은 나중에 알려준다. 이때, a() 메서드를 실행할 수 있도록 코드를 작성하라.
JVM은 클래스를 CLASSPATH에서 찾는다. 이때, 다음 코드는 Class.forName(className)은 className에 해당되는 클래스를 CLASSPATH에서 찾는다. 그리고 그 클래스 정보를 Class clazz 참조 변수에 넣어준다.
String className = "theory.singleton.Bus";
Class<?> clazz = Class.forName(className);
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println("method = " + method.getName());
}
그리고 다음 세 줄의 코드는 Object o = new Bus(); 와 같다. 여기서 clazz.newInstance()는 clazz 정보를 가지고 새로운 인스턴스를 만들라는 의미이다.
String className = "theory.singleton.Bus";
Class<?> clazz = Class.forName(className);
Object o = clazz.newInstance();
즉, 인스턴스를 만드는 과정을 new 연산자를 사용하지 않고 인스턴스를 생성한 것이다. 그리고 이 것을 형변환해서 다음과 같이 사용할 수 있다.
String className = "theory.singleton.SuperCar";
Class<?> clazz = Class.forName(className);
Object o = clazz.newInstance();
Car car = (Car) o;
car.a();
그리고 만약 Car를 상속하지 않는 다른 클래스의 메서드를 실행시키고자 하면 다음과 같이 코드를 작성할 수 있다.
여기서 clazz.getDeclaredMethod의 의미는 a() 메서드 정보를 가지고있는 Method를 반환하라는 의미이고, m.invoke(o, null)의 의미는 Object o 가 참조하는 객체의 m 메서드를 실행하라는 의미이다.
String className = "theory.singleton.SuperCar";
Class<?> clazz = Class.forName(className);
Object o = clazz.newInstance();
Method method = clazz.getDeclaredMethod("a", null);
method.invoke(o, null);
이렇게 하면 문자열로 클래스 이름과 메서드 이름을 받아들여서 인스턴스를 생성해 실행할 수 있게 된 것이다.
이렇게 ClassLoader를 이용해 인스턴스를 만들 수도 있고, 그 인스턴스가 가진 메서드를 실행할 수 있는 것을 자바에서는 Reflect라는 문법이라 한다.
그리고 스프링, 서블릿이 내부적으로 Reflection이 사용된다.
또한 이 팩토리 메서드 패턴과 ClassLoader를 결합하면 클래스 이름만 가지고도 인스턴스를 만들어주는 공장을 만들어줄 수 있는 것이다. 즉, 인스턴스 생성이 필요하면 그 공장에 요청만 하면 되는 것이다.
인용
https://youtu.be/8A6ElEmMnSY?si=zoTjP0wZVl49igYT
'Language > Java' 카테고리의 다른 글
배열 (0) | 2023.09.16 |
---|---|
익명 클래스 (Anonymous Class) (0) | 2023.09.15 |
인터페이스 (0) | 2023.09.15 |
부모가 될 수 없는 클래스 - String (0) | 2023.09.15 |
추상클래스 (0) | 2023.09.15 |