> Java > java지도 시간 > 본문

완벽한 코드 생성: 생성 패턴 이해

WBOY
풀어 주다: 2024-08-07 07:58:23
원래의
420명이 탐색했습니다.

Creating the Perfect Code: Understanding Creational Patterns

디자인 패턴에 관한 블로그 시리즈의 시작입니다. 이번 블로그에서는 디자인 패턴의 첫 번째 유형인 Creational Patterns에 대해 설명하겠습니다. 여기에서는 생성 패턴에 해당하는 유형을 실제 사례와 함께 논의합니다. 저는 선택 언어로 Java를 사용할 예정입니다.

디자인 패턴이란 무엇입니까?

디자인 패턴은 소프트웨어 개발에서 중요한 역할을 하며, 일반적인 문제에 대한 검증된 솔루션을 제공하고 모범 사례를 장려합니다. 이는 코드에서 반복되는 디자인 문제를 해결하기 위해 사용자 정의할 수 있는 미리 만들어진 청사진과 같습니다.

Java의 창조적인 디자인 패턴 탐색

객체 지향 프로그래밍에서 생성 디자인 패턴은 객체 인스턴스화를 활용과 분리하여 객체 생성의 유연성과 확장성을 높일 수 있으므로 중요한 역할을 합니다. 이 블로그 게시물은 생성 디자인 패턴의 다섯 가지 주요 유형인 팩토리 메소드(Factory Method), 추상 팩토리(Abstract Factory), 빌더(Builder), 프로토타입(Prototype) 및 싱글톤(Singleton)에 중점을 둘 것입니다. 각각의 작동 방식을 보여주기 위해 Java의 실제 예를 사용하겠습니다.

1. 팩토리 메소드

팩토리 메소드 패턴은 객체를 생성하기 위한 인터페이스를 정의하지만 서브클래스가 생성될 객체의 유형을 변경할 수 있도록 허용합니다. 이 패턴은 Java의 느슨한 결합을 지원하여 애플리케이션별 클래스를 코드에 바인딩할 필요가 없도록 합니다.

실제 시나리오: 트럭, 선박 등 다양한 차량을 이용해 물품을 운송하는 물류 회사를 가정해 보겠습니다. 차량 유형은 필요한 운송 수단에 따라 다릅니다.

// Product Interface
interface Transport {
    void deliver();
}

// Concrete Products
class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("Deliver by land in a truck.");
    }
}

class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("Deliver by sea in a ship.");
    }
}

// Creator
abstract class Logistics {
    public abstract Transport createTransport();

    public void planDelivery() {
        Transport transport = createTransport();
        transport.deliver();
    }
}

// Concrete Creators
class RoadLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Truck();
    }
}

class SeaLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Ship();
    }
}

// let's call the main class
public class Main {
    public static void main(String[] args) {
        Logistics logistics = new RoadLogistics();
        logistics.planDelivery();

        logistics = new SeaLogistics();
        logistics.planDelivery();
    }
}
로그인 후 복사

2. 추상공장

추상 팩토리 패턴은 구체적인 클래스를 지정하지 않고 관련 객체 또는 종속 객체의 패밀리를 생성하기 위한 인터페이스를 제공합니다. 시스템이 객체 생성 방식에 독립적이어야 할 때 유용합니다.

실제 시나리오: 빅토리아풍, 현대풍 등 다양한 유형의 가구 세트를 판매하는 가구점을 상상해 보세요. 각 세트에는 의자, 소파 등의 제품이 포함되어 있습니다.

// Abstract Products
interface Chair {
    void sitOn();
}

interface Sofa {
    void lieOn();
}

// Concrete Products
class VictorianChair implements Chair {
    @Override
    public void sitOn() {
        System.out.println("Sitting on a Victorian chair.");
    }
}

class ModernChair implements Chair {
    @Override
    public void sitOn() {
        System.out.println("Sitting on a Modern chair.");
    }
}

class VictorianSofa implements Sofa {
    @Override
    public void lieOn() {
        System.out.println("Lying on a Victorian sofa.");
    }
}

class ModernSofa implements Sofa {
    @Override
    public void lieOn() {
        System.out.println("Lying on a Modern sofa.");
    }
}

// Abstract Factory
interface FurnitureFactory {
    Chair createChair();
    Sofa createSofa();
}

// Concrete Factories
class VictorianFurnitureFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return new VictorianChair();
    }

    @Override
    public Sofa createSofa() {
        return new VictorianSofa();
    }
}

class ModernFurnitureFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return new ModernChair();
    }

    @Override
    public Sofa createSofa() {
        return new ModernSofa();
    }
}

// Client code
public class Main {
    private static void createFurniture(FurnitureFactory factory) {
        Chair chair = factory.createChair();
        Sofa sofa = factory.createSofa();
        chair.sitOn();
        sofa.lieOn();
    }

    public static void main(String[] args) {
        FurnitureFactory victorianFactory = new VictorianFurnitureFactory();
        createFurniture(victorianFactory);

        FurnitureFactory modernFactory = new ModernFurnitureFactory();
        createFurniture(modernFactory);
    }
}
로그인 후 복사

3. 빌더

빌더 패턴은 복잡한 객체의 구성과 표현을 분리하므로 동일한 구성 프로세스로 다양한 표현을 만들 수 있습니다. 이는 선택적인 속성이 많은 객체를 생성하는 데 특히 유용합니다.

실제 시나리오: 고객이 다양한 토핑, 크기, 크러스트 유형으로 피자를 맞춤 설정할 수 있는 온라인 피자 주문 시스템을 생각해 보세요.

// Product
class Pizza {
    private String dough = "";
    private String sauce = "";
    private String topping = "";

    public void setDough(String dough) { this.dough = dough; }
    public void setSauce(String sauce) { this.sauce = sauce; }
    public void setTopping(String topping) { this.topping = topping; }

    @Override
    public String toString() {
        return "Pizza [dough=" + dough + ", sauce=" + sauce + ", topping=" + topping + "]";
    }
}

// Builder Interface
interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildTopping();
    Pizza getPizza();
}

// Concrete Builders
class HawaiianPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public HawaiianPizzaBuilder() {
        this.pizza = new Pizza();
    }

    @Override
    public void buildDough() { pizza.setDough("cross"); }
    @Override
    public void buildSauce() { pizza.setSauce("mild"); }
    @Override
    public void buildTopping() { pizza.setTopping("ham+pineapple"); }
    @Override
    public Pizza getPizza() { return this.pizza; }
}

class SpicyPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public SpicyPizzaBuilder() {
        this.pizza = new Pizza();
    }

    @Override
    public void buildDough() { pizza.setDough("pan baked"); }
    @Override
    public void buildSauce() { pizza.setSauce("hot"); }
    @Override
    public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
    @Override
    public Pizza getPizza() { return this.pizza; }
}

// Director
class Waiter {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
    public Pizza getPizza() { return pizzaBuilder.getPizza(); }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildTopping();
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
        PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

        waiter.setPizzaBuilder(hawaiianPizzaBuilder);
        waiter.constructPizza();
        Pizza pizza1 = waiter.getPizza();
        System.out.println("Pizza built: " + pizza1);

        waiter.setPizzaBuilder(spicyPizzaBuilder);
        waiter.constructPizza();
        Pizza pizza2 = waiter.getPizza();
        System.out.println("Pizza built: " + pizza2);
    }
}
로그인 후 복사

4. 프로토타입

프로토타입 패턴은 프로토타입이라고 하는 기존 개체를 복사하여 새 개체를 만드는 데 사용됩니다. 이 패턴은 새로운 객체를 생성하는 데 드는 비용이 클 때 유용합니다.

실제 시나리오: 모양을 생성, 복제, 편집할 수 있는 그래픽 편집기를 생각해 보세요.

import java.util.HashMap;
import java.util.Map;

// Prototype
abstract class Shape implements Cloneable {
    private String id;
    protected String type;

    abstract void draw();

    public String getType() { return type; }
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

// Concrete Prototypes
class Rectangle extends Shape {
    public Rectangle() { type = "Rectangle"; }
    @Override
    public void draw() { System.out.println("Drawing a Rectangle."); }
}

class Circle extends Shape {
    public Circle() { type = "Circle"; }
    @Override
    public void draw() { System.out.println("Drawing a Circle."); }
}

// Prototype Registry
class ShapeCache {
    private static Map<String, Shape> shapeMap = new HashMap<>();

    public static Shape getShape(String shapeId) {
        Shape cachedShape = shapeMap.get(shapeId);
        return (Shape) cachedShape.clone();
    }

    public static void loadCache() {
        Rectangle rectangle = new Rectangle();
        rectangle.setId("1");
        shapeMap.put(rectangle.getId(), rectangle);

        Circle circle = new Circle();
        circle.setId("2");
        shapeMap.put(circle.getId(), circle);
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        ShapeCache.loadCache();

        Shape clonedShape1 = ShapeCache.getShape("1");
        System.out.println("Shape: " + clonedShape1.getType());

        Shape clonedShape2 = ShapeCache.getShape("2");
        System.out.println("Shape: " + clonedShape2.getType());
    }
}
로그인 후 복사

5. 싱글톤

싱글턴 패턴은 클래스에 인스턴스가 하나만 있도록 보장하고 이에 대한 전역 액세스 지점을 제공합니다. 이 패턴은 로깅, 캐싱 및 스레드 풀에 일반적으로 사용됩니다.

실제 시나리오: 하나의 인스턴스만 모든 인쇄 작업을 관리해야 하는 프린터 스풀러를 상상해 보세요.

class PrinterSpooler {
    private static PrinterSpooler instance;

    private PrinterSpooler() {
        // private constructor to prevent instantiation
    }

    public static PrinterSpooler getInstance() {
        if (instance == null) {
            instance = new PrinterSpooler();
        }
        return instance;
    }

    public void print(String document) {
        System.out.println("Printing document: " + document);
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        PrinterSpooler spooler1 = PrinterSpooler.getInstance();
        PrinterSpooler spooler2 = PrinterSpooler.getInstance();

        spooler1.print("Document 1");
        spooler2.print("Document 2");

        System.out.println("Are both spoolers the same instance? " + (spooler1 == spooler2));
    }
}
로그인 후 복사

참고자료

https://refactoring.guru/

https://www.javatpoint.com/design-patterns-in-java

https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial

위 내용은 완벽한 코드 생성: 생성 패턴 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿