package GOF;
interface Create {
public void create();
}
class A implements Create {
@Override
public void create() {
System.out.println("A");
}
}
class B implements Create {
@Override
public void create() {
System.out.println("B");
}
}
interface Produce {
public Create produce();
}
class C implements Produce {
@Override
public Create produce() {
return new A();
}
}
class D implements Produce {
@Override
public Create produce() {
return new B();
}
}
public class AbstractFactory {
public static void main(String[] args) {
Produce produce = new C();
Create create = produce.produce();
create.create();
}
}
如上图所示代码,是抽象工厂模式的实例。请问在实际的业务场景中如何使用?有什么优点。
大家讲道理2017-04-18 09:29:40
많은 분들이 디자인 패턴을 유연하게 적용하지 못하는 질문이 참 의미가 깊다고 생각합니다
문제 분석의 관점에서 팩토리 클래스 디자인 패턴을 사용해야 하는 이유에 대해 이야기해보겠습니다
질문 1: 과 유사한 함수를 가진 클래스가 있는 경우가 많으므로 이를 추상화하고 인터페이스를 사용하여 공개 메서드를 노출하고 추상 클래스를 사용하여 공개 구현을 제공하는 것이 좋습니다. .
으아악두 번째 질문: 유사한 기능을 가진 이러한 클래스를 인스턴스화하는 것이 문제가 되었습니다. 각 클래스의 생성자 매개변수가 다르기 때문에 매번 개체를 새로 만드는 것이 번거로워 간단한 팩토리로 캡슐화됩니다. 패턴.
으아악세 번째 질문: 단순한 팩토리 모델은 확장에 도움이 되지 않으며 열기 및 닫기 원칙을 위반합니다. 클래스가 추가될 때마다 팩토리 클래스를 수정해야 합니다(팩토리 클래스와 비즈니스 클래스는 두 개의 소규모 파트너가 따로 작성하면 의사 소통에 많은 시간이 걸리지 않습니다 ...) 그래서 단순하게 추상화하는 것을 원칙으로하는 Factory Method Pattern이 있습니다. 공장.
으아악질문 4: 갑자기 잘못된 점을 발견했습니다. 코드가 너무 많아지고, 유사한 기능을 가진 제품에 대해 3개의 추상화 계층이 있고, 각 제품에 대해 2개의 팩토리 클래스도 추상화되었기 때문입니다. 그러나 특정 비즈니스 시나리오에서는 클래스를 인스턴스화하는 것만으로는 충분하지 않습니다. 예를 들어, 게임에서 군인에게 장비를 장착하려면 먼저 그에게 총기를 장착해야 합니다(소총, 저격총 등 많은 총기가 있습니다. 추상화하려면 질문 1을 사용하세요). 하지만 총기를 장착한 후에는 총알도 장착해야 합니다(추상화를 위해 질문 1의 방법을 계속 사용). 이제 현재 상황에 따라 2계층 팩토리 클래스를 추상화할 수 있습니다. 총기와 총알을 모두 생산하는 공장이 있나요? 이것이 추상 팩토리 패턴입니다. 쉽게 말하면 관련 제품이나 유사한 제품을 하나의 공장에 모아서 생산할 수 있기 때문에 별도의 공장을 열 필요가 없습니다.
그리고 정정하자면, 게시한 코드는 추상 팩토리 패턴이 아니라 팩토리 메소드 패턴입니다.
질문자가 제 답변을 받아들이지 않은 걸 보니 몇 마디 더 말씀드리고 구체적인 적용 사례를 말씀드리겠습니다.
우리 모두는 Java의 제네릭이 유형 삭제를 사용하여 구현된다는 것을 알고 있습니다(제네릭은 javac 컴파일 프로세스 중에 제거되고 강제 유형 변환이 추가됨). 따라서 new T()를 사용하여 객체를 직접 인스턴스화할 수 없습니다. 실제로 팩토리 메소드 패턴 디자인 패턴을 이용하면 해결할 수 있다.
일반 인스턴스화를 사용하는 클래스가 있다고 가정해 보겠습니다.
으아악다음과 같이 공장 인터페이스를 제공합니다.
으아악다음 방법을 사용하여 개선할 수 있습니다
으아악이때 다음과 같은 방법으로 Foo
를 인스턴스화할 수 있습니다. 으아악ps: 너무 장황한 내용을 피하기 위해 여기서는 내부 클래스를 사용하여 팩토리 메소드 구현을 수행합니다.