>Java >java지도 시간 >심플팩토리

심플팩토리

Barbara Streisand
Barbara Streisand원래의
2024-11-24 11:40:11316검색

심플팩토리란?

단순한 팩토리는 디자인 패턴이 아닙니다. 이는 단순히 클라이언트 코드에서 객체 생성을 분리합니다. 즉, Simple Factory는 인스턴스화 논리를 별도의 클래스로 이동하여 객체 인스턴스화를 캡슐화합니다.

간단한 팩토리는 팩토리 패턴과 혼동되는 경우가 많습니다. 차이점을 명확히 하기 위해 Simple Factory에 대해 알아보겠습니다. 또한 Simple Factory를 배우면 Factory 패턴을 쉽게 이해할 수 있습니다.

Simple Factory는 어떤 문제를 해결할 수 있나요?

구체적인 구현을 위한 프로그래밍은 애플리케이션 유지 관리를 매우 어렵게 만들기 때문에 피해야 합니다. 인터페이스에 프로그래밍하는 것이 항상 바람직합니다. 클라이언트 코드에서 구체적인 클래스를 인스턴스화하는 경우 Simple 팩토리가 클라이언트에서 객체 생성을 분리할 수 있으므로 Simple 팩토리가 유용합니다. 이를 통해 애플리케이션의 확장성과 유지 관리가 더욱 쉬워졌습니다.

문제

버거샵 시스템을 개발 중입니다. 소고기버거, 치킨버거 등 다양한 버거를 만들어 내는 시스템이 필요합니다.

첫 번째 시도는 다음과 같습니다.

// Client orders a burger
Burger orderBurger(String type) {
    Burger burger;

    if (type.equals("beef")) {
        burger = new BeefBurger();
    } else if (type.equals("chicken")) {
        burger = new ChickenBurger();
    } else if (type.equals("fish")) {
        burger = new FishBurger();
    }

    burger.prepareBun();
    burger.grillPatty();
    burger.addToppings();
    burger.wrap();

    return burger;
}

문제는 인터페이스가 아닌 구현을 위해 코딩하고 있다는 것입니다. 어디? if 문을 사용하고 버거 유형을 기반으로 구체적인 클래스를 인스턴스화합니다.
왜 문제가 됩니까? 우리의 클라이언트 코드는 객체 생성과 밀접하게 결합되어 유연성이 떨어집니다!! 더 이상 생선 버거를 판매하지 않고 채식 버거를 판매하기 시작한다고 가정해 보겠습니다. 클라이언트 코드를 방문하여 수정해야 합니다. 즉, 수정을 위해 닫혀있지 않습니다.

해결책

문제를 해결하기 위해 객체 생성만 담당하는 별도의 클래스를 만들 수 있습니다. 그러면 클라이언트 코드는 객체 생성에 대해 걱정할 필요가 없으며 추상화에 의존할 수 있습니다. 이 기술을 "다양한 내용 캡슐화"라고 합니다. 구체적인 객체 인스턴스화에 대한 코드는 자주 변경될 것으로 예상되지만 prepareBun(), grillPatty(), addToppings(), Wrap() 프로세스는 앞으로 모든 버거에서 동일하게 유지될 가능성이 높습니다.
Simple Factory의 장점은 다른 클래스에서 재사용이 가능하다는 것입니다. SimpleBurgerFactory.createBurger() 메소드를 사용하는 BurgerRestaurant, BurgerCateringShop과 같은 다른 클라이언트 클래스가 있을 수도 있습니다.

Simple Factory

  1. 클라이언트
    클라이언트는 SimpleBurgerFactory를 통해 특정 버거 객체를 인스턴스화합니다. 클라이언트 관점에서 보면 어떤 콘크리트 버거가 생성될지 알 수 없습니다. 즉, 객체 생성 로직이 이제 클라이언트에서 분리되었습니다.

  2. 심플버거팩토리
    이 클래스는 변화하는 것, 즉 객체 생성 로직을 캡슐화합니다! createBurger()는 클라이언트가 이 클래스를 사용하여 객체를 인스턴스화하기를 원하기 때문에 정적 메서드로 선언됩니다(물론 인스턴스화하기 전에는 인스턴스를 가질 수 없습니다!). createBurger()는 BurgerType 열거형을 허용하여 생성해야 할 버거 유형을 결정합니다.

  3. 버거
    이 추상 클래스는 모든 버거 사이에 공통 인터페이스를 제공하고 기본 동작을 정의합니다.

  4. 버거 하위 클래스
    콘크리트 제품은 다음과 같습니다. Burger 클래스를 확장하는 한 메서드를 재정의하여 특정 동작을 구현할 수 있습니다.

구조

Simple Factory

암호

// Client orders a burger
Burger orderBurger(String type) {
    Burger burger;

    if (type.equals("beef")) {
        burger = new BeefBurger();
    } else if (type.equals("chicken")) {
        burger = new ChickenBurger();
    } else if (type.equals("fish")) {
        burger = new FishBurger();
    }

    burger.prepareBun();
    burger.grillPatty();
    burger.addToppings();
    burger.wrap();

    return burger;
}
public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
// Abstract Product
public abstract class Burger {

    public BurgerType burgerType;
    public List<String> toppings = new ArrayList<>();

    public void prepareBun() {
        System.out.println("Preparing a bun");
    }

    public void grillPatty() {
        if (burgerType == null) {
            throw new IllegalStateException("pattyType is undefined");
        }
        System.out.println("Grill a " + burgerType + " patty");
    }

    public void addToppings() {
        for (String item : toppings) {
            System.out.println("Add " + item);
        }
    }

    public void wrap() {
        System.out.println("Wrap a burger up");
    }
}
// Concrete product
public class BeefBurger extends Burger {

    public BeefBurger() {
        burgerType = BurgerType.BEEF;
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce");
        toppings.addAll(items);
    }
}
// Concrete product
public class VeggieBurger extends Burger {

    public VeggieBurger() {
        burgerType = BurgerType.VEGGIE;
        List<String> items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");
        toppings.addAll(items);
    }

    // Concrete product can implement specific behavior that differs from other products
    @Override
    public void wrap() {
        System.out.println("Wrapping paper shouldn't print any meats but vegetables");
    }
}
// Simple factory, responsible for instantiating an object
public class SimpleBurgerFactory {

    public static Burger createBurger(BurgerType type) {
        return switch (type) {
            case BEEF -> new BeefBurger();
            case CHICKEN -> new ChickenBurger();
            case FISH -> new FishBurger();
            case VEGGIE -> new VeggieBurger();
            default -> throw new IllegalArgumentException("unknown burger type");
        };
    }
}

출력:

public class Client {

    public static void main(String[] args) {
        Burger burger = orderBurger(BurgerType.VEGGIE);
        System.out.println(burger); // Check if the object is actually veggie burger
    }

    public static Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

함정

  • 객체 인스턴스화를 위한 의사결정 코드는 때때로 더 복잡해질 수 있습니다. 이런 경우에는 Factory 메소드를 대신 사용하는 것이 좋습니다.

팩토리 패턴과의 비교

  • 간단한 팩토리에서는 일반적으로 어떤 제품 유형을 만들 것인지 결정하는 하나의 팩토리 클래스가 있는 반면, 팩토리 패턴에서는 여러 개의 팩토리를 도입할 수 있습니다.
  • 간단한 팩토리는 종종 정적 메서드를 사용하여 객체를 생성하므로 호출하기는 쉽지만 확장하기는 어렵습니다. 반면, 팩토리 메소드는 모든 팩토리에 대한 인터페이스 역할을 하는 슈퍼 클래스의 추상 메소드를 사용하며 서브클래스는 객체 인스턴스화를 위한 구체적인 구현을 제공합니다.

여기에서 모든 디자인 패턴 구현을 확인할 수 있습니다.
GitHub 저장소


추신
기술 블로그를 처음 작성하는 초보입니다. 글쓰기를 개선하기 위한 조언이 있거나 혼란스러운 점이 있으면 댓글을 남겨주세요!
읽어주셔서 감사합니다 :)

위 내용은 심플팩토리의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.