본문 바로가기

Web/tip

[pattern] 내가 보려고 쓰는 예제

728x90

 

 

 

1. singleton

 

public class SampleSingleton {
    private static SampleSingleton INSTANCE;

    private SampleSingleton() {
    }

    public static synchronized SampleSingleton getInstance() {
        if(INSTANCE == null) INSTANCE = new SampleSingleton();
        return INSTANCE;
    }
}

특징

  • private 으로 만듦
  • .getInstance() 를 만들어 한 번만 호출될때 오브젝트 생성, static 필드에 저장
  • 또는 초기값으로 미리 인스턴스 생성하여 static 필드에 저장해둠
  • .getInstance() 로만 접근해서 가져감
  • stateless 해야한다(무상태) 의도가 있든 없든 어떤 상태가 되든 안되든 변경되면 안됨

 

 

2. DI

public class SampleDao {

	SampleConnector sampleConnector;
    
    // DI (Dependency Injection) 
    public SampleDao(SampleConnector sampleConnector) {
        this.sampleConnector = sampleConnector;
    }

    ...

 

 

3. DL

public class SampleDao {

	SampleConnector sampleConnector;
    
    public SampleDao() {
    	ApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(DaoFactory.class);

        this.sampleConnector = applicationContext.getBean(SampleConnector.class);
    }

    ...

 

 

4. Factory

@Configuration
// `@Configuration`은 `애플리케이션 컨텍스트` 혹은 `빈 팩토리`가 사용할 설정 정보라는 표시이다.
// `@Component`와는 다르게 의존 정보를 설정할 수 있는 곳이다.
// `@Component`에서 아래와 같이 내부에서 직접 생성하는 메소드를 사용하면,
// `Method annotated with @Bean called directly. use dependency injection` 이라는 에러 문구가 뜬다.
// `@Configuration`에서는 내부에서 직접 생성하는 메소드를 사용해도 빈 의존관계로 취급된다.
public class DaoFactory {
    @Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시이다.
    public SampleDao sampleDao() {
        return new SampleDao(sampleConnector());
    }

    @Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시이다.
    public SampleConnector sampleConnector() {
        return new ASampleConnector();
    }
}

 

 

 

5. LocalClass

 

public void add(User user) throws SQLException {
    class AddStatement implements StatementStrategy{
        @Override
        public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
            PreparedStatement ps = c.prepareStatement(
                    "insert into users(id, name, password) values (?, ?, ?)"
            );

            ps.setString(1, user.getId());
            ps.setString(2, user.getName());
            ps.setString(3, user.getPassword());

            return ps;
        }
    }

    jdbcContextWithStatementStrategy(new AddStatement());
}

 

 

 

6. 익명내부클래스

public void add(User user) throws SQLException {
        StatementStrategy stmt = c -> {
            PreparedStatement ps = c.prepareStatement(
                    "insert into users(id, name, password) values (?, ?, ?)"
            );

            ps.setString(1, user.getId());
            ps.setString(2, user.getName());
            ps.setString(3, user.getPassword());

            return ps;
        };

        jdbcContextWithStatementStrategy(stmt);
    }

 

 

 

7. Generic을 이용한 콜백 인터페이스

public interface LineCallback<T> {
    T doSomethingWithLine(String line, T value);
}
public class Calculator {
    public <T> T lineReadTemplate(String filepath, LineCallback<T> callback, T initValue) throws IOException {
        BufferedReader br = null;

        try {
            String line = null;
            T result = initValue;
            br = new BufferedReader(new FileReader(filepath));

            while((line = br.readLine()) != null) {
                result = callback.doSomethingWithLine(line, result);
            }

            return result;
        } catch(IOException e) {
            System.out.println("e.getMessage() = " + e.getMessage());
            throw e;
        }
        finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    System.out.println("e.getMessage() = " + e.getMessage());
                }
            }
        }
    }

    public Integer calcSum(String filePath) throws IOException {
        LineCallback<Integer> callback = ((line, value) -> Integer.valueOf(line) + value);
        return this.lineReadTemplate(filePath, callback, 0);
    }

    public Integer calcMultiply(String filePath) throws IOException {
        LineCallback<Integer> callback = ((line, value) -> Integer.valueOf(line) * value);
        return this.lineReadTemplate(filePath, callback, 1);
    }

    public String concatenate(String filePath) throws IOException {
        LineCallback<String> callback = ((line, value) ->  value + line);
        return this.lineReadTemplate(filePath, callback, "");
    }

    public Double calcDivide(String filePath, Double initValue) throws IOException {
        LineCallback<Double> callback = ((line, value) -> Double.valueOf(line) * value);
        return this.lineReadTemplate(filePath, callback, initValue);
    }
}
LineCallback<T> callback 파라미터에서 받은 타입으로 T 타입을 설정하게 된다.
파라미터 중, callbackinitValue 모두 같은 T 타입을 사용하므로 두 파라미터의 타입은 일치해야 한다.
728x90