bumdream / morning_study

1 stars 0 forks source link

2. 디자인 패턴공부 #7

Open bumdream opened 6 years ago

bumdream commented 6 years ago

자기가 원하는 거 공부 (1개 또는 2개)

hongsukchoi commented 6 years ago

프록시 패턴(Proxy Pattern)

프록시 = 대리자

어떤 작업을 할 때, 구체적으로 인터페이스를 사용하고 실행시킬 클래스에 대한 객체가 들어갈 자리에 대리자 객체를 대신 투입해 작업을 대신 시키는 패턴.

왜 쓸까?

일단 프록시 패턴의 특징은 다음 4가지와 같다

쓰는 이유는 4번째가 핵심이라고 생각하는데, 데이터가 크거나 해서 로딩작업이 느릴 때 등 작업시간이 긴 경우,

일단 완료된 상태까지만 유저에게 제공하거나 그 시간 동안 다른 작업을 하려는 경우에 쓸모 있을 것 같다.

주의할 점: 프록시는 흐름제어만 할 뿐 결과값을 조작하거나 변경시키면 안됩니다.

예시

2018-08-03 10 00 07

프록시가 실제 작업 객체를 필드로 가지고 있으면서 해당 함수를 호출한다. 그렇기 때문에 작업 딜레이 동안 프록시는 다른 일을 할 수 있다. 2018-08-03 10 01 16

출처: 림키

bumdream commented 6 years ago

전략패턴 (Strategy Pattern)

전략패턴을 구성하는 3가지 요소

전략패턴 적용사례 (SubtitleParser)

public interface SubtitleParser {
    List<SubtitleObject> parse(String subtitlePath) throws IOException;
}
bumdream commented 6 years ago

싱글톤패턴 (Singleton)

Eaeeger initialization (이른 초기화 방식)

package SingleTonExample;

public class EagerInitialization {

    //private static으로 선언
    private static EagerInitialization instance = new EagerInitialization();

    //생성자
    private EagerInitialization() {}

    //인스턴스 리턴
    public static EagerInitialization getInstance() {
        return instance;
    }

}

lazy initialization

thread safe initialization

public class ThreadSafeInitalization {

    private static ThreadSafeInitalization instance;
    private ThreadSafeInitalization () {}

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

    public void print () {
        System.out.println("It's print() method in ThreadSafeInitalization instance.");
        System.out.println("instance hashCode > " + instance.hashCode());
    }

}

initialization on demand holder idiom

enum initialization

public enum EnumInitialization {
    INSTANCE;
    static String test = "";
    public static EnumInitialization getInstance() {
        test = "test";
        return INSTANCE;
    }
}

java reflection

hongsukchoi commented 6 years ago

탬플릿 콜백 패턴(Template Callback Pattern)

전략 패턴에 익명 내부 클래스를 가미한 패턴

하나의 컨텍스트에서만 사용하는 전략일 때, 불필요한 클래스 생성을 방지할 수 있다.

다음은 자주 쓰는 탬플릿 콜백 패턴 형태

Strategy.java (전략 인터페이스 정의)

public interface Strategy {
void runStrategy();
}

SoliderWithRefactoring.java (전략을 사용할 컨텍스트 + 내부 익명 클래스 이관 당함)

public class SoliderWithRefactoring {
    void runContext(String StrategySound) {

        execute(StrategySound).runStrategy();
    }

    private Strategy execute(final String StrategySound) {
        return new Strategy() {

            @Override
            public void runStrategy() {
                System.out.println(StrategySound);       
            }
        };

    }
}

Client.java (클라이언트 Solider안에 내부 익명 클래스를 이관했다. -> 코드가 깔끔해짐)


public class Client {

    public static void main(String[] args) {
        SoliderWithRefactoring rambo = new SoliderWithRefactoring();

        rambo.runContext("탕! 탕탕탕!");

        rambo.runContext("수류탄 투척~! 쾅!!!");
    }
}

Strategy 인터페이스를 통해 OCP와 DIP를 지켰다.

hongsukchoi commented 6 years ago

싱글톤 패턴 리뷰

"해당 클래스의 인스턴스가 하나만 만들어지고,

어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴"

출처: http://hjjungdev.tistory.com/4 [우아한 프로그래밍]

Synchronized

(thread safe initialization 읽다가 헷갈려서 다시 찾아봄)

Synchronized 메소드를 사용하는 동안에 다른 스레드에서 해당 메소드를 가진 객체를 사용할 수 없음

출처: 해시코드

bumdream commented 6 years ago

Adapter Pattern(어댑터 패턴)

예시

Volt class

public class Volt {
    private int volts;

    public Volt(int v) {
        this.volts = v;
    }

    public int getVolts() {
        return this.volts;
    }

    public void setVolts(int volts) {
        this.volts = volts;
    }
}

socket class

public class Socket {
    public Volt getVolt() {
        return new Volt(120);
    }
}

설명

adapter class

public interface SocketAdapter {
    public Volt get120Volt();
    public Volt get12Volt();
    public Volt get3Volt();
}

adapter클래스 구현방법

예시

}

hongsukchoi commented 6 years ago

팩토리 메서드 패턴(Factory Method Pattern)

팩토리에서 객체를 생성해 반환하는 패턴.

2018-08-07 9 50 20 Concrete Creator(팩토리)에서 Concrete Product(객체)를 생성, 반환함.

public class ConcreteFactory extends Factory{

    @Override
    public Product createProduct(String name) {

        switch (name) {
            case "AAA": return new ProductA(); 
            case "BBB": return new ProductB();
        }      
        return null;
    }
}
public class Main {

    public static void main(String[] args) {

        ConcreteFactory factory = new ConcreteFactory();
        List<Product> products = new ArrayList<>();
        products.add(factory.createProduct("AAA"));
        products.add(factory.createProduct("BBB"));

        for(Product product : products){
              System.out.println(productA.getName()+"\n");
        }
    }

}

기본적으로 DIP를 지키는 패턴 (상위와 하위 객체는 구상 클래스에 의존하지 않고, 모두 동일한 추상화에 의존)

장점