검색결과 리스트
Refactoring에 해당되는 글 7건
- 2009/08/18 [후기] Ralph Johnson과 함께하는 소프트웨어 개발의 지혜들 (9)
- 2009/07/03 이클립스 Extract Method 리팩토링Tip
- 2009/02/10 리팩토링에 익숙해지기 2
- 2009/02/09 리팩토링에 익숙해지기 (9)
- 2006/11/17 이클립스를 활용한 메소드 시그너처 변경(Alt+Shift+C) (1)
- 2006/11/17 이클립스를 활용한 Extract Interface 리팩토링
- 2006/11/11 이클립스를 활용한 Pull-up 리팩토링
글
[후기] Ralph Johnson과 함께하는 소프트웨어 개발의 지혜들
2009 이야기
2009/08/18 08:42
주말에 랄프 존슨 특강에 참석했다. 프로젝트 초기라 바쁜 와중에 맞이하는 주말인데 굳이 유명인사 특강에 참석해야 할까 싶은 생각을 안고 자리에 나갔다. 아마도 특강 개설 과정에 참여하지 않았으면 그 자리에 있진 않았을 것이다.
랄프 존슨 특강을 듣기 시작한 지 얼마 지나지 않아 생각이 바뀌었다. 기름기가 잔뜩 꼈던 정신상태에 경종을 울렸다. 먼저 두 가지 사항을 반성했다.
1강: Fifteen Years of Design Patterns
베스트셀러인 GoF 디자인 패턴. 실제 발표는 94년 OOPSLA인데 출간은 95년이다. 이유가 무엇일까? 출판업자는 우리나라와 다르지 않았다. 연초에 출간해야 매출에 유리하기 때문에 해를 넘겨 책을 볼 수 있었다. 후속으로 쏟아진 관련 서적이 매우 많다. 랄프는 그중에서 4권을 꼽았다. 그 중 두 권에 대한 논평이 인상깊다. 하나는 그 유명한 헤드 퍼스트 시리즈다. 헤드 퍼스트는 자신의 책보다 더 많이 팔렸다며 미소를 지었다. 그리고, 헤드 퍼스트의 독특한 전개 방식에 대해 높이 평가했다. 두 번째는 에릭 에반스의 DDD에 대한 평이다. 랄프는 크리스토퍼 알렉산더를 글 잘 쓰는 사람으로 평가했다. 그리고 컴퓨터 과학과 건축(building)은 다르다고 이야기했다. DDD는 알렉산더류에 가까우면서 매우 독창적인(very unique) 책이라는 점을 강조했다.
책 소개 이후에는 디자인 패턴 자체에 대해 설명했다. 디자인 패턴을 고급(advanced) 객체지향 프로그래밍 전형으로 소개한 점이 인상적이었다. 객체지향에선 보통 명사는 객체이고, 동사는 행위이다. 그런데 고급이란 표현은 일반적(not normal)이 아니란 의미다. 예를 들어 Strategy는 알고리즘인데, 함수가 아니라 객체로 존재한다. 뒤이어 스스로 코어라 정의한 14개 패턴을 나열했다.
주로 언급한 패턴에 대해 기억에 남는 내용을 메모한다.
그리고 위험한 패턴으로 Mediator와 Singleton을 언급했다. 많은 사람이 잘못 사용하면서, 나쁜 패턴이라 칭하는 데 대해 일침을 가했다. Mediator는 반드시 재사용을 전제로 해야 하며, 종종 데이터와 코드를 구분하는 우를 범하기 쉬운 패턴이다. 싱글턴을 써야 하는 경우를 명확하게 정의해줬다.
코어에 이어서 생성 패턴을 열거했다.
마지막 카탈로그로 복합(Compound) 패턴을 두 개 꼽았다.
랄프 존슨 특강을 듣기 시작한 지 얼마 지나지 않아 생각이 바뀌었다. 기름기가 잔뜩 꼈던 정신상태에 경종을 울렸다. 먼저 두 가지 사항을 반성했다.
- 영어에 자유로워지겠다고 결심했지만, 실제 행동은 그렇지 못했다.
- 디자인 패턴에 대해 충분히 안다고 생각했는데, 사실 아무것도 모르는 사람과 별반 다르지 않음을 느꼈다.
1강: Fifteen Years of Design Patterns
베스트셀러인 GoF 디자인 패턴. 실제 발표는 94년 OOPSLA인데 출간은 95년이다. 이유가 무엇일까? 출판업자는 우리나라와 다르지 않았다. 연초에 출간해야 매출에 유리하기 때문에 해를 넘겨 책을 볼 수 있었다. 후속으로 쏟아진 관련 서적이 매우 많다. 랄프는 그중에서 4권을 꼽았다. 그 중 두 권에 대한 논평이 인상깊다. 하나는 그 유명한 헤드 퍼스트 시리즈다. 헤드 퍼스트는 자신의 책보다 더 많이 팔렸다며 미소를 지었다. 그리고, 헤드 퍼스트의 독특한 전개 방식에 대해 높이 평가했다. 두 번째는 에릭 에반스의 DDD에 대한 평이다. 랄프는 크리스토퍼 알렉산더를 글 잘 쓰는 사람으로 평가했다. 그리고 컴퓨터 과학과 건축(building)은 다르다고 이야기했다. DDD는 알렉산더류에 가까우면서 매우 독창적인(very unique) 책이라는 점을 강조했다.
책 소개 이후에는 디자인 패턴 자체에 대해 설명했다. 디자인 패턴을 고급(advanced) 객체지향 프로그래밍 전형으로 소개한 점이 인상적이었다. 객체지향에선 보통 명사는 객체이고, 동사는 행위이다. 그런데 고급이란 표현은 일반적(not normal)이 아니란 의미다. 예를 들어 Strategy는 알고리즘인데, 함수가 아니라 객체로 존재한다. 뒤이어 스스로 코어라 정의한 14개 패턴을 나열했다.
- Composite
- Strategy
- Decorator
- State
- Iterator
- Observer
- Value Object
- Mediator
- Facade
- Proxy
- Command
- Template Method
- Adapter
- Null Object (Exceptional Object)
주로 언급한 패턴에 대해 기억에 남는 내용을 메모한다.
- Composite
- Strategy
- Observer
그리고 위험한 패턴으로 Mediator와 Singleton을 언급했다. 많은 사람이 잘못 사용하면서, 나쁜 패턴이라 칭하는 데 대해 일침을 가했다. Mediator는 반드시 재사용을 전제로 해야 하며, 종종 데이터와 코드를 구분하는 우를 범하기 쉬운 패턴이다. 싱글턴을 써야 하는 경우를 명확하게 정의해줬다.
encapsulate global state when it cannot be eliminated
코어에 이어서 생성 패턴을 열거했다.
- Abstract factory (peripheral)
- Factory method
- Prototype
- Builder
- Singleton
- Dependency Injection
- Memento
- Chain of responsibility
- Bridge
- Visitor
- Type Object
- Extension Object
- Generation Gap
마지막 카탈로그로 복합(Compound) 패턴을 두 개 꼽았다.
- Flyweight
- Interpreter
글
이클립스 Extract Method 리팩토링Tip
2009 이야기
2009/07/03 18:32
다음과 같은 코드가 있다.
rolls[frameIdx + 1] + rolls[frameIdx + 2] 부분을 메소드로 뽑아내고자 한다. 이클립스에서 블록 지정을 하고 Alt+Shift+M 단축키를 누르면, 다음과 같은 메시지를 만날 수 있다.
두 가지 해결책이 있다. 하나는 굳이 이클립스 명령을 쓰지 않는 방법이다. 다른 방법은 블록 지정 부분을 괄호로 묶고 나서 Extract Method 명령을 수행하는 방법이다.
결코, 빠른 방법은 아니지만 몇 가지 사소한 이점이 있다.
score += 10 + rolls[frameIdx + 1] + rolls[frameIdx + 2];
rolls[frameIdx + 1] + rolls[frameIdx + 2] 부분을 메소드로 뽑아내고자 한다. 이클립스에서 블록 지정을 하고 Alt+Shift+M 단축키를 누르면, 다음과 같은 메시지를 만날 수 있다.
Can only extract a single expression or a set of statements.1
두 가지 해결책이 있다. 하나는 굳이 이클립스 명령을 쓰지 않는 방법이다. 다른 방법은 블록 지정 부분을 괄호로 묶고 나서 Extract Method 명령을 수행하는 방법이다.
score += 10 + (rolls[frameIdx + 1] + rolls[frameIdx + 2]);
결코, 빠른 방법은 아니지만 몇 가지 사소한 이점이 있다.
- 타이핑 절감
- 오타 방지
- 자동 줄맞춤
- inline 리패토링하면 다시 제거 가능
- 젠장. 보안 툴 탓에 이미지 파일을 못 올린다. [본문으로]
글
리팩토링에 익숙해지기 2
2009 이야기
2009/02/10 09:18
디렉터리 정리를 하려는데 리팩터링(Refactoring)이 떠올랐다. 우선 Kent Beck를 인용해보자.
마치 정리하지 않은 디렉터리처럼 코드 역시 마냥 필요에 따라 고쳐가도 작동(works)한다. 그러나 애초부터는 고사하고 시간이 지나고 깨끗이(clean) 정리하지 않으면 작동을 하더라도 유지하기 어렵다. 4개월 넘게 디렉터리 정리 없이 즉흥적으로 썼더니 파일이 중복으로 존재한다. 4개월간 쌓인 파일을 새로운 기준으로 정리하려니까 만만치 않다. 무슨 일이든 작동과 정리(간결히 하기) 사이는 짧을수록 좋다.
The goal is clean code that works. [...] First we'll solve the "that
works" part of the problem. Then we'll solve the "clean code" part.
This is the opposite of architecture-driven development, where you
solve "clean code" first, then scramble around trying to integrate into
the design the things you learn as you solve the "that works" problem.
마치 정리하지 않은 디렉터리처럼 코드 역시 마냥 필요에 따라 고쳐가도 작동(works)한다. 그러나 애초부터는 고사하고 시간이 지나고 깨끗이(clean) 정리하지 않으면 작동을 하더라도 유지하기 어렵다. 4개월 넘게 디렉터리 정리 없이 즉흥적으로 썼더니 파일이 중복으로 존재한다. 4개월간 쌓인 파일을 새로운 기준으로 정리하려니까 만만치 않다. 무슨 일이든 작동과 정리(간결히 하기) 사이는 짧을수록 좋다.
글
리팩토링에 익숙해지기
2009 이야기
2009/02/09 08:29
“In order to do Scrum or XP or any form of Agile successfully, you must refactor. Sorry, not optional. Necessary.”
We must evolve the infrastructure. It’s not a rule, it’s worse. It’s essentially a law of nature.
We must evolve the infrastructure. It’s not a rule, it’s worse. It’s essentially a law of nature.
Ron Jeffries의 촌철살인이다. 요즘 공개한 API를 다시 돌아보면서, 온 힘을 다해 정제하지 않은 과거가 부끄러웠다. 의기소침해진 나에게 '그러면서 배우는 것이야.'라고 격려하는 듯하다.
어느 시점에서든 최고의 코드를 만들자고 눈에 불을 켜고 검토하고 수정해도 최고일 순 없었을 것이다. 적절한 간격으로 영리하고 기민하게 일을 하지 못했을 뿐이다. 1
- 의지가 부족해 게을리 보냈던 시간이 있었음이야 물론 말할 필요도 없다. [본문으로]
글
이클립스를 활용한 메소드 시그너처 변경(Alt+Shift+C)
2006/리팩토링
2006/11/17 19:28
public abstract String findByDong(String dong);
반환값이 String이었는데 여러 개의 객체 배열로 반환받고 싶다. 그리고, static 메소드로 변경하고 싶다. 이럴 때도 이클립스 리팩토링 기능을 이용할 수 있다. 편집기에서 메소드 부분(주석 포함)을 선택하거나 패키지 탐색기에서 메소드를 선택하고 오른쪽 마우스를 누른다.
Alt+Shift+C 조합키를 단축키로 사용할 수 있음을 알 수 있다.
접근 지정자, 반환값 유형, 매개변수, 예외, 메소드 이름 등 모든 것을 바꿀 수 있다. ^^; 아쉽게도 static 은 여기서 부여할 수 없다. 변경을 적용하기 전에 Preview 버튼을 선택하면 미리 보기를 통해 변경되는 부분을 확인할 수 있다.
인터페이스와 이를 구현한 클래스에 적용이 미침을 알 수 있고, 코드 비교를 통해 구체적으로 어떻게 바뀌는지 확인할 수 있다.
원문 작성 일시: 2004/11/19 (금) 13:57
글
이클립스를 활용한 Extract Interface 리팩토링
2006/리팩토링
2006/11/17 19:23
리팩토링 카다로그에 보면 Extract Interface가 있다.
Several clients use the same subset of a class's interface, or two classes have part of their interfaces in common.
동일한 클래스 인터페이스(public method)를 여러 클라이언트가 공유하는 경우, 혹은 두 개 이상의 클래스가 동일한 인터페이스를 공통으로 갖고 있는 경우 이를 인터페이스를 뽑아낸다.


이클립스에서 이러한 기능을 지원해준다. 물론, 도와주는 것이지 판단은 사람의 몫이다. ^^;
아래와 같은 코드가 있다고 하자.
public class ZipcodeInDB {
public String findByDong(String dong){
return "";
}
}
return "";
}
}
내용은 없지만, findByDong이 다른 클래스에도 있을 수 있어, Zipcode라는 인터페이스를 만들어보겠다. 패키지 탐색기에서 ZipcodeInDB를 선택하고 오른쪽 마우스를 누르면, Refactor > Extract Interface 라는 메뉴를 선택할 수 있다.
Interface name란에 원하는 인터페이스(자바 Inteface) 이름을 넣고, 인터페이스에 포함시킬 메소드를 선택한다. 가장 상당은 옵션은 현재 ZipcodeInDB라는 클래스를 참조하는 코드에서 ZipcodeInDB 대신에 Zipcode 타입으로 참조하게 하고자 할 때 선택한다.
public class ZipcodeInDB implements Zipcode
Interface name란에 원하는 인터페이스(자바 Inteface) 이름을 넣고, 인터페이스에 포함시킬 메소드를 선택한다. 가장 상당은 옵션은 현재 ZipcodeInDB라는 클래스를 참조하는 코드에서 ZipcodeInDB 대신에 Zipcode 타입으로 참조하게 하고자 할 때 선택한다.
이렇게 하면, 당연히 코드에 변경이 일어나야 한다. 확인해보자.
public class ZipcodeInDB implements Zipcode
ZipcodeInDB에는 "implments Zipcode" 부분이 추가되었고, 인터페이스 코드는 새로 생성되었다.
public interface Zipcode {
public abstract String findByDong(String dong);
}
public abstract String findByDong(String dong);
}
원문 작성 일시: 2004/11/19 (금) 13:27
글
이클립스를 활용한 Pull-up 리팩토링
2006/리팩토링
2006/11/11 00:42
Spring을 사용하다 보면 협업 객체의 IoC 기능 활용을 위해 setter가 요구된다.
public class ArticleListController extends AbstractController{
private ArticleLinkDao articleLinkDao;
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
...
}
public void setArticleLinkDao(ArticleLinkDao articleLinkDao) {
this.articleLinkDao = articleLinkDao;
}
}
그런데 이러한 클래스가 또 만들어야 한다고 가정해보자. 중복이 발생한다.
public class ThemePageController extends AbstractController{
private ArticleLinkDao articleLinkDao;
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
...
}
public void setArticleLinkDao(ArticleLinkDao articleLinkDao) {
this.articleLinkDao = articleLinkDao;
}
}
중복을 막기 위해서 BaseController를 만들어 이들을 상속하게 하자.
1. AbstractController -> BaseController로 변경
public class ArticleListController extends BaseController{
private ArticleLinkDao articleLinkDao;
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
...
}
public void setArticleLinkDao(ArticleLinkDao articleLinkDao) {
this.articleLinkDao = articleLinkDao;
}
}
2. 빠른 수정(Quick fix)으로 BaseController 생성
BaseController가 AbstractController를 상속해야 함을 잊지 말자.
3. Refactor > Pull up... 메뉴 선택
리팩토링을 하고 나면 기분까지 개운(?)해진다. ^^;
4. BaseController 변경
BaseController를 abstract로 만들어 반드시 handleRequestInternal을 구현하게 하고, 매개변수 이름을 request, response과 같이 보다 의미있게 바꿔주는 센스를 발휘하면, 마법사 혹은 빠른 수정으로 상속 객체를 생성할 때 이를 그대로 사용하게 된다. ^^
public abstract class BaseController extends AbstractController {
protected ArticleLinkDao articleLinkDao;
@Override
abstract protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception;
abstract protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception;
public void setArticleLinkDao(ArticleLinkDao articleLinkDao) {
this.articleLinkDao = articleLinkDao;
}
this.articleLinkDao = articleLinkDao;
}
}
BaseController를 abstract로 만들어 반드시 handleRequestInternal을 구현하게 하고, 매개변수 이름을 request, response과 같이 보다 의미있게 바꿔주는 센스를 발휘하면, 마법사 혹은 빠른 수정으로 상속 객체를 생성할 때 이를 그대로 사용하게 된다. ^^







