좌충우돌 개발

2017-08-28_TIL

|
사파리 개발자 도구 활성화

사파리의 환경설정 - 고급 - 메뉴 막대에서 개발자용 메뉴보기

사파리 콘솔에 아래 경고 발생
[Warning] WARNING: cdn.mathjax.org has been retired. Check https://www.mathjax.org/cdn-shutting-down/ for migration tips. (MathJax.js, line 32)

_includes/head.html 부분을 아래와 같이 수정 한다. 해당 js파일의 제공 url의 서비스 종료로 해당 경고 발생

<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js/...">   
MathJax

블로그에 수학식을 표현할 때 사용한다.

2017-08-25_TIL

|

블로그 테마적용

테마 적용 방법

  • 마음에 드는 테마를 github에서 zip파일 형태로 다운 받는다
  • 압축을 풀고 기존에 있던 _post를 제외하고 덮어 씌운다.
  • 문제점 : 덮어 씌우고 jekyll build를 실행하였을 때 에러가 발생
  • 해결 : 디렉토리내의 gem파일을 삭제 후 build한다.

폰트 변경

  • _scss/base/_global.scss 파일을 수정

permalink : 퍼머링크(permalink)는 인터넷에서 특정 페이지에 영구적으로 할당된 URL 주소라고 한다

  • 블로그 태그 적용 미적용의 차이점
  • 적용 : http://127.0.0.1:4000/til/2017/08/25/test/
  • 미적용 : http://127.0.0.1:4000/til%20(today%20i%20learned)/2017/08/25/test/

작성한 글이 보이지 않는다

  • post의 date 일자가 현재 시간보다 미래이면 글이 보이지 않는다.

Toby 스프링3 1부 2장 테스트

|

2장 테스트

테스트란 내가 예상하고 의도 했던 대로 코드가 정확히 동작하는 지를 확인해서, 만든 코드를 확신할 수 있게 해주는 작업이다.

@Test
@Test expected : 보통의 테스트와 반대로, 정상적으로 테스트 메소드를 마치면 테스트가 실패하고, expected로 지정한 예외가 던저지면 테스트는 성공하게 된다.

포괄적인 테스트
네거티브 테스트를 먼저 만들어라

테스트가 이끄는 개발

  • 기능설계를 위한 테스트
  • 조건 / 행위 / 결과
테스트 주도 개발 (TDD: Test Driven Development)
  • ‘실패한 테스트를 성공시키기위한 목적이 아닌 코드는 만들지 않는다’ 는 것이 TDD의 기본 원리이다.
  • 테스트 작성하고 이를 성공시키는 코드를 만드는 작업의 주기를 가능한 한 짧게 가져가도록 권장한다.
Junit의 테스트 수행 방식
  1. 테스트 클래스에서 @Test가 붙은 public 이고 void형이며 파라미터가 없는 테스트 메소드를 모두 찾는다.
  2. 테스트 클래스의 오브젝트를 하나 만든다.
  3. @Before가 붙은 메소드가 있으면 실행한다.
  4. @Test가 붙은 메소드를 하나 호출하고 테스트 결과를 저장해둔다.
  5. @After가 붙은 메소드가 있으면 실행한다.
  6. 나머지 테스트 메소드에 대해 2~5번을 반복한다.
  7. 모든 테스트의 결과를 종합해서 돌려준다.

기억할 점 :
각 테스트 메소드를 실행할 때마다 테스트 클래스의 오브젝트를 새로 만든다는 점이다.
한번 만들어진 테스트 클래스의 오브젝트는 하나의 테스트 메소드를 사용하고 나면 버려진다.
각 테스트가 독립적으로 실행 됨을 보장하기 위해서 새로 오브젝트를 생성하여 테스트를 진행한다.

픽스처 : 테스트를 수행할 때 필요한 정보나 오브젝트를 픽스처(fixture)라고 한다. 일반적으로 픽스처는 여러 테스트에서 반복적으로 사용되기 때문에 @Before 메소드를 이용해 생성해두면 편리하다.

@BeforeClass

@RunWith 는 JUnit 프레임워크의 테스트 실행 방법을 확장할 때 사용하는 애노테이션이다. @ContextConfiguration 은 자동으로 만들어줄 애플리케이션 컨텍스트의 설정 파일 위치를 지정한 것이다. @Autowired 가 붙은 인스턴스 변수가 있으면 텍스트 컨텍스트 프레임워크는 변수 타입과 일치하는 컨텍스트 내의 빈을 찾는다. 타입이 일치하는 빈이 있으면 인스턴스 변수에 주입해준다.
@Autowired는 같은 타입의 빈이 두 개 이상 있는 경우에는 타입만으로는 어떤 빈을 가져올지 결정할 수 없다.

스프링 애플리케이션 컨텍스트는 초기화할 때 자기 자신도 빈으로 등록한다.

Interface를 두고 DI를 해야하는 이유
  1. 소프트웨어 개발에서 절대로 바뀌지 않는 것은 없기 때문이다.
  2. 클래스의 구현 방식은 바뀌지 않더라도 인터페이스를 두고 DI를 적용하게 되면 다른 차원의 서비스 기능을 도입할 수 있기 때문이다.
  3. 테스트 때문이다. DI는 테스트가 작은 단위의 대상에대해 독립적으로 만들어지고 실행되게 하는데 중요한 역할을 한다.

@DirtiesContext: 테스트 메소드에서 애플리케이션 컨텍스트의 구성이나 상태를 변경한다는 것을 테스트 컨텍스트 프레임워크에 알려준다.

  • Test시 테스트용 설정파일을 두고 하는게 좋다
  • 컨테이너 없는 DI 테스트

침투적 기술과 비침투적 기술 침투적 기술은 기술을 적용했을 때 애플리케이션 코드에 기술 관련 API를 등장하거나, 특정한 인터페이스나 클래스를 사용하도록 강제하는 기술을 말한다. 침투적 기술을 사용하면 애플리케이션 코드가 해당 기술에 종속되는 결과를 가져온다. 반면에 비침투적인기술은 애플리케이션 로직을 담은 코드에 아무런 영향을 주지 않고 적용이 가능하다. 따라서 기술에 종속적이지 않은 순수한 코드를 유지할 수 있게 해준다. 스프링은 이런 비침투적인 기술의 대표적인 예이다.

DI를 이용한 테스트 방법 선택 항상 스프링 컨테이너 없이 테스트할 수 있는 방법을 가장 우선적으로 고려하자. 이 방법이 테스트 수행 속도가 가장 빠르고 테스트 자체가 간결하다. 테스트를 위해 필요한 오브젝트의 생성과 초기화가 단순하다면 이 방법을 먼저 고려해야 한다.

여러 오브젝트와 복잡한 의존관계를 갖고 있는 오브젝트를 테스트해야 할 경우가 있다. 이때는 스프링의 설정을 이용한 DI 방식의 테스트를 이용하면 편리하다. 테스트에 애플리케이션 설정 파일을 사용하는 경우는 테스트 전용 설정파일을 따로 만들어 사용하는 편이 좋다.

테스트 설정을 따로 만들었다고 하더라도 때로는 예외적인 의존관계를 강제로 구성해서 테스트해야 할 경우가 있다. 이때는 컨텍스트에서 DI를 받은 오브젝트에 다시 테스트 코드로 수동 DI해서 테스트하는 방법을 사용하면 된다. 테스트 메소드나 클래스에 @DirtiesContext 애노테이션을 붙이는 것을 잊지 말자

학습 테스트(learning test) 로 배우는 스프링 학습 테스트의 목적 : 자신이 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히려는 것이다.

학습 테스트의 장점

  • 다양한 조건에 따른 기능을 손쉽게 확인해 볼 수 있다.
  • 학습 테스트 코드를 개발 중에 참고할 수 있다.
  • 프레임워크나 제품을 업그레이드 할때 호환성 검증을 도와준다.
  • 테스트 작성에 대한 좋은 훈련이 된다.
  • 새로운 기술을 공부하는 과정이 즐거워진다.

Static import 란 : 다른 class에 정의된 static filed나 static method를 현재 class에서 정의 된것처럼 사용하기 위해 사용한다.

Import static org.junit.Assert.assertThat\*
assertThat(is(not(sameInstance(testObject))  /* 클래스 내의 메소드처럼 사용 가능하다*/

sameInstance(object)
or(is())

is()는 equals() 비교를 해서 같으면 성공하지만 is(not())은 반대로 같이 않아야 성공한다.

버그 테스트 : 코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트를 말한다

  • 테스트 완성도를 높여준다
  • 버그의 내용을 명확하게 분석하게 해준다
  • 기술적인 문제를 해결하는 데 도움이 된다.

정리

  • 테스트는 자동화되어야 하고, 빠르게 실행할 수 있어야 한다
  • main() 테스트 대신 JUnit 프레임워크를 이용한 테스트 작성이 편리하다
  • 테스트 결과는 일관성이 있어야 한다. 코드의 변경 없이 환경이나 테스트 실행 순서에 따라서 결과가 달라지면 안 된다.
  • 테스트는 포괄적으로 작성해야 한다. 충분한 검증을 하지 않는 테스트는 없는 것보다 나쁠 수 있다.
  • 코드 작성과 테스트 수행의 간격이 짧을수록 효과적이다
  • 테스트하기 쉬운 코드가 좋은 코드이다.
  • 테스트를 먼저 말들고 테스트를 성공시키는 코드를 만들어가는 테스트 주도 개발 방법도 유용하다.
  • 테스트 코드도 애플리케이션 코드와 마찬가지로 적절한 리텍토링이 필요하다.
  • @Before @After를 사용해서 테스트 메소드들의 공통 준비 작업과 정리 작업을 처리할 수 있다
  • 스프링 테스트 컨텍스트 프레임워크를 이용하면 테스트 성능을 향상시킬 수 있다.
  • 동일한 설정파일을 사용하는 테스트는 하나의 애플리케이션 컨텍스트를 공유한다.
  • @Autowired를 사용하면 컨텍스트의 빈을 테스트 오브젝트에 DI할 수 있다.
  • 기술의 사용 방법을 익히고 이해를 돕기 위해 학습 테스트를 작성하자
  • 오류가 발견될 경우 그에 대한 버그테스트를 만들어두면 유용하다.

Toby 스프링3 1부 1장 오브젝트와 의존관계

|

오브젝트와 의존관계

  • 초난감 DAO
    • Extract method
  • DAO 의 분리
    • Template method pattern
    • Factory method pattern : 객체를 생성하기 위한 interface 를 정의 하는데, 어떤 class의 instance를 만들지 subclass에서 결정하게 만든다
    • 
과심사의 분리
  • DAO 확장
    • 클래스의 분리
    • interface 도입
    • 관계설정 책임의 분리
    • 원칙과 패턴
      1. 개방 폐쇄 원칙( OCP: Open-Closed Principle) 클래스나 모듈은 확장에는 열려 있어야하고 변경에는 닫혀 있어야한다.
      2. 객체지향 설계 원칙 ( SOLID) => UML for java programmer 참조
        • 높은 응집도와 낮은 결합도 (high coherence and low coupling)
        • 낮은 결합도: 하나의 변경이 발생할 때 마치 파문이 여타 모듈과 객체로 변경에한 요구가 전파되지 않는 상태이다.
        • 높은 응집도 : 변화가 발생할 때 해당 모듈에서 변하는 부분이 크다
        • Strategy pattern : 전략 패턴 자신의 기능 맥락(context)에서 필요에 따라 변경이 필요한 알고리즘을 인터페이를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라 바꿔서 사용하는 디자인 패턴이다. context를 사용하는 client 는 context가 사용할 전략을 context의 생성자를 통해서 제공해주는게 일반적이다.
    • 제어의 역전(IOC)
      • 오브젝트 팩토리 : 객체 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 리턴 하는 오브젝트를 팩토리라고 한다. 즉 설계도 역할을 한다.
      • 제어의 역전: 제어의 역전에서는 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않는다. 당연히 생성하지도 않는다. 모든 제어 권한을 자신이 아닌 다른 대상에게 위임한다.

      예) java의 servlet을 만들면 사용자가 직접 객체 생성에 개입하지 않고 컨테이너가 알아서 생성하고 관리한다.

    • 스프링의 IOC
      • 오브젝트 팩토리를 이용한 스프링 IOC

        @Configuration
        @Bean
        ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
        UserDao dao = context.getBean("userDao", UserDao.class);
        
      • 애플리케이션 컨텍스트의 동작방식

        • ApplicationContext IoC를 적용해서 관리할 모든 오브젝트에 대한 생성과 관계설정을 담당 Dao factory와 달리 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 없고, 그런 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻는다. 때로는 외부의 오브젝트 팩토리에 그 작업을 위임하고 그 결과를 가져다가 사용하기도 한다.

        • ApplicationContext의 장점
          • 클라이언트가 구체적인 팩토리 클래스를 알 필요가 없다.
          • 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.
          • 애플리케이션 컨텍스트는 Bean을 검색하는 다양한 방법을 제공한다.
        • 스프링 IoC의 용어 정리
          • 빈(Bean) : 스프링이 IoC 방식으로 관리하는 오브젝트라는 뜻 managed Object라고 부르기도 한다. 주의할 점은 스프링을 사용하는 애플리케이션에서 만들어지는 모든 오브젝트가 다 Bean은 아니라는 사실이다. 그중에서 스프링이 직접 그 생성과 제어를 담당하는 오브젝트를 Bean이라고 부른다.

          • Bean Factory : 스프링의 IoC를 담당하는 핵심 컨테이너를 가리킨다. Bean을 등록하고 , 생성하고, 조회하고 돌려주고, 그 외에 부가적인 Bean을 관리하는 기능을 담당한다. 보통은 이 bean factory를 사용하지 않고 이를 확장한 application context를 이용한다. BeanFactory라고 붙여쓰면 빈 팩토리가 구현하고 있는 가장 기본적인 인터페이스의 이름이 된다. 이 인터페이스에 getBean()과 같은 method가 정의되어 있다.
          • ApplicationContext : beanFactory를 확장한 IoC 컨테이너이다. bean을 등록하고 관리하는 기본적인 기능은 bean factory와 동일하하다. 여기에 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다. Bean factory라고 부를 때는 주로 bean의 생성과 제어의 관점에서 이야기하는 것이고, application Context라고 할 때는 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기하는 것이라고 보면 된다. ApplicationContext라고 적으면 application context가 구현해야하는 기본 인터페이스를 가리키는 것이기도 하다. ApplicationContext는 BeanFactory를 상속한다.
          • 설정정보/설정 메타정보(configuration metadata) : 스프링의 설정 정보란 애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보를 말한다.실제로 스프링의 설정정보는 컨테이너에 어떤 기능을 세팅하거나 조정하는 경우에도 사용하지만, 그보다 IoC컨테이너에 의해 관리되는 애플리케이션 오브젝트를 생성하고 구성할때 사용된다.
          • 컨테이너(container) 또는 IoC 컨테이너
          • 스프링 프레임워크 : IoC컨테이너, 애플리케이션 컨텍스트를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할때 주로 사용한다. 그냥 스프링이라고 줄여서 말하기도 한다.
  • 싱글톤 레지스트리와 오브젝트 스코프 전통적인 싱글톤 패턴 구현 방법
    • 클래스 밖에서 오브젝트를 생성하지 못 하도록 생성자를 private로 만든다.
    • 생성된 싱글톤 오브젝트를 저장할 수 있는 자신과 같은 타입의 스태틱 필드를 정의한다.
    • 스태틱 팩토리 메소드인 getInstance()를 만들고 이 메소드가 최초로 호츨되는 시점에서 한번만 오브젝트를 만들어지게 한다. 생성된 오브젝트는 스태틱 필드에 저장한다. 또는 스태틱 필드의 초기값으로 오브젝트를 미리 만들어 둘 수 있다.
    • 한번 오브젝트(싱글톤)가 만들어지고 난 후에는 getInstance()메소드를 통해 이미 만들어져 스태틱 필드에 저장된 오브젝트를 넘겨준다.

    전통적 싱글톤의 단점

    • private 생성자를 갖고 있기 때문에 상속할 수 없다.
    • 싱글톤은 테스트가 어렵다.
    • 서버 환경에서 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
    • 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

    싱글톤 레지스트리

    • 전통적 싱글톤의 단점을 보완하기 위해 만들어짐
    • 평범한 자바 클래스를 싱글톤으로 만들어 준다.

    오브젝트의 동일성(identical)과 동등성(equivalent)

    • 싱글톤 레지스트리로서의 애플리케이션 컨텍스트 스프링은 기본적으로 별다른 설정을 하지 않으면 내부에서 생성하는 빈 오브젝트를 모두 싱글톤으로 만든다. ApplicationContext는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리(singleton registry) 이다.

서버 애플리케이션과 싱글톤

싱글톤 패턴으로 구현 했을 때 의 한계점

  • private 생성자를 갖고 있기 때문에 상속할 수 가 없다.
  • 싱글톤은 테스트하기가 어렵다
  • 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
  • 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다

Singleton registry :

오브젝트 팩토리 = 스프링의 애플리케이션 컨텍스트 = Ioc컨테이너 = 스프링 컨테이너 = bean factory

클래스

|

클린코드 10장 클래스

클래스 체계

정적 공개 상수
정적 비공개 변수
비공개 인스턴스 변수

공개 함수
비공개 함수: 자신을 호출하는 공개 함수 직후에 넣는다.
전체는 신문과 같은 방식으로 작성한다.

클래스는 작아야한다.

  • 클래스가 맡고 있는 책임이 적어야한다.
  • 클래스의 이름은 클래스 책임을 기술한다.
  • 단일 책임 원치(Single Responsibility Principle) : 클래스나 모듈을 변경해야 하는 이유는 단 하나뿐이어야 한다.
  • 큰 클래스 몇개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직 하다.
  • 작은 클래스가 맡은 책임은 하나며, 다른 작은 클래스와 협력하여 시스템에 필요한 동작을 수행한다.

응집도(cohesion)

  • 클래스는 인스턴스 변수 수가 작아야 한다.
  • 각 클래스 메서드는 클래스 인스턴스 변수를 하나이상 사용해야 한다.
  • 일반적으로 메서드가 변수를 더 많이 사용할 수록 메서드 와 클래스는 응집도가 높아 진다.
  • 응집도가 높다는 말은 클래스에 속한 메소드와 변수가 서로 의존하며 논리적으로 묶인다는 의미이다.

응집도를 유지하면 작은 클래스가 여럿이 나온다.

  • 큰 method를 나눌 때 변수를 instance 변수로 변경한다.
  • 이렇게 되면 응집도가 떨어지게 된다.
  • 응집도가 떨어진 method는 클래스로 변경한다.

변경하기 쉬운 클래스

상세구현에 의존하는 클라이언트 클래스는 구현이 변경이 되면 위험에 빠진다.
그래서 interface나 abstract class를 사용하여 구현이 미치는 영향을 격리시킨다.
격리 이후에 stub을 사용하여 test를 용이하게 만든다.