토비의 스프링 요약 3장 - 템플릿 (1)

  • 개방 폐쇠의 원칙 OCP : 확장에는 열려있고, 변경에는 닫혀있다.
  • 템플릿
    • 변경이 거의 일어나지 않으며,
    • 일정 패턴으로 유지되는 특성을 가진 부분 -> 자유롭게 변형되는 성질을 가진 부분으로 부터 독립

[ 3.1 다시 보는 초난감 DAO ]

예외처리 기능을 갖춘 DAO

  • jdbc에서 예외가 발생하면 잡아줘야됨 : 리소스반환 필수!
  • try-catch를 이용해 예외처리.-finally 를 통해 리소스반환을 한다.

[ 3.2 변하는 것과 변하지 않는 것 ]

JDBC try/catch/finally 를 그냥 사용할 경우 문제점

  • 중첩구조로 되어있어 매우 답답함
  • 중복된 코드
  • 실수 가능성

템플릿 메소드를 활용한 분리

  • 변하지 않는 부분은 남겨두고, 변하는 부분을 따로 빼서 Abstract method로 만듬.
  • 이 클래스를 상속받아 자식에서 Abstract method를 구현함.
  • 바뀌는 부분만 자식에서 갈아끼워가며 원하는 형태로 구현가능!
  • 단, 상속을 통해서만 가능하다는점..-> 다양한 제약사항

전략 패턴

  • 순서
    • 변하지 않는 맥락 context
    • preparedStatement를 만들어 줄 외부 기능 호출
    • 받아서 실행
    • 예외는 밖으로던지고,
    • 끝나면 적절히 닫아줌.
  • preparedStatement가 고정되어 있으면 OCP라고 할 수 없음

DI적용을 위한 클라이언트/컨텍스트 분리

  • 클라이언트가 전략을 정하고,
  • context에서는 그 전략을 받아서 실행만!

public void deleteAll() thorws SQLException{
	StatementStrategy st - new DeleteAllStatement(); //전략 설정
    jdbcContextWithStatementtStrategy(st);			// context에 DI넣어서 실행
}

[ 3.3 JDBC 전략 패턴의 최적화 ]

추가정보

  • delete와 달리 add 같은거는 어떤걸 추가할지에 대한 추가정보가 더필요함.
  • 그럴때는 입력 받아서 field로 만들어주면됨

public class AddStatement implements StatementStrategy{
	User user;
    
    public AddStatement(User user){
    	this,user = user;
    }
}
//....

로컬 클래스

  • 위와같이 작성하면 delete, add와 같이 DAO접근하는 전략하나마다 class가 생기게 된다
  • 어차피 UserDAO 밖에 사용하지 않으니 내부 클래스로 만들어준다

  • 자바에서 로컬 변수처럼 클래스를 선언 하는 방법임
  • 외부 파라메터는 final로 선언하는것이 좋음 : 외부변수를 받아 그대로사용, 변조 안함.
public void add(final User user) thorws SQLException{
	public class AddStatement implements StatementStrategy{
	//User user;
    /*
   		public AddStatement(User user){
    		this.user = user;
    	}
    */  
        public PreparedStatement makePreparedStatement(Connection c) {
        	//...
        	return ps;
        }
    }
    
    StatementStrategy st = new AddStatement(user);
    jdbcContextWithStatementStrategy(st);       
}

익명 내부 클래스

  • AddStatement()의 경우 add()를 위해 생성된 클래스로 이미 사용처가 정해짐 -> 이름 필요 없음.
  • delete도 마찬가지..
pulbic void deleteAll() throws SQLException{
	jdbcContextWithStatementStrategy(
    	new StatementStarategy(){
        	public PreparedStatement makePreparedStatement(Connection c) throws SQLException{
            	return c.prepareStatement("delete from users");
            }
        }    	
    )
}

[ 3.4 컨텍스트와 DI ]

...

+ Recent posts