2021-10-03

1003 토비의 스프링 - DI

 1. DI란

- 설계단계에서 클래스 레벨의 의존관계를 설정하는 것이 아니라, 런타임시에 의존관계를 설정하는 것.

2. 어떻게 가능한가?

- 설계 단계에서는 - 즉, 클래스레벨에서는 - 인터페이스만 의존하게 만들어두고, 런타임시에 factory혹은 컨테이너가 적절한 클래스를 생성하여, 생성자의 파라메터로 넣어주는 방식을 취한다. 

- 이것은 @Configuration만 바꾸어주면 가능하므로 - 코드를 일일이 고치지 않고, @Configuration의 수정만으로 의존관계 설정을 바꿀수있다!!

- 클래스간의 의존관계가아니라, 런타임시의 의존관계!! 동적 생성.

3. 응용

- 어떻게 응용할 수 있을까?


1) - 이를테면 db커넥션연결을 test시와 prod시를 분리하고 싶을 때 - 해당 커넥션에 따로따로 클래스를 만들고, @Configuraiton만 갈아끼운다는 전략이 있을수있다.

2)

- 또한 이를테면 관심사의 분리와 함께 응용할 수 있다.

- connection이 이루어질때마다 카운팅을 하는 요청을 생각해보자. 

그럼 커넥션이 이루어질때마다 코드를 수정해서 counter를 하고 , 다시 배포시에는 이걸 일일이 다 고쳐야 할까?! 아니다! 

- connection conter클래스를 따로 만들고, @Configuration에는 이 빈을 등록. 그리고 counter클래스의 생성자에 원래 쓰던 connection객체를 파라메터 생성자로 넘긴다.

그러면- 해당 커넥션이 맺어질떄마다관심사 분리로 counter가 1씩 증가.

실제 사용하는 커넥션 객체는 counter클래스의 생성자파라메터로 들어가있는 애가 커넥션을 수행하게 된다. !!!!

우와아아아.

2021-10-02

1002 토비의 스프링 학습

 


- 관심사의 분리. 

- 클라이언트는 내가 어떤 오브젝트를 사용하는지에 관심이없다. 

- 생성및 관계설정의 책임을 DaoFactory에게 위임한다.

- 원래는 각각의 클래스가 가지고 있던 의존성 책임을 -> DaoFactory에게 위임하고. 각각의 클래스는 본연의 비지니스 역할(콘택스트) 에만 집중할 수 있게된다.

- 결국 이 DaoFactory가 일종의 applicationContext로서 Ioc를 담당

- 프레임워크와 라이브러리의 차이는 제어의 흐름이 누구에게 있는가이다.

- 스프링은 '시간'을 '관계'를 담당해준다.

- 각종 오브젝트들을 적절한 시간에 만들고, 그 오브젝트들의 관계를 넣어준다.

- 우리는 비지니스 로직을 공개하지 않고 코드를 짤수있게 된다. 


- 위코드 확인 : 먼저 빈들을 싱글톤으로 등록해두고 -> 클라이언트가 해당 빈을 요청하면 -> getBean으로 찾아서 리턴한다. 


<용어 정리>

- bean:

스프링이 관리하는 오브젝트. 모든 객체가 빈이 아니라, 스프링이 직접 생명주기를 관리해야만 빈이라고 부른다. 

- bean factory

: 빈의 생명주기와 관계설정을 관리하는 클래스. 보통은 빈 팩토리 클래스를 막바로 사용하기보다 어플리케이션 콘텍스트 클래스를 불러서 사용한다. 

- applicationContext :

빈 팩토리를 상속한다. 빈생명주기 + 스프링이 제공하는 부가적인 기능 .




- 직접 제작한 DaoFactory 에서 만들어낸 userDao클래스는 각각 다른 메모리값이 할당된 별개의 인스턴스이다.

반면 @Configuration어노테이션을 통해 ApplicationContext를 생성하고,

이를 통해 Bean Factory 에서 불러낸 UserDao클래스는 동일하다. 테스트 케이스 초록불을 확인할 수 있다.

즉 스프링은 기본적으로 빈을 생성할때 싱글톤 전략을 사용한다. 하지만 왜일까?

- 번외) 동일성과 동등성

동일성 : 물리적 동일성. 같은 메모리상에 위치한다. 기본적으로 Object의 equals메소드는 동일성비교를 한다. (==)

동등성 : 논리적으로 같은가. 특정기준에 의해서 같은 인스턴스임을 보장한다. 단 이때 물리적 메모리 할당값은 다를 수 있다.  (equals)


- 스프링이 싱글톤으로 빈을 생성하는 이유

: 일단 기본적인 자바 싱글톤 전략을 직접 사용한다고 했을때 발생하는 문제점이 여럿있다.

private생성자이므로 상속불가하고 , 확장불가하고, 테스트 하기 어려워진다. 밖에서 생성할수가 없으니..

그리고 서버환경에서는 반드시 한개만 만들어진다고 보장할 수도 없다. 

-> 그렇지만, 싱글톤으로 생성하는 것 적극지지 - 왜냐하면, 유저의 요청에 따라 계속해서 클래스를 생성하면 메모리가 절대로 못버텨난다. 

- 스프링은 자바의 전통적인 싱글톤 전략 대신 Ioc를 이용하여 빈을 싱글톤으로 생성하고 관리한다. 


- 싱글톤사용시 주의점

: 멀티스레드 환경에서는 객체가 공유되기 때문에 주의한다 . 

따라서 -> 상태stateless해야한다. 변경되는 상태값을 가지고 있으면 안된다.

- 변경될수있는 값은 파라메터로 혹은 지역변수로 전달한다. 이건 스택에 쌓이는 정보이므로 공유되지 않으므로 괜찮다.

- 혹은 읽기전용 변수 / 혹은 다른 싱글톤객체를 인스턴스 변수로 가지고 있는 것은 괜찮다.

1002 리눅스 명령어 : date, uptime,passwd,uname

 # date

현재 날짜와 시간을 출력하는 명령어

- root사용자의 경우 -s (setting)옵션 사용하여 시간설정 가능

uptime

- 시간, 사용자, 접속율 통계

- 현재시간, 시스템 가동시간, 접속한 사용자 수, 평균 시스템 부하 확인가능

passwd

- 비밀번호 설정관련 명령어

- passwd [사용자이름] : 해당 유저의 패스워드 변경

uname

- 시스템 정보 출력

- uname -a : 모든 정보 출력

- 옵션 :

  -m, --machine   머신(하드웨어타입을 출력한다.

 

  -n, --nodename  머신의 네트웍 노드 호스트명을 출력한다.

 

  -r, --release   운영체제 릴리즈 넘버를 출력한다.

 

  -s, --sysname   운영체제의 이름을 출력한다.

 

  -v  운영체제의 버전을 출력한다.

 

   -p  프로세서 종류 출력. x86_64

  -s 커널(운영체제) 이름 출력. Linux

- o OS이름 출력. Linux/CLI

1002 Mock 객체 이용하기

 # 어떻게 의존성 관리를 할것인가?

## 더미 객체

- 해당 인터페이스 상속하는 더미 클래스를 임시로 만든다.

- 객체가 필요할 뿐 기능까지는 사용하지 않을때. 

- 해당 더미객체의 메소드 호출이 필요한 경우 정상적인 결과를 보장하지는 않음

## 테스트스텁

- 더미객체의 기능 + 특정한 값 혹은 메시지를 리턴해줌

- 특정 값 혹은 메시지가 하드코딩되어 있다.

## 페이크 객체(Fake Stub)

- 특정한 값, 메시지가 배열로 저장되어있다. 

- DB데이터의 아주아주 일부를 넣었다고 생각하면 될듯. 

## 사용포인트

- 해당 목 객체의 메소드가 몇번 호출되었는가

- 예상하는 결과값을 돌려주는가


## Mockito 프레임워크

- 메소드 호출 -> 수행 -> 값검증 

- mock객체 생성 -> when(조건 값 혹은 메소드 수행시) -> then( 이러이러한 결과여야 한다.)

- 예상값을 미리 안만들어도 되니까 편리하다.

- when then 으로 목객체 만들고 verify한다.

### 그외

- given / when / then 프레임워크 방식

- 목객체대신 실객체를 손쉽게 사용할 수 있다면 당연 그렇게 해야한다. 목객체를 사용하는 것에 매몰되어 실제 목표를 잊으면 안됨. 효율적으로 코드작성을 하자.

1002 좀더 나은 TDD

 ## 테스트 클래스 위치

### 소스폴더는 다르게, 패키지는 동일하게 , 컴파일된 클래스는 각각 다른 곳으로.

- 컴파일된 대상 클래스와 테스트 클래스의 위치가 서로 다르게 만들어지기 때문에 섞일 염려가 없다. 따라서 배포시에도 아주 빠르게 패키징이 가능하다.

- binary파일들이 위치하는 bin폴더(class들이 위치) 를 따로따로. output 지정하는 것임

### 아예 프로젝트 전체를 분리하기

- 테스트 수행시에 필요한 라이브러리를 분리하기 편하게 하기 위하여 선택하기도 함

### 스프링, 메이븐 프로젝트 방식

- 일반적으로 사용되는 방법. src폴더를 네개로 분류.

- /src/main/java 제품 코드가 들어가는 위치 

- /src/main/resources 제품 코드에서 사용하는 각종 파일, XML 등의 리소스 파일들 

- /src/test/java 테스트 코드가 들어가는 위치 

-/src/test/resources 테스트 코드에서 사용하는 각종 파일, XML 등의 리소스 파일들


# 테스트 메소드명 작성

- 한글을 사용해도 Ok.

- 시나리오 혹은 매개변수등을 추가로 입력해도 Ok.

# 테스트 케이스 작성시 고려사항

- happy day 시나리오를 작성 or Blue day시나리오 작성 등

- 동시성, 성능테스트 문제

- 다른 OS에서도 잘 돌아가는지

- GUI(뷰 영역) 테스트 문제

- 의존성문제 : 보통 목 객체 이용

1002 JUnit

 # 어노테이션

## 순서지정

- @Before, @After는 각각의 메소드별로

- @BeforeClass, @AfterClass는 테스트 클래스 한번씩만.

- 이를테면 tearDown메소드를 작성하여 커넥션 close를 @AfterClass로 작성할수있다.

## 예외 테스트 

- @Test(expected=NumberFormatException.class) 

## 시간 제한 테스트 

- @Test(timeout=1000)

## 테스트 무시 

- @Ignore("this method isn't working yet") 

## 러너

- RunWith(클래스이름.class) 

- JUnit Test 클래스를 실행하기 위한 러너(Runner)를 명시적으로 지정한다. 

- @RunWith는 junit.runner.Runner를 구현한 외부 클래스를 인자로 갖는다.

- 대표적인 스프링의 테스트러너는 자체적인 러너클래스를 구현하고 있다. 이를통해 스프링이 제공하는 새로운 테스트 기능도 사용할 수있게 된다.


1002 TDD 개발

 # TDD 필요성

- 개발자 본인의 우연적 판단에 근거한 프로그래밍을 방지하기 위함

# TDD 정의

- 비지니스코드를 작성하기 전에 테스트 코드를 작성하는 것

# 목표

- 제대로 동작하는 깔끔한 코드 작성

# 진행 방법

- 테스트 케이스 작성

- 테스트 케이스 통과할 수 있는 비지니스 코드 작성

- 리팩토링

- 반복

# 리팩토링 고려사항

- 중복코드 없는가?

- 이름 개선할 수 있는가?

- 소스코드 가독성은?

# JUnit 활용하기

- JUnit 라이브러리를 활용하여 데이터의 값을 직접확인후 테스트결과를 판단하는 것이 아니라  , 플래그의 색여부로 간단하게 테스트 통과여부 확인가능해진다.


## 흥미로웠던 점

- JUnit test class는 메소드 호출시마다 계속 자기자신의 생성자를 만든다.

각각의 테스트케이스를 독립적으로 수행하기 위해 클래스 자체를 리셋하는 것이다. 그래서 각각의 테스트 메소드들의 영향을 최소화한다.


메소드 4개, 생성자도 네번 각각 불리는 것을 확인할 수있다.

0328 fdisk, mkfs, mount, fstab

 1. 하드디스크를 붙인다. 2. fdisk -l로 하드디스크를 확인한다.  - interactiive한 커맨드모드 사용하여 (m) 붙인 하드디스크의 파티셔닝을 한다.  - 마지막에 w를 해야 실제로 반영이 된다.  3. mkfs를 하여 어떤 파일시스...