디자인 패턴 - 생성 패턴

참고 링크

Books

개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴

Joshua Bloch(2018). Effective Java(3rd ed.). Addison-Wesley Professional.

Articles

The Catalog of Design Patterns

Posts

디자인 패턴

[Design Pattern] 디자인 패턴 정의와 종류에 대하여


디자인 패턴


Creational Patterns 생성 패턴


<5가지 생성 패턴>
- Factory Method 팩토리 메서드 패턴
- Abstract Factory 추상 팩토리 패턴
- Builder 빌더 패턴
- Prototype 원형 패턴
- Singleton 싱글톤 패턴


Factory Method 팩토리 메서드 패턴


방법 2를 활용한 예제

20210805-034907

interface Pizza {
    public void prepare();
    public void bake();
    public void box();
}
abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);    // factory method 사용
        pizza.prepare();
        pizza.bake();
        pizza.box();
        return pizza;
    }

    // factory method
    abstract Pizza createPizza(String type);
}

class NYPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if ("cheese".equals(type)) {
            return new NYStyleCheesePizza();
        } else if ("pepperoni".equals(type)) {
            return new NYStylePepperoniPizza();
        }
        return null;
    }
}

class ChicagoPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        if ("cheese".equals(type)) {
            return new ChicagoStyleCheesePizza();
        } else if ("pepperoni".equals(type)) {
            return new ChicagoStylePepperoniPizza();
        }
        return null;
    }
}


사용

PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();

Pizza pizza = nyStore.orderPizza("cheese");
Pizza pizza1 = chicagoStore.orderPizza("pepperoni");




Abstract Factory 추상 팩토리 패턴


추상 팩토리 패턴 정의 예시 - JAVA JDBC API 구조

20210805-180119




Builder 빌더 패턴

Effective Java - 아이템 2에서 소개되는 Builder 패턴을 기준으로 설명

점층적 생성자 패턴

public class User {
    private final String name;
    private final String location;
    private final String hobby;

    public User(String name) {
        this(name, "x", "x");
    }

    public User(String name, String location) {
        this(name, location, "x");
    }

    public User(String name, String location, String hobby) {
        this.name = name;
        this.location = location;
        this.hobby = hobby;
    }        
}

자바 빈즈 패턴(JavaBeans Pattern)

public class User {
    private String name = "이름";
    private String address = "주소";
    private String hobby = "취미";

public User() {}

/// setter

User user = new User();
user.setName("Poogle");
user.setAddress("Seoul");
user.setHobby("driving");


public class User {
    private final String name;
    private final String address;
    private final int age;
    private final String hobby;

    public static class Builder {
        //필수 매개변수
        private final String name;
        private final int age;

        //선택 매개변수 - 기본값으로 초기화
        private String address = "주소";
        private String hobby = "취미";

        public Builder(Strng name, int age) {
            this.name = name;
            this.age = age;
        }

        public Builder address(String val) {
            address = val;
            return this;
        }

        public Builder hobby(String val) {
            hobby = val;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }

    private User(Builder builder) {
        name = builder.name;
        age = builder.age;
        address = builder.address;
        hobby = builder.hobby;
    }
}

사용

User user = new User.Builder("Poogle", 27) //필수값
                    .address("Seoul")
                    .hobby("driving")
                    .build(); //build로 객체 생성

장점



Prototype 원형 패턴




Singleton 싱글톤 패턴


Java와 Spring 싱글톤 차이점


싱글톤 패턴의 문제점


이른 초기화 방식 (Eager Initialization)

public class Singleton {
    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return uniqueInstance;
    }
}


늦은 초기화 방식 (Lazy Initialization - synchronized)

    public class Singleton {
        private static Singleton uniqueInstance;

        private Singleton() {}

        public static synchronized Singleton getInstance() {
            if(uniqueInstance == null) {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
    }


DCL 방식 (Lazy initialization - Double Checking Locking)

    public class Singleton {
        private volatile static Singleton uniqueInstance;

        private Singleton() {}

        public Singleton getInstance() {
            if(uniqueInstance == null) {
                synchronized(Singleton.class) {
                    if (uniqueInstance == null) {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }


열거 타입 방식 (Lazy Initialization - Enum)

    public enum Singleton {
        INSTANCE;
    }