[독후감]아프니까 청춘이다

제가 양서를 선정하는 주요 기준은 보통사람들과 다르지 않게, 베스트셀러에서

저에게 맞는 책을 찾아서 봅니다.

그 중에 예전부터 눈여겨 보다가 꺼내보게 된 “아프니까 청춘이다“를 읽게 되었습니다.

주로 대학생을 포커싱해서 나온 책이지만,  직장인이 읽어도 좋을 만한 책이었습니다.

제가 눈여겨 본 사항들을 아래 적어보았습니다.

  • “내 일”을 하고 “내일”이 이끄는 삶을 살라
  • 나의 진로는 내가 즐겁게 할 수 있는 일을 하라
  • 하루에 10분이라도 나 자신을 돌아보자
  • 신문을 읽어 다양한 시각으로 세상을 바라보자
  • 지금 직장에서 나는 얼마나 성과를 낼 수 있는가에 대한 우직함도 필요
  • 혼자 놀지말고 세상속에 나를 내던져라

어떻게 보면, 자기계발서에서 흔히 보는 문구들이라고 생각할 수 있지만 독자를 진심으로

생각하는 저자의 마음은 충분히 느낄 수 있는 책이었습니다.

더불어, 이 책의 포커싱 대상인 대학생들이 읽기에는 앞으로 자신의 인생을 설계함에 있어

더없이 훌륭한 책이라 생각되었습니다.

제가 눈여겨 본 문구들 중에 제일 마음에 와 닿았던 것은,

  • “내 일”을 하고 “내일”이 이끄는 삶을 살라

저 문구입니다. 요즘 책들을 보면 자기 정체성에 대한 중요성을 말하는 책들이 많은 것

같습니다. 제가 읽으려하는 김어준 총수의 “건투를 빈다” 혹은 요즘 발간된

우석훈 박사의 “1인분 인생“도 같은 맥락의 책이라 생각됩니다.

 

하루하루 자신의 삶을 돌아보고, 자신의 목표를 따라 즐겁게 그 길을 헤쳐나간다는 것..

그것이 비록 험난한 가시밭길이라 하더라도, 이 책의 제목처럼 “자신의 열정을 토할 수

있는 청춘이라면 아픔도 당연한 것처럼” 여길 수 있는 자신으로 발전할 수 있으리라

믿습니다.

Advertisements

[javascript]john Resig 라이브러리를 통한 object 코딩 실습

전에 자바스크립트 object 코딩실습에 대한 포스팅을 올린 적이 있습니다.

자바스크립트 객체를 만들어 사용하는 법과 연괄배열을 사용하는 법에 대해 간단히

실습해봤는데요. 이번엔 john Resig이 만든 라이브러리를 통해 실습을 해보도록 하겠습니다.

================================================================

우선 위의 블로그를 보시면 아시겠지만, 자바스크립트 객체를 상당히 간단하게(!) 만들어

사용할 수 있습니다.

일반적으로, OOP와 자바프로그래밍을 하실 수 있는 분이라면 무리없이 코딩이 가능합니다.

거두절미하고 아래 예제코드를 보시죠.

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="resig.js"></script>
<script language="javascript">
(function ($) {
    "use strict";

    if(typeof window.bluepoet == "undefined") {
          window.Bluepoet = {};
    }

    Bluepoet.Parent = Class.extend({
        name : '',
        init: function(name) {
            var me = this;
            me.name = name;
        },
        getName: function() {
            var me = this;
            return me.name;
        }
   });

   Bluepoet.Child = Bluepoet.Parent.extend({
       init:function(name) {
           return this._super(name);
       }
   });
})(jQuery);

$(document).ready(function() {
    var parent = new Bluepoet.Parent("parent");
    var child = new Bluepoet.Child("child");

    document.write(parent.getName() + " : " + child.getName());
});
</script>
</head>
<body>
</body>
</html>

위 코드의 결과는 각각 Parent, Child 클래스의 이름인 “parent : child”가 나오게 됩니다.

코드를 간단히 설명드리면,

우선, “Bluepoet”이란 전역객체를 선언하고 Bluepoet에 각각 Parent와 Child 클래스를

선언했습니다. 이때, john Resig이 만든 라이브러리르 사용하여 클래스를 만듭니다.

내용은, init 메서드로 자바스크립트 클래스의 생성자를 만들고, 자바 클래스와 동일하게

안에 필드와 메서드를 만들어 사용할 수 있습니다.

최종적으로, Parent와 Child 클래스를 생성할 때 생성자에 각자의 이름을 넣어주고

객체를 생성해서, 각자의 이름을 출력하게 됩니다.

Parent에 init과 getName 메서드에 this를 대입한 “me” 변수를 선언한 이유는

객체자신을 제외한 이벤트객체와의 차별화를 위해 따로 정의를 한 것입니다.

두 객체 다 자기자신을 모두 this로 사용하기 때문에 나중에 있을 혼란을 미연에

방지하기 위해서이죠.

끝으로, 윗단에 “use strict”라고 명시해 놓은 것은 strict mode에서 자바스크립트

컴파일 과정에 더욱 엄격한 체크를 하겠다는 선언입니다.

위 내용에 대한 설명은 아래 링크를 참조하시면 됩니다.

자바스크립트 코드를 객체지향적으로 만들게 되면, 기존보다 코드량이 훨씬

줄어들뿐만 아니라, DOM에서의 요소검색에서도 월등한 성능향상을

기대할 수 있습니다.

자~! 이제 자바스크립트 객제지향코드의 바다로 풍덩~ 빠져보시죠^^

[Mockito]Spring framework에서 Controller 테스트케이스 만들기

요즘 저에게 가장 화두가 되고 있는 단어 중에 하나가 바로 “테스트“입니다.

어떻게 하면, 테스트케이스를 통해 실제 코드를 더욱 견고하고 깔끔하게 만드는가 하는데에

따른 고민에서 시작됩니다.

바로 그 시작점인 “테스트“케이스를 만드는데 있어, 현재 가장 많이 쓰이고 있는

프레임워크인 “스프링“에서 웹 어플리케이션의 서버사이드 “프론트“를 담당하고 있는

“Contoller”부분에 대한 간단한 CRUD 테스트케이스를 만들어 보았습니다.

public class TempVo {

    private Integer id;
    private String name;

    ... 이하 setter/getter코드 생략

}

 

public interface TempService {

    TempVo getListUserInfo(int id);

    int insertUserInfo(TempVo temp);

    int updateUserInfo(TempVo temp);

    int deleteUserInfo(TempVo temp);

    List getListTemp();
}

 

import static com.glider.framework.test.ReflectionInjectorUtils.injector;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.collect.Lists;

@RunWith(MockitoJUnitRunner.class)
public class CommonControllerTest {

	// 테스트대상 클래스의 의존객체에 Mock Object 주입
	@Mock
	private TempService tempService;

	// 테스트대상 클래스에 Mock Object 주입
	@InjectMocks
	private CommonController commonController = new CommonController();

	private ModelAndView model;

	@Before
	public void setUp() {
		// 테스트대상 Mock 클래스에 의존 Mock객체를 쉽게 주입할 수 있음.
		// http://wiki.kwonnam.pe.kr/java/unittest/reflectioninjector 참고.
		injector(commonController).set(tempService);
		model = new ModelAndView();
	}

	@Test
	public void getTemp() {
		int id = 1;
		TempVo temp = new TempVo();

		when(tempService.getListUserInfo(id)).thenReturn(temp);

		commonController.temp(id, model);

		verify(tempService).getListUserInfo(id);
		assertThat(model.getViewName(), is("temp/temp"));
	}

	@Test
	public void insertTemp(){
		TempVo temp = new TempVo();
		temp.setId(1);
		temp.setName("bluepoet");

		when(tempService.insertUserInfo(temp)).thenReturn(1);

		commonController.insertTemp(name, model);

		verify(tempService).insertUserInfo(temp);
		assertThat(model.getViewName(), is("temp/temp"));
	}

	@Test
	public void updateTemp() throws Throwable {
		TempVo temp = new TempVo();
		temp.setId(3);
		temp.setName("bluepoet");

		when(tempService.updateUserInfo(temp)).thenReturn(1);

		commonController.updateTemp(name, model);

		verify(tempService).updateUserInfo(temp);
		assertThat(model.getViewName(), is("temp/temp"));
	}

	@Test
	public void deleteTemp() throws Throwable {
		TempVo temp = new TempVo();
		temp.setId(1);
		temp.setName("bluepoet");

		when(tempService.deleteUserInfo(temp)).thenReturn(1);

		commonController.deleteTemp(name, model);

		verify(tempService).deleteUserInfo(temp);
		assertThat(model.getViewName(), is("temp/temp"));
	}

	@Test
	public void getListTemp() {
		List list = Lists.newArrayList();

		when(tempService.getListTemp()).thenReturn(list);

		commonController.getListTemp(model);

		verify(tempService).getListTemp();
		assertThat(model.getViewName(), is("temp/tempList"));
	}
}

물론 CRUD Controller 메서드안에 더욱 복잡한 로직이 들어갈 수도 있습니다.

그럴땐, 테스트케이스가 더 복잡해지겠지요.

다만, 큰 것을 만들때는 작은 것부터 Step by Step으로 나가는 것이 좋다고 생각합니다.

스프링 framework에서 controller를 만들때는 위 테스트케이스를 뼈대로 해서,

테스트케이스를 확장해나가시면 더욱 견고한 real code를 만드실 수 있으리라고 봅니다.

단위테스트에 대해서는 토비의 스프링3에서도 여러차례 리팩토링과 함께 잘 나와있으니

참고하시면 될것 같구요(테스트대역, 스텁,  Mock Object의 개념등..)

아래 포스팅에서는 테스트케이스를 작성하는 방법과 활용에 대해서 더욱 잘 나와있으니

꼭 일독을 권해드립니다.

* 참고 url

[디자인패턴]”템플릿-컬백”패턴 실습

최근에 토비의 스프링3를 열독하면서 소개된 “템플릿-컬백” 디자인패턴의 예제를

실습하면서 스스로도 다시 한번 블로그 포스팅을 통해 되새겨야 겠다고 생각하고

실습예제를 간단히 만들어 보았습니다.

토비님과 다른 예제를 만들려고 하였으나, 여력이 되지 않아 토비님 예제에서 살짝만

바꿔 사칙연산을 할 내용을 “파일“에서 “HTML페이지“로 바꾸어 실습해 보았습니다.

================================================================

1. 먼저 “템플릿-컬백“을 적용하기 전에 클래스 파일입니다.

public class Calculator {

	public int sum() {
		String[] arrList = new String[4];
		int result = 0;

		try {
			URL url = new URL("http://bluepoet.dothome.co.kr/test.html");
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			String str = "";

			while((line = br.readLine()) != null) {
				str += line;
			}

			arrList = str.split("<br>");

			for(String s : arrList) {
				result += Integer.valueOf(s);
			}

			return result;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return result;
	}

	public int multi() {
		String[] arrList = new String[4];
		int result = 1;

		try {
			URL url = new URL("http://bluepoet.dothome.co.kr/test.html");
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			String str = "";

			while((line = br.readLine()) != null) {
				str += line;
			}

			arrList = str.split("<br>");

			for(String s : arrList) {
				result *= Integer.valueOf(s);
			}

			return result;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return result;
	}
}

보면 아시겠지만, HTML 페이지에서 3,4,5,6을 가져와 더하고 빼는 기능을 하는 부분 이외는

나머지 부분이 모두 동일하다는 것을 알 수 있습니다.

================================================================

2. Calculator 클래스에서 바뀌는 부분, 즉 컬백을 적용할 부분은

int result = 0;
int result = 1;

result += Integer.valueOf(s);
result *= Integer.valueOf(s);

처음에 초기값을 설정해주는 부분과 사칙연산을 하는 부분입니다.

그럼, “템플릿-컬백“을 적용하여 “인터페이스“를 두어 컬백을 수행할 부분을

추상화하여 분리하고, 나머지 공통적인 템플릿부분은 별도의 메소드로 분리하여

리팩토링을 진행하였습니다.

public int sum() {
	Operation oper = new Operation() {

		@Override
		public int exec(int result, String s) {
			result += Integer.valueOf(s);
			return result;
		}
		};

	return templateLine(oper)-1;
}

public int multi() {
	Operation oper = new Operation() {

		@Override
		public int exec(int result, String s) {
		    result *= Integer.valueOf(s);
			return result;
		}
	};

	return templateLine(oper);
}

public int templateLine(Operation oper) {
	String[] arrList = new String[4];
	int result = 1;

	try {
		URL url = new URL("http://bluepoet.dothome.co.kr/test.html");
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();

		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		String line = null;
		String str = "";

		while((line = br.readLine()) != null) {
			str += line;
		}

		arrList = str.split("<br>");

		for(String s : arrList) {
   		    result = oper.exec(result, s);
		}

		return result;
	} catch (MalformedURLException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}

	return result;
}

인터페이스로 컬백부분을 분리하고 각기 사칙연산을 수행하는 메서드 안에서

익명내부클래스“로 정의해서 컬백에 대한 내용을 수행하고 마지막에 공통적인 부분을

수행하는 템플릿메서드에 해당 인터페이스를 구현한 익명의 객체를 파라미터로 전달하면

됩니다.

위에 리팩토링한 클래스를 테스트하는 테스트 클래스를 만들었습니다.

public class CalculatorTest {
	Calculator calculator;

	@Before
	public void setup() {
		calculator = new Calculator();
	}

	@Test
	public void sumTest() {
		assertThat(calculator.sum(), is(18));
	}

	@Test
	public void multiTest() {
		assertThat(calculator.multi(), is(360));
	}
}

테스트를 돌려보면 기분좋은 녹색막대가 나오게 됩니다.

전에 공통적인 부분을 중복으로 사용하여 코드가 지저분했다면 간단하게 “템플릿-컬백

패턴을 사용하여 리팩토링한 결과, 깔끔하고 가독성 좋은 코드로 환골탈태하였습니다.

토비의 스프링3에 책을 보며 알게 된 사실이지만, 스프링에서 무심코 편하게 썼던

jdbcTemplate class도 사실 스프링 내부에서 “템플릿-컬백”패턴을 적용하여 돌아가고

있었다고 합니다. 사실, 생각해보니 connection을 얻어오는 부분부터 예외처리나

close처리 등이 빠져있어 그런 부분을 도대체 어디서 처리했는지 궁금증을 가져본 분이라면,

새벽에 해가 떠오르는 것처럼 “아~!“하는 감동(?)을 맛보실 수 있지 않을까 싶습니다.

================================================================

이번에 스타리그 앱을 이 “템플릿-컬백“을 적용하여 리팩토링 하였는데, 그 포스팅도

시간되는대로 올리도록 하겠습니다^^