※ TDD(테스트 주도 개발)
1. 테스트 코드를 먼저 작성해야 하는 이유?
-> 테스트 코드를 먼저 작성하는 개발 방법론은 테스트 주도 개발(Test-Driven Development, TDD)로 많이 불린다. 우리는 프로덕션 코드보다 테스트 코드를 먼저 작성해야 하는데, 그 이유는 다음과 같다.
1) 깔끔한 코드를 작성할 수 있다.
2) 장기적으로 개발 비용을 절감할 수 있다.
3) 개발이 끝나면 테스트 코드를 작성하는 것은 매우 귀찮다. 실패 케이스면 더욱 그렇다.
* 프로덕션 코드(Production Code) : 프로그램 구현을 담당하는 부분으로 사용자가 실제로 사용하는 소스코드를 의미한다.
* 테스트 코드(Test Code): 프로덕션 코드가 정상적으로 동작하는지 확인하는 코드를 의미합니다.
* 리팩토링(refactoring): 결과의 변경 없이 코드의 구조를 재조정함(기존 프로그램의 기능을 변경하지 않고 내부의 코드를 수정하는 것).-> 가독성을 높이고 유지보수를 편하게 한다.
2. TDD(Test-Driven Development) 방법 및 순서
1) 실패하는 작은 단위 테스트를 작성한다. 처음에는 컴파일조차 되지 않을 수 있다.
2) 빨리 테스트를 통과하기 위해 프로덕션 코드를 작성한다. 이를 위해 정답이 아닌 가짜 구현 등을 작성할 수도 있다.
3) 그다음의 테스트 코드를 작성한다. 실패 테스트가 없을 경우에만 성공 테스트를 작성한다.
4) 새로운 테스트를 통과하기 위해 프로덕션 코드를 추가 또는 수정한다.
5) 1~4단계를 반복하여 실패/성공의 모든 테스트 케이스를 작성한다.
6) 개발된 코드들에 대해 모든 중복을 제거하며 리팩터링 한다.
3. 일반 개발 방식 vs TDD 개발방식
1) 일반 개발 방식

보통의 개발 방식은 '요구사항 분석 -> 설계 -> 개발 -> 테스트 -> 배포'의 형태의 개발 주기를 갖는데 이러한 방식은 소프트웨어 개발을 느리게 하는 잠재적 위험이 존재한다.
그 이유로는,
1) 소비자의 요구사항이 처음부터 명확하지 않을 수 있다.
2) 따라서 처음부터 완벽한 설계는 어렵다.
3) 자체 버그 검출 능력 저하 또는 소스코드의 품질이 저하될 수 있다.
4) 자체 테스트 비용이 증가할 수 있다.
이러한 문제점들이 발생되는 이유는 어느 프로젝트든 초기 설계가 완벽하다고 말할 수 없기 때문이다.
보통 고객의 요구사항 또는 디자인의 오류 등 많은 외부 또는 내부 조건에 의해, 재설계하여 점진적으로 완벽한 설계로 나아간다.
하지만, 재설계로 인해 개발자는 코드를 삽입, 수정, 삭제하는 과정에서 불필요한 코드가 남거나 중복처리 될 가능성이 크다.
2) TDD 개발 방식

TDD와 일반적인 개발 방식의 가장 큰 차이점은 테스트 코드를 작성한 뒤에 실제 코드를 작성한다는 점이다.
디자인(설계) 단계에서 프로그래밍 목적을 반드시 미리 정의해야만 하고, 또 무엇을 테스트해야 할지 미리 정의(테스트 케이스 작성)해야만 한다.
1) 테스트 코드를 작성하는 도중에 발생하는 예외 사항(버그, 수정사항)들은 테스트 케이스에 추가하고 설계를 개선한다. 2) 이후 테스트가 통과된 코드만을 코드 개발 단계에서 실제 코드로 작성한다.
이러한 반복적인 단계가 진행되면서 자연스럽게 코드의 버그가 줄어들고, 소스코드는 간결해진다.
또한, 테스트 케이스 작성으로 인해 자연스럽게 설계가 개선됨으로 재설계 시간이 절감된다.
※ DAO (Data access Object)
-> 컨트롤러와 DB에 사이에서 둘을 연결해주는 CRUD 메서드들이 있는 클래스이다.(TDD파일에 @Test 메서드들뺴고 나머지 CRUD 메서드들을 예외처리해주고 만들어준 클래스. 해당클래스의 인터페이스도 만들어주고 그거에 구현한 클래스가 되게 해주면된다.) 그리고 DAO 들어가는 메서드들은 try / catch/finally 로예외처리 해주는게 좋다.
1) 하나의 테이블당 하나의 DAO만 생성한다.
2) DAO는 계속 new로 생성하게 되면 생성할 때마다 새로운 인스턴스를 생성하게돼서 공유할 수 없다.
그래서 Bean에 등록해 놓고 Autowired로 끌어와서 사용하면 된다.
3) Autowired : 위에 ContextConfiguration에 쓰여있는 링크에 있는 root-context.xml에 있는 Bean 객체를 끌고 와서 사용 할수 있게 해줍니다.
※ DAO 클래스 예외처리 하는 법
1) CRUD(select 메서드로 예를 들어보겠다.) 메서드 안에 try catch finally로 감쌀 영역을 모두 선택해 준 후 (거의 메서드 안에 있는 모든 코드들을 다 드래그해주면 된다고 봄) ctrl + alt+ t를 눌러 (try /catch/finally ) 자동으로 예외처리 구문을 나눠준다.


2) 이렇게 예외구문이 나눠졌으면 finally 부분에 보통 리소스 반납할 것들을 모아놓는데 보통 try 구문에 해당 변수들을 선언하면(지역변수 개념) finally는 다른 메서드로 보기 때문에 try에서 선언한 변수들은 finally에서 못 읽을 것이다. 그래서
finally에서 리소스 될 변수들을 try catch문 밖에다가 먼저 선언해 주고 사용하면 try 나 finally부분에서 다 쓸 수 있을 것이다.
-> Connection conn, PrepaerdStatement pstmt, ResyltSet rs; 이런 부분들을 말한다 (리소스 반납할 변수들)


3) finally에 리소스 반납할 부분들도 하나의 메서드로 묶어서 사용할 수 있다. 즉. close라는 메서드를 활용해 표현할 수 있다.
-> 메서드 밖에다가 close 메서드 만들어놓으면 다른 메서드의 finally 구문에서도 쓸 수 있을 것이다.
* AutoCloseable(가변배열, 다형성 나를 갖고 있는 것들을 다받겠다라는 뜻)
-> 매개변수로 몇 개 들어올지 모르니 '...'으로 매개변수 여러 개 들어와도 된다라고 명시해 준 거. acs가... 에 들어온 매개변수라 보면 된다.
-> 향상된 for문을 돌려서 acs에 배열을 ac에 대입해 돌려준다.
-> 리소스 반납은 리소스를 사용하고 있는 것을 닫는다는 소리 인다 즉 try에서 사용한 리소스들을 닫아준다는 뜻이고,
이건 리소스가 null값이 아니라 어떤 값들을 담고 있다는 뜻이다 , 그래서 이 값들이 null이 아니면 해당 리소스들을. close()
닫아준다라고 명시한 것이다. (ac!= null) ac.close() 이 부분을 뜻함.
* 그리고 DAO 에 들어갈 메서드들은 모두 try catch finally 문으로 예외처리 해주는 걸 추천한다.

※ DAO 만드는 순서
1. DAO 클래스를 만들고 여기에 TDD 했던 거를 복사해서 붙여 넣기하고 @Test 붙은 메서드들만 다 삭제해 준다.
->( DB 로보낼 CRUD 메서드들만 DAO에 남게 될 것이다.)
->(DAO 클래스로 옮긴 TDD 들은 @Test 메서들 다 지워주고 나머지 CRUD 메서드들은 try catch finally 구문으로 예외처리 다해줘야 한다. 예외처리는 해주고 인터페이스화 하는 게 좋다. -> '※ DAO 클래스 예외처리 하는 법' 이거 참조)
2. 현재파일 interface화 하기 (DAO의 public class 들어간 클래스명, 우클릭 > Refactor > Extract Interface 클릭)

3. 창 나오면 'Rename Original Class~~ ' 선택
4. 구현 클래스 이름 부분 변경에 원래클래스명 뒤에 '~Impl'으로 설정 (Imple은 오타이고, Impl 로해야된다.)
5. 하단 Member 부분에 public인 메서드들 체크하고 > Refactor 클릭

DAO 결과 1:DAO 클래스 (Impl 해준 거)

DAO 결과 2: DAO 인터페이스

* 위에 처럼 DAO 만들면 Imlp DAO 클래스 한 개와 Interface DAO 가 생성될 것이다.
※ 어노테이션
-> 영속성 콘테스트 관리를 위해 Bean을 등록하여야 한다. 기존의 Spring에서는 xml을 활용하여 Bean을 등록하였지만 프로젝트 규모가 커지게 되면 xml 사용에는 한계가 존재한다. 그래서 탄생하게 된 것이 어노테이션을 이용하여 Bean을 등록하는 것이다. Bean 등록 어노테이션인 @Bean, @Configuration, @Component에 대해 알아보자!
-> @Component는 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 Annotation입니다.
(아래 어노테이션들을 명시하면 해당 클래스는 bean객체로 등록된다 (즉 static 화 된다 보면 됨. 프로그램생성 시 바로 쓸 수 있게 메모리에 할당되는 거.)
-> @Component 관련 어노테이션뿐만 아니라 , @Controller, @Configuration 어노테이션도 클래스에 명시하면 bean객체로 등록된다.
1) @Component - 이게 최상위이고 아래 @Controller, @Reponsitory, @Service 가 있다. (최상위보단 아래 개념으로 디테 일하게 명시해 주는 게 좋다)
Spring에서 관리되는 객체임을 나타내는 어노테이션
@Component 가 명시된 클래스들은 자동으로 스프링 빈으로 등록되고, 탐색 대상이 된다.
2) @Controller
web MVC 패턴에 사용되는 어노테이션
@xxxMapping 어노테이션을 해당 어노테이션 밑에서만 사용할 수 있음.
3) @Repository (Dao 한테 달아주면 됨)
퍼시트턴트 레이어, DB 같은 파일 외부 INPUT / OUTPUT 작업을 처리함. ->외부파일 허용함
4) @Service
비즈니스 로직(유효성 검사할 때) 함수에 사용된다.
3. @Repository 자동으로 쓸기 위한 환경설정
-> @Repository를 자동으로 Bean 객체로 등록할 수 있게 (auto scanning 할 수 있게)
-> servlet-context.xml의 맨 위 <bean 부분이랑, <context:component-scan base-package="com.bitstudy.app" /> 복 사해서 root-context.xml에 넣기.

1) 기존에 있던 bean 주석
2) servlet-context에 있던 bean 가져오기
3) beans:beans 쓰여있던 거 beans로 바꾸기
4) xmlns:beans 써있던거 xmlns로 바꾸기
5) servlet-context에 있던 context 가져오기
※ DAO 인식순서
1. 파일 리스트
1) DAO파일(인터페이스)
2) DAO파일(클래스)
3) 컨트롤러
2. 컨트롤러에 @Autowired로 Dao 끌어오기
-> Ex03_UserDao userDao = new Ex03_UserDaoImpl 이랑 같은 뜻
-> Ex03_UserDao 은 인터페이스 타입이고 Ex03_UserDaoImpl 가 인터페이스 Ex03_UserDao를 구현하고 있으니
다형성 방식을 이용해 인터페이스 타입인 userDao 참조변수에 Ex03_UserDaoImpl 클래스를 인스턴스화할 수 있다.
* 이렇게 @Autowired로 Dao 끌어온 것에 어떤 클래스를 쓸 건지 명시하는 것은 DAO 클래스 파일에 @Repository 붙여놓으면 해당 DAO 클래스를 '@Autowired Ex03_UserDao userDao; ' 명시한 컨트롤러에서 사용할 수 있습니다.

3. DAO 클래스 파일에 @Repository를 붙여놔서 컨트롤러에서 인식할 수 있게 함.
@Repository를 쓰면 @Autowired 쓴 컨트롤러에서 인식할 수 있다.

4. DAO파일이 인터페이스가 있고 클래스파일도 따로 있는 이유는 만약 DB를 mysql도 사용하고 oracle도 사용하는 등등 여러 db를 사용하게 된다면 인터페이스로 각각 메서드 이름을 규격화시켜 놓고, DAO파일을 db 마다 만들어놓고 컨 트롤러에서 다형성을 이용해 인터페이스로 불러오면 @Repository만 수정하면 유지보수하기 쉽기 때문이다.
'국비교육' 카테고리의 다른 글
국비지원 73일차 (spring - 빈(bean)개념 , Controller,Service,Repository) (0) | 2023.11.07 |
---|---|
국비지원 72일차 (스프링_MyBatis(환경설정, 연결 )) (1) | 2023.11.04 |
국비지원 70일차(스프링 - executeQuery, executeUpdate) (0) | 2023.11.02 |
국비지원 69일차 (스프링 - DB연결하기) (0) | 2023.10.31 |
국비지원 68일차(스프링 - cookie,session ) (1) | 2023.10.30 |