Factory Method
-
하위 클래스에서 인스턴스 작성하기
-
인스턴스를 생성하는 공장을 Template Method패턴으로 구성하는 것이 Factory Method패턴
-
Template Method 패턴 이란?
하위클래스에서 구체적으로 로직이 들어가는 패턴
-
인스턴스를 만드는 방법을 상위 클래스 측에서 결정하지만 구체적인 클래스 이름까지는 결정하지 않음
-
구체적인 내용은 모두 하위 클래스에서 수행
⇒ 인스턴스 생성을 위한 골격과 실제 인스턴스를 생성하는 클래스를 분리해서 생각하는 패턴 -
디자인 패턴 중 생성 패턴에 포함
생성 패턴이란?
- 시스템이 어떤 Concrete Class를 사용하는지에 대한 정보를 캡슐화함
- 클래스의 인스턴스 들이 어떻게 만들어지고 어떻게 결합하는지에 대한 부분을 완전 가려준다
⇒ 생성패턴을 이용하면 무엇이 생성되고, 누가 생성하며, 어떻게 생성되는지, 언제 생성할 것인지에 대한 유연성을 확보할 수 있음
-
주의깊게 봐야하는것
-
여기에서 Factory, Product 클래스는 framework라는 패키지 소속
-
IDCard, IDCardFactory 클래스는 구체적인 내용을 구현하여 idcard라는 패키지에 소속
각각의 class의 역할
추상적인 골격 ⇒ framework , 구체적인 내용 ⇒ idcard
Creator(작성자) 역할
-
예제에서는 Factory 클래스가 작성자 역할을함
예제에서 createProduct는 인스턴스 생성을 위한 메소드
-
실제로 생성하는 ConcreateProduct에 가지고 있는 정보가 없고 Product와 인스턴스 생성의 메소드를 호출하면 Product가 생성되는 것 뿐이다
-
new를 사용해서 실제 인스턴스를 생성하는 것 대신, 인스턴스 생성을 위한 메소드를 호출해서 구체적인 클래스 이름에 의한 속박에서 상위 클래스를 자유롭게 만듦
Product(제품) 역할
- 예제에서 Product 클래스가 제품 역할을함
- famework에 포함
- 생성되야하는 인스턴스가 가져야할 인터페이스(API)를 결정하는 것 ⇒ 추상클래스
- 구체적인 내용은 하위클래스인 ConcreteProduct 역할
- Product를 생성하는 추상 클래스는 framework
ConcreteCreator.java (구체적인 작성자)
- 예제에서는 IDCard가 구체적인 작성자 역할을 함
- idcard
- 구체적인 제품을 만드는 클래스
ConcreteProduct.java (구체적인 제품)
- 예제에서는 IDCardFactory 클래스가 구체적인 제품 역할을함
- 구체적인 제품
- idcard
예제
- Main.java
package FactoryMethod;
import FactoryMethod.framework.Factory;
import FactoryMethod.framework.Product;
import FactoryMethod.idcard.IDCardFactory;
public class Main{
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("김카드");
Product card2 = factory.create("이카드");
Product card3 = factory.create("박카드");
card1.use();
card2.use();
card3.use();
}
}
- Factory.java
package FactoryMethod.framework;
// import FactoryMethod.idcard.IDCard;
// Template Method 패턴이 사용되는 class
// 제품을 실제로 만들고 등록하는 구현은 하위클래스에서 함
// Tempplte Method 패턴 - 하위 클래스에서 구체적으로 처리하는 패턴
public abstract class Factory {
public final Product create(String owner) {
Product p = createProduct(owner);
// Product p = createNew(owner);
registerProduct(p);
return p;
}
// 자바의 특징 -> 접근지정자 (protected, public, private) => 캡슐화
// createProduct : 인스턴스 생성을 위한 메소드
// new로 실제 인스턴스를 생성하는 대신 인스턴스 생성을 위한 메소드를 호출해서 구체적인 클래스 이름에 의한 속박에서 상위 클래스를 자유롭게함
// protected Product createNew (String owner) {
// return new IDCard(owner);
// }
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
}
- Product.java
package FactoryMethod.framework;
// FactoryMethod.framework 는 제품에 대해서 표현한 패키지, 사용 생성 이런것
public abstract class Product {
public abstract void use();
}
- IDCardFactory.java
package FactoryMethod.idcard;
import FactoryMethod.framework.*;
import java.util.*;
public class IDCardFactory extends Factory {
private List owners = new ArrayList();
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
}
public List getOwners() {
return owners;
}
}
- IDCard.java
package FactoryMethod.idcard;
import FactoryMethod.framework.*;
// 인식 카드를 나타내는 클래스
public class IDCard extends Product {
private String owner;
// 생성자
public IDCard(String owner) {
System.out.print(owner + "카드 만듦\n");
this.owner = owner;
}
@Override
public void use() {
System.out.print(owner + "카드 사용\n");
}
public String getOwner() {
return owner;
}
}
왜 사용해야 하는가?
-
팩토리 패턴은 클라이언트 코드로 부터 서브 클래스의 인스턴스화를 제거해서 서로 간의 종속성을 낮추고, 결합도를 느슨하게해서 호가장을 쉽게함
-
만약 framework패키지를 이용해서 제품과 공장을 만든다고 가정
TV의 클래스 Television과 TV공장 TelevisionFactory를 만든다고 하면 framework 패키지를 import한 별도의 Television 패키지를 만들게됨
⇒ 이때 framework 패키지를 수정하지 않아도 전혀 다른 제품과 공장을 만들수 있다
⇒ 즉. framework패키지는 내용을 수정할 수 없다
⇒ 왜? framework 패키지 안에 idcard 패키지를 import하지 않음
⇒ 이로 알수 있는점 : framework 패키지는 idcard패키지에 의존하고 있지 않음
Factory.java의 createProduct 메소드 구현방법
-
추상메소드
하위 클래스가 반드시 이 메소드를 override해야함
-
디폴드의 구현
디폴트 구현을 준비하고 하위 클래스에서 구현하지 않을 때 사용
이 경우 Product를 new해서 사용하므로 Product를 추상클래스로 놓을수 없다
-
에러이용
FactoryMethodRuntimeExecption이 별도로 작성되어야함
하위클래스에서 구현하지 않을 경우에 실행시 에러 발생
추상 클래스
- 클래스간의 공통점을 찾아내서 공통의 부모를 설계하는 작업
- 아직 구현되지 않은 클래스를 포함한 것으로 무조건 자식클래스에서 재구현해서 인스턴스 화해야한다
- 없거나 하나 이상의 추상 메소드(아직 구현되어 있지 않은 abstract로 정의된 메소드)를 가지고 있는 것
- 추상 클래스는 생성자는 가질수있음 하지만
- 인스턴스를 만들수 없지만 추상클래스를 상속받은 클래스를 통하면 인스턴스화 가능함
왜 사용하는가?
- 부모 클래스에서 공통 부분의 구현과 설계가 완료되면 자식이 상속받아 기능 확장 가능
- 자식 클래스에서 추상클래스를 반드시 구현해야함
- 공통 사항이 한곳에서 관리되어 개발 및 유지보수 용이
- 부모 추상 클래스에서 기본 생성자가 없으므로 하위 클래스에 사용 된 생성자는 부모 생성자를 명시적으로 호출해야함
참고
디자인 패턴(Design Pattern)이란?
객체지향 소프트웨어를 '잘' 설계한다는 것은 쉬운 일이 아닙니다. 게다가, 재사용할 수 있는 객체지향 소프트웨어를 만드는 것은 더 힘듭니다. 설계를 할 때에는 지금 당장 갖고 있는 문제를 해
readystory.tistory.com
[JAVA/자바] 추상 클래스(abstract class), 추상 메소드
이번 포스팅은 추상 클래스에 대해서 알아보도록 하겠다. 추상이란 말처럼 공통적인 특성이나 속성들을 추...
blog.naver.com
'Study(Language)' 카테고리의 다른 글
[Design Pattern] Singleton (0) | 2021.01.07 |
---|