design patterns

Factory Method Pattern

Minji May Gil 2016. 5. 15. 22:06

Factory Method Pattern

Define an interface for creating a single object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

factory는 객체를 찍어낸다. 객체 생성과 객체 관리를 해주기 때문에 factory를 사용하는 부분에서 new로 객체를 생성할 필요가 없다.

modifier를 강제할 수 있다.

 

1) Story

  1. YGEnt가 아이돌 그룹을 만든다: debut().
    아이돌 그룹은 profile()로 프로필을 확인할 수 있는 메서드를 가진다.
    YGEnt는 아이돌 그룹의 목록을 뽑아내는 list()메서드를 가진다.
  2. Entertainment(interface)-AbstractEnt(abstract)-YGEnt순으로 class를 구현한다.
    boygroup과 girlgroup은 Singer interface를 구현한다.
  3. debut()안에 다른 메서드들(recruit(),train())을 포함시켜 메서드의 외부노출이 불가능하다.

 

2) UML class diagram

 

image

 

 

3) Code

story1)

public class BoyGroup {
	int memberCnt;
	String name;
	
	BoyGroup(int memberCnt,String name) {
		this.memberCnt=memberCnt;
		this.name=name;
	}
	
	public int getMemberCnt() {
		return memberCnt;
	}
	public void setMemberCnt(int memberCnt) {
		this.memberCnt = memberCnt;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "{\"memberCnt\":" + memberCnt + ", \"Name\":\"" + name + "\"}";
	}
	
	public void profile(){
		System.out.println("memberCnt="+memberCnt+", name="+name);
	}
}
public class YGEnt {

	List list=new ArrayList();
	
	public BoyGroup debut(String name, int memberCnt){
		BoyGroup boyGroup=new BoyGroup(memberCnt,name);
		list.add(boyGroup);
		return boyGroup;
	}
	
	public List list(){
		return list;
	}
}
public class Main1 {

	public static void main(String[] args) {
		
		YGEnt yGEnt =new YGEnt();
		
		//BoyGroup boyGroupA = new BoyGroup(5,"빅뱅");
		BoyGroup boyGroupA = yGEnt.debut("빅뱅",5);
		BoyGroup boyGroupB = yGEnt.debut("위너",5);
		
		boyGroupA.profile();
		boyGroupB.profile();
		
		System.out.println(boyGroupA);
		System.out.println(boyGroupB);
		
		List list = yGEnt.list();
		System.out.println(list);
		
	}
}

story2)

public interface Entertainment {
	
	List debut(String name);
	int recruit();
	Singer train(String name, int memberCnt);
	List enlist(Singer singer);

}
public abstract class AbstractEnt implements Entertainment{

	List list=new ArrayList();
	
	@Override
	public List debut(String name) {
		
		int memberCnt=recruit();
		Singer singer=train(name,memberCnt);
		list.add(singer);
		
		return list;
	}
	
	public abstract int recruit();
	public abstract Singer train(String name, int memberCnt);

	@Override
	public List enlist(Singer singer) {
		return list;
	}

}
public class YGEnt extends AbstractEnt {

	@Override
	public int recruit() {
		int rand=(int)(Math.random()*10+1);
		return rand;
	}

	@Override
	public Singer train(String name, int memberCnt) {
		
		Singer singer=null;
		
		int rand=(int)(Math.random()*2);
		
		if(rand==0){
			singer=new BoyGroup(memberCnt, name);
		}else{
			singer=new GirlGroup(memberCnt, name);
		}
		
		return singer;
	}
}
public interface Singer {
	public void profile();
}
public class BoyGroup implements Singer {
	int memberCnt;
	String name;
	final String gender="boy";
	
	BoyGroup(int memberCnt,String name) {
		this.memberCnt=memberCnt;
		this.name=name;
	}
	
	public int getMemberCnt() {
		return memberCnt;
	}
	public void setMemberCnt(int memberCnt) {
		this.memberCnt = memberCnt;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "{\"memberCnt\":" + memberCnt + ", \"Name\":\"" + name +"\", \"gender\":\""+gender+ "\"}";
	}
	
	public void profile(){
		System.out.println("memberCnt="+memberCnt+", name="+name);
	}
}
public class GirlGroup implements Singer{
	int memberCnt;
	String name;
	final String gender="girl";
	
	GirlGroup(int memberCnt,String name) {
		this.memberCnt=memberCnt;
		this.name=name;
	}
	
	public int getMemberCnt() {
		return memberCnt;
	}
	public void setMemberCnt(int memberCnt) {
		this.memberCnt = memberCnt;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "{\"memberCnt\":" + memberCnt + ", \"Name\":\"" + name +"\", \"gender\":\""+gender+ "\"}";
	}
	
	public void profile(){
		System.out.println("memberCnt="+memberCnt+", name="+name);
	}
}
public class Main2 {

	public static void main(String[] args) {
		
		YGEnt yGEnt =new YGEnt();
		
		yGEnt.debut("빅뱅");
		yGEnt.debut("2NE1");
		yGEnt.debut("위너");
		yGEnt.debut("이하이");
		Listlist=yGEnt.debut("아이콘");
		
		System.out.println(list);
		
	}
}