팩토리 메소드 패턴이란?
복잡한 생산 과정을 숨기고, 완성된 인스턴드만 반환한다.
[new를 사용하지 않고도 클래스 이름만 가지고도 인스턴스 생성하는 방법]
1) 팩토리 사용
package com.example;
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(){ //내부에서 Bus 만들어서 return
return new Bus();
}
}
getBus() 생성
package com.example;
public class BeanFactoryMain {
public static void main(String[] args) {
BeanFactory bf1 = BeanFactory.getInstance();
BeanFactory bf2 = BeanFactory.getInstance();
Bus b1 = bf1.getBus();
Bus b2 = bf2.getBus(); //생성과정을 맡김
//기존에는 Bus b3 = new Bus();로 생성
}
}
생성 과정을 대신해주는 클래스 = 팩토리
2) 클래스 로더 사용
Class clazz = Class.forName("클래스풀네임");
Object obj = clazz.newInstance();
[예제]
a() 메소드를 가지고 있는 클래스가 있다. 이 클래스 이름이 아직 무엇인지 모르지만 나중에 이 클래스 이름을 알려주겠다.
a()메소드를 실행할 수 있도록 코드를 작성해라.
ex) Bus b1 = new Bus();
b1.a();
에서 Bus인지를 안알려주는것
[단계1]
package com.example;
public class Bus {
public void a(){
System.out.println("a");
}
public void b(){
System.out.println("a");
}
public void c(){
System.out.println("a");
}
}
package com.example;
public class ClassLoaderMain {
public static void main(String[] args) throws Exception{
//className에 해당되는 클래스 정보를 CLASSPATH에서 찾음
//그 정보를 clazz가 참조하도록 한다.
// Object o = new Bus();
String className = "com.example.Bus"; //나중에 알게될 클래스 명
Class clazz = Class.forName(className);
Object o = clazz.newInstance();
Bus b = (Bus)o; //Bus로 형변환
b.a();
}
}
[단계2] a()이름을 가진 메소드를 모두 출력하고 싶을때
추상 클래스 생성
package com.example;
public abstract class Car {
public abstract void a();
}
상속받는 클래스 작성
package com.example;
public class Bus extends Car {
public void a(){
System.out.println("a");
}
public void b(){
System.out.println("a");
}
public void c(){
System.out.println("a");
}
}
package com.example;
public class SuperCar extends Car{
public void a(){
System.out.println("supercar a");
}
}
→ Car를 상속받는 메소드는 모두 가능
String ClassName = "come.example.Car를상속받는메소드"
package com.example;
public class ClassLoaderMain {
public static void main(String[] args) throws Exception{
// Object o = new Bus();
// Car c = new Bus();
String className = "com.example.SuperCar"; // Car을 상속받는 아무 클래스이름. SuperCar & Bus
Class clazz = Class.forName(className);
Object o = clazz.newInstance();
Car b = (Car)o; //인스턴스를 부모타입으로 참조
b.a();
}
}
[단계3] Car를 상속받지 않는 클래스 생성
package com.example;
public class MyHome {
public void a(){
System.out.println("a라는 메소드를 myhome이 갖고있어요");
}
}
String className = "com.example.아무클래스이름";
.getDeclaredMethod를 사용했기때문에 아무거나 사용해도 찾을 수 있음
package com.example;
import java.lang.reflect.Method;
public class ClassLoaderMain {
public static void main(String[] args) throws Exception{
String className = "com.example.MyHome"; //나중에 알게될 클래스 명
Class clazz = Class.forName(className);
Object o = clazz.newInstance();
Method m = clazz.getDeclaredMethod("a", null); // a() 메소드 정보를 가지고 있는 Method를 반환하라
m.invoke(o, null); //Object o가 참조하는 객체의 m 메소드를 실행하라
}
}
'[즐거운 자바 강좌] 정리' 카테고리의 다른 글
[즐거운 자바] 섹션 5 - 배열 Arrays클래스 (0) | 2024.03.31 |
---|---|
[즐거운 자바 강좌] 섹션 5 - 배열(Array) (1) | 2024.03.31 |
[즐거운 자바 강좌] 섹션4 - 인터페이스(interface) (3) | 2024.03.31 |
[즐거운 자바 강의] 섹션4 - 객체지향 문법 (3) (1) | 2024.03.31 |
[즐거운 자바 강좌] 섹션3 - 객체지향문법(2) (0) | 2024.03.31 |