이 글은 주로 Java 디자인 패턴 Abstract Factory의 관련 정보를 자세하게 소개하며, 관심 있는 친구들은 참고할 수 있습니다.
1. 개념
관련 인터페이스를 생성하는 방법을 제공합니다. 또는 구체적인 클래스를 지정하지 않고 상호 의존적인 객체를 생성합니다.
2. 패턴 동기
이 객체 시리즈는 상호 의존적이며 제품군과 동일합니다
3. 패턴 구조
위 그림을 통해 명확하게 볼 수 있습니다. 추상 팩토리 패턴에는 다음이 포함됩니다. 다음 4가지 역할:
1. 추상 팩토리 역할(AbstractFactory): 추상 팩토리 패턴의 핵심은 특정 비즈니스 로직과 관련이 없으며 일반적으로 JAVA 인터페이스 또는 추상 클래스입니다.
2. 콘크리트 팩토리 역할: 이 역할은 일반적으로 특정 비즈니스 로직과 밀접하게 관련되어 있습니다. 이 역할의 팩토리 메서드는 특정 제품을 인스턴스화하고 특정 비즈니스 로직에 따라 반환합니다. 클라이언트는 이 역할을 전달하고 해당 팩토리 메서드를 호출합니다. 역할은 특정 제품 객체를 얻습니다. 이 역할은 일반적으로 특정 JAVA 클래스에 의해 가정됩니다.
3. 추상 제품 역할: 이 역할을 수행하는 클래스는 팩토리 메소드 패턴으로 생성된 제품의 상위 클래스이거나 그들이 공유하는 인터페이스(보통 인터페이스 또는 추상 클래스)입니다.
4. 특정 제품 역할: 추상 팩토리 패턴으로 생성된 모든 제품은 이 역할의 인스턴스이며 이를 가정할 특정 JAVA 클래스가 있습니다.
샘플 코드는 다음과 같습니다.
public class AbstractProductA { /** * @roseuid 59AC05990327 */ public AbstractProductA() { } } public class ProductA1 extends AbstractProductA { /** * @roseuid 59AC05990359 */ public ProductA1() { } } public class ProductA2 extends AbstractProductA { /** * @roseuid 59AC05990381 */ public ProductA2() { } } public class AbstractProductB { /** * @roseuid 59AC059903BA */ public AbstractProductB() { } } public class ProductB1 extends AbstractProductB { /** * @roseuid 59AC059A001F */ public ProductB1() { } } public class ProductB2 extends AbstractProductB { /** * @roseuid 59AC059A0049 */ public ProductB2() { } } public abstract class AbstractFactory { /** * @roseuid 59AC05690005 */ public AbstractFactory() { } /** * @return AbstractProductA * @roseuid 59ABFB0103BE */ public Abstract AbstractProductA createProductA() ; /** * @return AbstractProductB * @roseuid 59ABFB3B029D */ public Abstract AbstractProductB createProductB() ; } public class ConcreteFactory1 extends AbstractFactory { /** * @roseuid 59AC057A02FC */ public ConcreteFactory1() { } /** * @return AbstractProductA * @roseuid 59ABFB9C00C9 */ public AbstractProductA createProductA() { return new ProductA1(); } /** * @return AbstractProductB * @roseuid 59ABFBA30011 */ public AbstractProductB createProductB() { return new ProductB1(); } } public class ConcreteFactory2 extends AbstractFactory { /** * @roseuid 59AC057A02C0 */ public ConcreteFactory2() { } /** * @return AbstractProductA * @roseuid 59ABFCC701B9 */ public AbstractProductA createProductA() { return new ProductA2(); } /** * @return AbstractProductB * @roseuid 59ABFCC9001F */ public AbstractProductB createProductB() { return new ProductB2(); } }
public class Client { /** * @roseuid 59AC055700AB */ public Client() { } public static void main(String[] args){ AbstractFactory theAbstractFactory; AbstractProductA theAbstractProductA; AbstractProductB theAbstractProductB; theAbstractFactory=new ConcreteFactory1(); theAbstractProductA=theAbstractFactory.createProductA(); theAbstractProductB=theAbstractFactory.createProductB(); } }
위의 패턴 구조 다이어그램을 기반으로 "특정 클래스를 지정하지 않고 일련의 관련되거나 상호 의존적인 개체를 생성하기 위한 인터페이스 제공"을 진행합니다. 간략한 분석:
1. ProductA1의 인스턴스와 ProductB1의 인스턴스가 비즈니스 로직을 기반으로 하는 상호 연관(예: 내부 관련 관계) 또는 상호 의존(예: 전체 및 부분) 관계의 집합인 관련 또는 상호 의존 개체, ProductA1
은 동일한 제품 수준 구조 AbstractProductB의 ProductB1에만 연관될 수 있지만 ProductB2와 연관될 수는 없습니다.
2. 특정 클래스를 지정하지 않고 일련의 관련 또는 상호 의존적 객체를 생성하기 위한 인터페이스를 제공합니다. 여기서 인터페이스는 구조 다이어그램에서 AbstractProductA 및 AbstractProductB입니다. 특정 구현은 종속성 반전 원칙을 준수합니다. "특정 클래스를 지정할 필요가 없습니다." 즉, 클라이언트는 ProductA1, ProductA2, ProductB1 및 ProductB2의 존재를 알지 못하며 특정 제품 인스턴스를 반환하기 위해 특정 팩토리의 팩토리 메서드만 호출하면 됩니다.
4. 패턴 예시
추가 분석을 위해 공장 방식 패턴의 예시를 따르겠습니다. 이제 이 타이어 공장은 더 이상 자동차 타이어만 생산하는 데 만족하지 않고, 이제 엔진 생산 라인(EngineLine)을 도입했습니다. 도어라인을 비롯해 자동차 전체에 대한 다양한 부품 생산 라인이 생겼다. 이제 자동차를 쉽게 제작할 수 있다고 할 수 있지만, 모든 자동차를 생산할 수 있는 것은 아니다. 예를 들어 벤츠와 BMW 두 종류만 생산할 수 있다. NX에는 이러한 공장이면 충분합니다. 예를 들어 자동차에는 이제 타이어, 도어 및 엔진만 포함되어 있습니다(물론 그 이상이 있어야 합니다). 그러면 이 공장은 아래와 같이 고객 요구 사항에 따라 BMW 및 벤츠 자동차를 생산할 수 있습니다. :
코드는 다음과 같습니다.
public interface Door { public void open(); public void close(); } public class BenzDoor implements Door { @Override public void open() { System.out.println("奔驰车门开"); } @Override public void close() { System.out.println("奔驰车门关"); } } public class BmwDoor implements Door { @Override public void open() { System.out.println("宝马车门开"); } @Override public void close() { System.out.println("宝马车门关"); } } public interface Tire { public void getColor(); public void getLife(); public void getWidth(); } public class BenzTire implements Tire { @Override public void getColor() { System.out.println("benz车color"); } @Override public void getLife() { System.out.println("benz车life"); } @Override public void getWidth() { System.out.println("benz车width"); } } public class BmwTire implements Tire { @Override public void getColor() { System.out.println("bmw车color"); } @Override public void getLife() { System.out.println("bmw车life"); } @Override public void getWidth() { System.out.println("bmw车width"); } } public interface Engine { public void start(); public void stop(); } public class BenzEngine implements Engine { @Override public void start() { System.out.println("benz车start"); } @Override public void stop() { System.out.println("benz车stop"); } } public class BmwEngine implements Engine { @Override public void start() { System.out.println("bmw车start"); } @Override public void stop() { System.out.println("bmw车stop"); } } public interface PartFactory { public Door createDoor(); public Tire createTire(); public Engine createEngine(); } public class BenzPartFactory implements PartFactory { @Override public Door createDoor() { return new BenzDoor(); } @Override public Tire createTire() { return new BenzTire(); } @Override public Engine createEngine() { return new BenzEngine(); } } public class BmwPartFactory implements PartFactory { @Override public Door createDoor() { return new BmwDoor(); } @Override public Tire createTire() { return new BmwTire(); } @Override public Engine createEngine() { return new BmwEngine(); } } public class Car { private Door door; private Engine engine; private Tire tire; public Car(PartFactory factory) { this.door = factory.createDoor(); this.engine = factory.createEngine(); this.tire = factory.createTire(); } public Door getDoor() { return door; } public Engine getEngine() { return engine; } public Tire getTire() { return tire; } } public class Client { public static void main(String[] args) { PartFactory partFactory=new BenzPartFactory(); Car benzCar=new Car(partFactory); benzCar.getDoor().open(); benzCar.getEngine().start(); benzCar.getTire().getColor(); } }
실행 결과는 다음과 같습니다.
벤츠 자동차 문 열림
벤츠 자동차 시동
벤츠 자동차 색상
위의 클래스 다이어그램과 실행 결과에 따르면 , 다음과 같은 분석이 가능합니다:
BenzDoor, BenzTire 및 BenzEngine은 강한 관계를 가지고 있습니다. 벤츠 자동차는 Bmw 도어, 즉 BmwDoor를 사용할 수 없다고 말할 수 있습니다. 이러한 강력한 관계는 BenzPartFactory를 통해 잘 유지됩니다. 위의 클라이언트 클래스와 마찬가지로 고객이 벤츠 자동차를 원한다면 벤츠 자동차를 생산하는 공장만 있으면 됩니다. 이 공장의 모든 제품 인스턴스는 벤츠 자동차의 일부입니다. 실행 결과에서도 확인할 수 있습니다.
ㅋㅋㅋ 수정을 사용합니다. 그런데 고객님께서는 교통체증이 있을 때 날아갈 수 있도록 자동차에 날개 한쌍을 설치하고 싶다고 하셨습니다. 이때 날개를 각 공장에 반납할 수 있는 팩토리 방식을 추가해야 하고, 각 공장을 수정해야 합니다. 이는 개방형 및 폐쇄형 원칙이 아닙니다. 따라서 추상 팩토리는 제품 계층 구조를 추가하기 위한 개방형 폐쇄 원칙을 지원하지 않지만 제품군 차원(예: 아우디 자동차)에 대한 개방형 폐쇄 원칙을 지원합니다.5. 패턴 제약 조건
상호 연관되거나 종속적인 제품군 생성에 적합하며, 제품군 방향의 확장을 지원하지만 제품 레벨 방향의 확장에는 적합하지 않습니다.6. 패턴 변형 및 확장
1. 추상 팩토리는 정적 팩토리 메서드를 제공합니다. 추상 팩토리는 정적 팩토리 메서드를 제공하고 매개 변수를 통해 특정 팩토리 인스턴스를 반환할 수 있습니다. 2. 추상 팩토리와 특정 팩토리 병합: 제품군 방향으로 제품군이 하나만 있다고 판단되면 이때 추상 팩토리는 필요하지 않으며 특정 팩토리 하나만 있으면 됩니다. 이를 더 확장할 수 있습니다. 자체 인스턴스를 반환하는 이 구체적인 팩토리에 대한 정적 메서드를 제공하세요.7. 다른 패턴과의 관계
제품 수준 구조가 하나만 있는 경우 아래와 같이 팩토리 메서드 패턴입니다. 여러 제품 수준 구조가 있는 경우 각 패턴은 추상 팩토리 팩토리 메소드는 "팩토리 메소드" 패턴입니다.8. 모델의 장점과 단점
제품군 방향에서는 개방형 원칙을 지원하지만, 제품 계층 방향에서는 개방형 원칙을 지원하지 않습니다.위 내용은 Java의 추상 팩토리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!