디자인 모드 노트(4): 공장 모드
Car car = new Car();
Wheel wheel = null;
if (type.equal("A")) {
wheel = new AWheel();
} else if (type.equal("B")) {
wheel = new BWheel();
} else if (type.equal("C")) {
wheel = new CWheel();
}
car.setWheel(wheel);
간단한 코드로 자동차 대상과 바퀴 대상을 만들고 type에 따라 어떤 바퀴를 사용할지 선택합니다.여기에 코드가 문제가 있다. 만약에 시간의 변화에 따라 A바퀴가 생산되지 않는다. 즉, A바퀴가 사용할 수 없다면 우리는 코드를 수정하고 A와 관련된 코드를 제거해야 한다. 그러나 많은 다른 클라이언트들도 이런 코드를 사용한다. 이것은 다른 클라이언트의 코드도 반드시 고쳐야 한다는 것을 의미한다.다시 말하면 이곳의 일련의 판단은 변화할 수 있는 부분이다.비교적 좋은 방법은 그것을 봉하여 단독으로 한 곳에 두는 것이다. 이후에 변화가 있으면 한 곳만 바꾸면 된다.이것이 바로 단순 공장 모델이다.
단순 공장 모델
예를 바꿔서 피자의 예를 봅시다.코드는 다음과 같습니다.
//Pizza
public abstract class Pizza {
protected String name;
public abstract void bake();
public abstract void cut();
@Override
public String toString() {
return "Pizza{" +
"name='" + name + '\'' +
'}';
}
}
//A Pizza
public class APizza extends Pizza {
public APizza() {
this.name = "A Pizza";
}
@Override
public void bake() {
System.out.println("A bake");
}
@Override
public void cut() {
System.out.println("A cut");
}
}
//B Pizza
public class BPizza extends Pizza {
public BPizza() {
this.name = "B Pizza";
}
@Override
public void bake() {
System.out.println("B bake");
}
@Override
public void cut() {
System.out.println("B cut");
}
}
//Pizza
public class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = null;
if ("A".equals(type)) {
pizza = new APizza();
} else if ("B".equals(type)) {
pizza = new BPizza();
}
if (pizza != null) {
pizza.bake();
pizza.cut();
}
return pizza;
}
}
//
public class Main {
public static void main(String[] args) {
PizzaStore store = new PizzaStore();
Pizza pizza = store.orderPizza("A");
}
}
테스트 클래스를 실행하면 다음과 같은 결과가 표시됩니다.
A bake
A cut
우리의 기대에 부합되지만 만약에 우리가 많은 상점이 있고 이런 상점에서 피자를 주문하는 논리는 모두 유형에 따라 판단된다(각 상점에서 파는 피자가 반드시 같지 않기 때문에 종종 기류에 뽑히지 못한다는 것을 주의한다). 즉, 상술한 if-else if...구조그렇다면 지금 A타입의 피자를 생산하지 않고 C타입의 피자를 대신할 계획이라면 우리는 A타입의 피자와 관련된 상점 코드마다 변경할 수밖에 없다.
현재 간단한 공장 모드로 코드를 고쳐서if-else 구조를 공장 클래스에 추출합니다.코드는 다음과 같습니다.
//
public class SimplePizzaFactory {
public Pizza createPizza(String type) {
if ("A".equals(type)) {
return new APizza();
} else if ("B".equals(type)) {
return new BPizza();
}
return null;
}
}
// Pizza
public class PizzaStore {
private SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza(String type) {
Pizza pizza = this.factory.createPizza(type);
if (pizza != null) {
pizza.bake();
pizza.cut();
}
return pizza;
}
}
나머지 클래스는 수정하지 않는다. 이렇게 하면 변화하는 부분을 하나의 단독 클래스에 뽑는 것이 장점이다. 피자 상점류는 공장의 실현에만 의존하고 피자의 구체적인 실현에 의존하지 않는다. 피자 상점은 피자를 직접 생산하지 않고 어떤 피자가 필요하면 한 공장에 가서'물건을 찾기'를 하면 된다고 간단하게 이해할 수 있다.
이제 와서 수요가 바뀌면 어떻게 되는지 분석해 볼까요?만약 어떤 피자 상점에서 A타입의 피자가 필요하지 않다면 (잘 팔리지 않아서) 피자는 어떻게 해야 하나요?우리 코드에서 그는 아무것도 할 필요가 없다.코드를 수정하지 않아도 된다. 피자 생산의 책임은 피자 공장에 맡기고 손님이 어떤 피자를 필요로 하는지, 상점에서 직접 피자 공장에 가서 가져가면 되기 때문이다. 피자가 어떤 건지 관심이 없다.
그러나 이런 방법도 한계가 있다. 예를 들어 현재 많은 상점이 있는데 이런 상점들은 자신의 특색을 원할 수도 있다. 공장에서 얻을 줄은 생각지도 못했다. (주의, 공장도 여러 가지가 있고 상점은 어느 공장에 가서 얻을 수 있는지를 마음대로 선택할 수 있다) 어떻게 해야 합니까?하나의 해결 방안은 공장 방법 모델을 이용하는 것이다.
공장 방법 모델
공장 방법 모델과 단순 공장의 차이는 제품을 생산하는 곳은 종류가 아니라 하나의 방법에서 다음과 같은 코드와 같다는 것이다.
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
if (pizza != null) {
pizza.bake();
pizza.cut();
}
return pizza;
}
protected abstract Pizza createPizza(String type);
}
// createPizza(String type); 。
public class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
if (type.equals("A")) {
return new APizza();
}
return null;
}
}
public class CHPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
if (type.equals("B"))
return new BPizza();
return null;
}
}
//
public class Main {
public static void main(String[] args) {
PizzaStore pizzaStore = new NYPizzaStore();
pizzaStore.orderPizza("A");
}
}
상기 코드는 단독 공장류를 사용하지 않고 구체적인 생산 피자의 책임은 각 상점에 맡기고 자기가 하고 싶은 대로 하고 자기가 책임지는 것을 볼 수 있다.
추상 공장 모델
현재 각 상점은 아직 만족하지 않는다. 그들은 손님들이 원료에 대한 요구가 매우 높다는 것을 발견했다. 그래서 그들은 스스로 원료를 가지려고 한다. 각지의 원료의 품질도 다르고 그러면 어디로 가지?어떻게 들지?이런 상황은 추상적인 공장 모델로 해결하고 추상적인 공장을 도입할 수 있다. 그 부류는 구체적인 공장이다. 그리고 각 상점은 어느 공장에서 재료를 받을지 결정한다.코드는 다음과 같습니다.
public interface PizzaFactory {
void createSourceA();
void createSourceB();
void createSourceC();
}
public class APizzaFactory implements PizzaFactory {
@Override
public void createSourceA() {
System.out.println("A create source A");
}
@Override
public void createSourceB() {
System.out.println("A create source B");
}
@Override
public void createSourceC() {
System.out.println("C create source C");
}
}
//B A , 。
//
public class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
PizzaFactory pizzaFactory = new APizzaFactory();
if (type.equals("A")) {
return new APizza(pizzaFactory);
}
return null;
}
}
// A Pizza
public class APizza extends Pizza {
private PizzaFactory pizzaFactory;
public APizza(PizzaFactory pizzaFactory) {
this.pizzaFactory = pizzaFactory;
this.name = "A Pizza";
}
@Override
public void bake() {
this.pizzaFactory.createSourceA();
this.pizzaFactory.createSourceB();
this.pizzaFactory.createSourceC();
System.out.println("A bake");
}
@Override
public void cut() {
System.out.println("A cut");
}
}
//
public class Main {
public static void main(String[] args) {
PizzaStore pizzaStore = new NYPizzaStore();
pizzaStore.orderPizza("A");
}
}
이렇게 되면 각 상점은 스스로 어느 공장에서 원료를 가져와 피자를 생성할지 결정할 수 있게 된다.
소결
공장 모델은 주로 세 가지가 있다.
단순 공장은 매우 간단하고 직관적이다. 바로 생산 제품의 논리를 하나의 단독 유형에서 추출하여 관리하고 필요할 때 가져가는 것이다.그러나 유연성이 부족하다는 한계가 있다.
공장 방법의 유연성은 단순 공장보다 높고 계승을 통해 자류가 스스로 생산의 논리를 결정할 수 있다.
추상 공장과 공장 방법의 차이는 그리 뚜렷하지 않다. 비교적 직관적인 차이는 공장 방법은 계승을 통해 이루어진 것이고 추상 공장은 주로 조합을 통해 이루어진다.추상 공장의 단점은 확장은 새로운 부류를 필요로 하고 공장 방법은 실현 방법의 구체적인 논리만 있으면 된다는 것이다. 그러나 추상 공장의 구조는 더욱 뚜렷하고 읽기 쉽다.한 마디로 하면 이 두 가지 방식은 효과가 많지 않기 때문에 구체적으로 어떤 것을 선택해야 하는지는 실제 상황에 따라 결정해야 한다.
다음은 플랜트 모델의 정의입니다.
공장 방법 모델: 공장 방법 모델은 창설 대상의 인터페이스를 정의하지만 하위 클래스에 따라 실례화할 클래스가 어느 것인지를 결정한다.공장 방법은 클래스의 실례를 하위 클래스로 미루게 한다
추상 공장 모델: 추상 공장 모델은 인터페이스를 제공하여 관련 또는 의존 대상의 가족을 만드는 데 사용되며 구체적인 종류를 명확하게 지정할 필요가 없다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.