public interface Phone {
}
public class Iphone implements Phone {
}
public class Galaxy implements Phone {
}
Phone iphone = new Iphone();
Phone galaxy = new Galaxy();
객체는 여러 곳에서 생성될 수 있는데, 호출하는 쪽이 객체의 생성자에 직접 의존하고 있으면 나중에 요구사항이 변경되었을 때 호출 코드가 모두 직접 수정되어야 하는 경우가 많이 발생하게된다.
public interface Phone {
enum Type {
IPHONE, GALAXY
}
}
public class PhoneFactory {
public Phone createPhone(Phone.Type phoneType) {
switch (phoneType) {
case IPHONE:
return new Iphone();
case GALAXY:
return new Galaxy();
default:
throw new IllegalArgumentException("Phone 타입이 아닙니다");
}
}
}
PhoneFactory phoneFactory = new PhoneFactory();
Phone iphone = phoneFactory.createPhone(Phone.Type.IPHONE);
Phone galaxy = phoneFactory.createPhone(Phone.Type.GALAXY);
그래서 생성자 호출 (new
) 을 별도의 클래스 (Factory
) 에서 담당하고 호출 코드에서는 팩토리를 통해 객체를 생성한다.
→ PhoneFactory
를 선언한 후 생성 메서드만 호출하면 실제 구현 클래스인 Iphone
, Galaxy
에 의존하지 않은 코드를 작성할 수 있게 된다!
→ 하지만 새로운 phone
클래스로 Zplip
이 추가된다면 PhoneFactory
내부를 수정해야하므로, 기존 코드에 영향을 주지 않는 것을 지향하는 객체지향 원칙을 지키기 힘들다. (OCP 원칙)
public interface Phone {
void register();
}
public class Iphone implements Phone {
@Override
public void register() {
System.out.println("아이폰 유저 입니다."); // iphone 전용 로직
}
}
public abstract class PhoneFactory {
public Phone newInstance() {
Phone phone = createPhone();
phone.register();
return phone;
}
protected abstract Phone createPhone();
}
public class IphoneFactory extends PhoneFactory {
@Override
protected Phone createPhone() {
return new Iphone();
}
}
public class ZFlipFactory extends PhoneFactory {
@Override
protected Phone createPhone() {
return new ZFlip();
}
}
팩토리를 추상 클래스로 정의하여, 실제로 어떤 객체를 생성할 지는 추상 메서드로 정의해서 하위 클래스에서 정의
PhoneFactory phoneFactory = new IphoneFactory();
Phone phone = phoneFactory.newInstance();
Iphone
클래스에 대한 의존성 없이 사용 가능PhoneFactory
에 대한 의존성도 제거 가능→ 새로운 phone
클래스로 Zplip
이 추가될때, 기존 코드의 변경 없이 phone
인터페이스와 ZplipPhoneFactory
를 새로 정의하여 확장 가능
→ 확장때마다 많은 클래스를 정의하여야 하기 때문에 코드량이 증가한다는 단점이 있음
public interface PhonePartsFactory {
Cpu createCpu();
Speaker createSpeaker();
}
서로 연관된 또는 의존적인 객체(parts)들을 모아서 인터페이스로 제공함. 각 phone
클래스(서브 클래스)에서는 parts 들을 오버라이딩하여 사용!
→ 팩토리 메서드 패턴과 비슷하지만 공통된 집합을 모아둔다는 점이 특징임
https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/DesignPattern