디자인 패턴

[디자인패턴] 추상 팩토리 패턴

Ash_jisu 2023. 12. 3. 19:59

추상 팩토리 패턴 정의

객체들을 통째로 묶어서 팩토리 클래스로 만들고, 이들 팩토리를 조건에 따라 생성하도록

다시 팩토리를 만들어서 객체를 생성하는 패턴이다. 이전에 팩토리 메서드 패턴을 좀 더 캡슐화한

방식이라고 보면 될 것 같다.

 

팩토리 메서드와 다른점

  • 팩토리 메서드: 객체 생성을 위임한다
  • 추상 팩토리: 서로 관련이 있는 객체들을 묶어서 새로운 팩토리 클래스를 만든다.

 

장점

  1. 구체적인 제품과 클라이언트 코드 간의 긴밀한 결합을 피한다.
  2. 단일 책임 원칙: 제품 생성 코드를 한 곳으로 추출하여 코드를 더 쉽게 지원할 수 있다.
  3. 기존 클라이언트 코드를 손상시키지 않고 제품의 새로운 변형을 도입 할 수 있다.

 

단점

  1. 새로운 인터페이스와 클래스가 패턴과 함께 도입되기 때문에 코드가 생각보다 복잡해질 수 있다.

 

 

 


패턴 적용 전

이미지

  • KeyboardFactory: 키보드 담당 팩토리
  • MouseFactory: 마우스 담당 팩토리
  • ComputerFactory: 컴퓨터 부품 담당 팩토리

 

코드

ComputerFactory.java

public class ComputerFactory {
	public void createComputer(String type) {
		KeyboardFactory kFactory = new KeyboardFactory();
		MouseFactory mFactory = new MouseFactory();
		
		kFactory.createKeyboard(type);
		mFactory.createMouse(type);
		
		
		System.out.println("----"+type+" 컴퓨터 완성 ----");
	}

}

 

MouseFactory.java

public class MouseFactory {
	public Mouse createMouse(String type) {
		Mouse mouse = null;
		
		switch(type) {
		case "LG":
			mouse = new LGMouse();
			break;
		case "Samsung":
			mouse = new SamsungMouse();
			break;
		}
		return mouse;
	}
}

 

KeyboardFactory.java

public class KeyboardFactory {
	public Keyboard createKeyboard(String type) {
		Keyboard keyboard = null;
		
		switch(type) {
		case "LG":
			keyboard = new LGKeyboard();
			break;
		case "Samsung":
			keyboard = new SamsungKeyboard();
			break;
		}
		
		return keyboard;
	}
}

 

LGKeyboard.java

public class LGKeyboard implements Keyboard {

	public LGKeyboard() {
		System.out.println("LG 키보드 생성");
	}
	
}

 

LGMouse.java

public class LGMouse implements Mouse {
	public LGMouse() {
		System.out.println("LG 마우스 생성");
	}

}

 

Clinet.java

public class Clinet {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ComputerFactory cFactory = new ComputerFactory();
		//삼성 컴퓨터 생성
		cFactory.createComputer("Samsung");
		//LG 컴퓨터 생성
		cFactory.createComputer("LG");
		
	}
}

SamsungKeyboard와 SamsungMouse는 구현법이 비슷해서 생략했다

 

 

 

문제점

객체 생성시 복잡한 과정을 거쳐야한다. LGComputer를 생산할려면

ComputerFactory는 2개의 팩토리를 거쳐 마우스와 키보드의 정보를 받아 객체를 생성한다.

만일 재료가 10개라면 10개의 팩토리를 거쳐야한다.

 

 

해결법

하지만 이것을 제조업체 별로 묶어버리면 

많은 클래스를 거칠 필요가 없어진다. 

삼성 컴퓨터를 만들게되면 SamsungFactory만 거치면 되는 문제이다.

 

 

 


패턴 적용 후

이미지

  • ComputerFactory: CreateKeyboard()와 CreateMouse()메서드를 가진 인터페이스이다
  • SamsungComputerFactory&LGComputerFactory: ComputerFactory인터페이스를 구현했다.

 

 

코드

FactoryOfComputerFactory.java

public class FactoryOfComputerFactory {
	
	public void createComputer(String type) {
		ComputerFactory cFactory = null;
		
		switch (type) {
		case "LG":
			cFactory = new LGComputerFactory();
			break;
		case "Samsung":
			cFactory = new SamsungComputerFactory();
			break;
		}
		cFactory.createKeyboard();
		cFactory.createMouse();
	}
}

 

ComputerFactory.java  

public interface ComputerFactory {
	public Keyboard createKeyboard();
	public Mouse createMouse();
	
}

 

 

SamsungComputerFactory.java

public class SamsungComputerFactory implements ComputerFactory {
	public SamsungKeyboard createKeyboard() {
		return new SamsungKeyboard();
	}
	
	public SamsungMouse createMouse(){
		return new  SamsungMouse();
	}
}

 

 

LGComputerFactory.java

public class LGComputerFactory implements ComputerFactory{
	public LGKeyboard createKeyboard() {
		return new LGKeyboard();
	}
	
	public LGMouse createMouse(){
		return new  LGMouse();
	}
}

 

 

Client.java

public class Clinet {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FactoryOfComputerFactory factoryOfComputerFactory = new FactoryOfComputerFactory();
		factoryOfComputerFactory.createComputer("Samsung");
		
	}
}

 

컴퓨터 팩토리들을 관리하는 팩토리인 FactoryOfComputerFactory 선언 후에 파라미터를 Samsung을 주면
ComputerFactory인터페이스를 구현하는 SasmsungComputerFactory FactoryOfComputerFactory에서 생성한다.

방식이 더 간략해진것을 볼 수 있다.

키보드와 마우스 클래스는 위에 사용되었던 기존 클래스를 사용해서 추가로언급하지 않았다.