Software Engineering/Refactoring

[scrap] 코드다듬기 메뉴판

vinc.oh 2008. 4. 28. 15:53
출처 달룟 달리라구~ | 달룟
원문 http://blog.naver.com/daliot/120021243576

리팩토링에 관한 메뉴판....

smalltalk를 공부하시면서 정리한 듯 한데.

달룟님과 안드레아님의 블로그를 통해 smalltalk의 매력이 전해진다는....

Ruby, SmallTalk .... 공부하고 싶은 스크립트/랭귀지.

 

---------------------------------------------------------------

 

 

코드다듬기를 설명하면서 절적한 용어가 생각나지 않아서 곤욕스러웠던 적이 많았는데,  다행이 이를 잘 정리한 싸이트가 있어 소개합니다.

 

원문에서는 ABC순으로 나열하였는 데, 저는 이걸 종류별로 묶어 보았습니다.

 

 

 

다형성 기법

다형성을 제대로 걸면 멋진 엎어치기 한판이 되지만, 그런 경우는 잘 없는 것 같다. 경우가 늘어나도 유연하게 대처할 수 있다는 장점이 있다.
Replace Conditional with Polymorphism  조건문을 다형성으로 대신한다.
Replace Conditional with Visitor  switch문을 double dispatch기법으로 대신함

Introduce Null Object   예외 상황이 발생하면 특정한 객체를 리턴하여 예외처리를 그 객체의 다형성에 의지하는 방식.

 

 

 

 

뜯어낼까? 합칠까?

비대해진 클래스나 매쏘드의 기능을 분리하여 적절하게 균형을 잡는다. 가장 적용할 일이 많은 방법이고, 적용 후 만족스러운 결과를 얻는다.

Extract Class 뚱뚱한 객체의 변수와 기능을 새 객체로 옮기기

Inline Class  두 클래스를 하나로 합친다.

Extract Method  여러 줄의 코드를 하나의 매쏘드로 묶어 밖으로 빼내기

Inline Method  피호출 매쏘드의 코드를 호출 매쏘드의 코드 속에 복사하고, 피호출 매쏘드를 삭제.

Extract Interface  여러 객체에 공통되는 매쏘드를 발견하여, interface로 정의 하기

Extract Package  코드를 패키지로 분리하기

Decompose Conditional 조건문의 참절과 거짓절을 매쏘드로 각각 뽑아 내기.
Replace Method with Method Object  뚱뚱해진 매쏘드를 객체로 만들어 호출하게 함
Duplicate Observed Data 뚱뚱한 View에서 데이터를 뽑아 Model를 만들고 View는 이를 관찰하게 하기

Separate Query from Modifier  객체변수를 접근하기도하며 고치기도 하는 큰 매쏘드를, 객체변수의 값을 변경하는 매쏘드와 그렇지 않은 매쏘드로 분리하기

 

 

 

상속 어떻게?

우리를 고민에 빠뜨리는 일 중에 하나. 추상클래스를 얼마나 넣어야 할까? 너무 많으면 이름 공간이 낭비되고 장황해진다. 너무 적으면, 중복이 늘어난다.

Collapse Hierarchy  상위클래스와 하위클래스를 합치기

Extract Subclass  클래스를 상위클래스와 하위클래스로 분리하기

Extract Superclass  비슷한 두개의 클래스의 공통점을 뽑아만든 상위클래스를 만들기

Replace Subclass with Fields  쓸데없이 상속한 것을 없애고 상위클래스에 속성을 표현하는 객체변수를 만듬

 

 

 

참조

참조를 하게 할 것인가 못하게 할 것인가? 너무 허용하면 위험하고, 너무 제한하면 접근할 일이 있을 때마다 우회하는 불편이 있다.

Change Bidirectional Association to Unidirectional  쌍방참조를 단방참조로
Change Unidirectional Association to Bidirectional  단방참조를 쌍방참조로

 

 

 

 


 

직접? 간접?

직접하면 좋은 일과 누구에게 부탁하면 좋은 일이 따로 있다.

Hide Delegate  직접 접근 할 수 있는 객체를, 다른 객체를 통하여 접근하도록 바꾸기

Remove Middle Man  다른 객체를 통하여 접근하던 객체를 직접 접근하도록 바꾸기

Replace Delegation with Inheritance 참조관계를 상속관계로 바꿈

Replace Inheritance with Delegation 상속관계를 참조관계로 바꿈

 

 

 

 

올릴까? 내릴까?

이 일은 상위 클래스에서 해주는 게 나을까 아님 하위 클래스에서 해주는 게 나을까? 고민하는 경우가 많다. 이것은 디자인 단계에서 결정하기보다는, 구현하다보면 어떻게 하는 것이 편할지 금방 드러난다. 입맛에 맞게 올리고 내리자.

Pull Up Field  하위 클래스들이 중북해서 가지고 있는 객체 변수를 상위 클래스로 옮긴다.
Pull Up Method  하위 클래스에서 중복 재정의된 매쏘드를 상위 클래스로 옮긴다.
Push Down Field 특정 하위 클래스에서만 필요한 객체 변수를 상위 클래스에서 그 클래스로 옮긴다.
Push Down Method 특정 하위 클래스에서만 필요한 매쏘드를 상위 클래스에서 그 클래스로 옮긴다.

Form Template  Method 하위클래스의 매쏘드 호출 행태의 규칙성을 발견, 이를 상위 클래스에 정의함

 

 

 

 

감추기

당신은 당신이 가진 자동차의 엔진 피스톤이 왕복하는 것을 꼭 보고 싶은가? 단지, 차를 몰고 어딘가로 가고 싶은 것일 뿐이라면, 후드를 닫아버리고 핸들만 잡자.

Encapsulate Collection   Collection의 직접접근을 차단하고, 대신 add/remove 매쏘드를 제공하기
Encapsulate Field 객체변수의 접근권을 제한함(public -> private, 접근자 제거)
Self Encapsulate Field  객체변수를 직접 사용하지 않고 접근자를 사용하기

Remove Setting Method  상수처럼 사용되는 객체변수를 만들기 위해 값을 바꾸는 접근자 매쏘드를 없앤다.
Hide Method  외부에서 쓸 일이 없는 매쏘드를 private으로 바꾸기

 

 

 

 

인자

어떤 일을 할 때, 객체들이 모여서 협동해야 한다. 자주 만나야 하는 객체는 객체변수에, 가끔 만나야 하는 객체는 인자로 넘겨준다.

Add Parameter 매쏘드에 인자를 추가

Remove Parameter  인자를 쓰지 않고 상수를 쓴다.

Introduce Parameter Object  매쏘드간에 여러개의 인자를 주고 받는 대신, 그런 인자들을 객체변수로 가지는 객체를 주고 받게 고친다.
Parameterize Method   코드에서 사용되는 객체가 다르다는 것 빼고 똑같은, 두 개 이상의 매쏘드를 인자를 가지는 하나의 매쏘드로 대체한다
Replace Parameter with Explicit Methods 매쏘드 인자를 객체변수 접근자로 바꿈
Replace Parameter with Method 지역매쏘드를 실행해서 구할 수 있는 값은 인자로 넘기지 않기

 

 

 

 

소속

영업이 할 일을 개발이 하고, 개발이 할 일을 품경에서 하며, 품경에서 할 일을 경리과에서 하면 어떤 일이 벌어질까?  종종 그런 일은 일어난다.

Move Class   패키지에 어울리지 않는 클래스를 다른 패키지로 옮긴다.
Move Field   한 클래스의 객체변수를 다른 클래스로 옮기기
Move Method   한 클래스의 매쏘드를 다른 클래스로 옮기기
Introduce Foreign Method  어떤 클래스에 매쏘드를 만들어야 마땅하나, 그 클래스를 수정할 수 없어, 내 클래스에 그 매쏘드를 두는 방법
Introduce Local Extension  어떤 클래스에 매쏘드를 만들어야 마땅하나, 그 클래스를 수정할 수 없어, 그 클래스를 상속하여 매쏘드를 달아주는 방법

 

 

 

 

 

예외처리

당연히 그럴줄 알았는데, 전혀 그렇지 못한 경우가 있다. 어떻게 해야할까?

Replace Error Code with Exception 조건문으로 예외처리하던 것을 에러발생으로 대신 함
Replace Exception with Test 에러발생하던 것을 조건문으로 대신 함.

Replace Nested Conditional with Guard Clauses 다단계 조건분기문을 매 조건마다 return문으로 짤라 구조를 단순하게 바꿈
Introduce Assertion   어떤 문장이 실행되기 전에, 무의식적 가정을 확인하는 문장을 넣음.

 

 

 

타입코드

클래스는 어떤 종류를 뜻한다. 하지만 클래스로 미세하게 그 종류를 나눌수 없거나, 미처생각하지 못한 다른 세부적인 종류가 있음을 알 때, 우리는 타입코드를 사용한다.

Replace Type Code with Class  타입코드를 대신 클래스 쓰기
Replace Type Code with State/Strategy  타입코드 대신 전략/상태 쓰기
Replace Type Code with Subclasses 타입코드 대신 상속하기

 

 

 

 

변수

내가 객체에 지어준 이름

Inline Temp  임시변수를 삭제하고 대신 표현식을 넣음.

Replace Temp with Query  수식을 저장하는 임시변수를 매쏘드로 대체함

Introduce Explaining Variable 가독성을 높이기 위해 일부러 어떤 표현식을 설명하는 변수를 도입.

 

 

 

생성

Convert Dynamic to Static Construction  동적 생성 대신 정적 생성 쓰기
Convert Static to Dynamic Construction  정적 생성 대신 동적 생성 쓰기

 

 

 

임시딱지 때기

급하게 짠 코드는 늘 있는 법이다.  동작도 잘 된다.  하지만 그대로 놔두면, 아주 깝깝한 상황이 발생한다.

Replace Array with Object  편의상 배열을 쓴 것을 없애고 대신 객체 사용
Replace Data Value with Object  간략한 객체 대신 그것을 포함하는 새 객체를 작성하여 대신 하기

 

 

구조적 언어에도 적용가능한 것

OOP를 모르는 분들이 디자인패턴이나 코드다듬기를 공부하고 싶다 설명해 달라고 하면 참 난감하다. OOP를 빼고 코드다듬기를 논할 수 있을까...  의외로 많은 덕목들이 그런언어에도 해당사항이 있었다.

 

Reverse Conditional  not을 사용하여 조건문에서 참절과 거짓절의 위치를 뒤바꾸는 것

Split Loop 한 반복문이 여러가지 일을 하는 것을 한 가지 일만 하게 분리하기

Split Temporary Variable  여러 의미로 다시 대입해서 사용하는 임시변수를 여러 개의 임시변수로 나눔
Substitute Algorithm  코드의 어떤 부분을 보다 알기 쉬운 알고리듬으로 바꿈

Consolidate Conditional Expression  조건문 합치기
Consolidate Duplicate Conditional Fragments  조건문에 무관한 라인 밖으로 빼내기

Replace Static Variable with Parameter 정적변수 대신 인자 쓰기

Replace Iteration with Recursion  반복문을 재귀호출로 대신 함

Replace Recursion with Iteration 재귀호출 대신 반복문으로 바꿈

Replace Magic Number with Symbolic Constant  상수 대신 상징적인 이름 쓰기

Reduce Scope of Variable  변수가 실제로 사용되는 범위에서만 정의되도록 scope를 잡아준다.
Rename Method  의미가 잘 설명되지 못하는 매쏘드의 이름을 바꾼다.

Remove Control Flag  루프를 제어하는 변수를 return이나 break으로 대체한다.
Remove Double Negative   어떤 행위를 하고 그것을 다시 무효화시키는 행위를 제거


 

 

원문:

http://www.refactoring.com/catalog/index.html

 

 

이렇게 한번 쭉 훑는다는 것으로도 사고방식이 그쪽으로 움직이는 것을 느낍니다. 이름만 알고 있는 기법을 체험할 수 있는 기회가 오겠죠.

 

 

특정언어에 특화된 내용들(XXXXBeans)은 걸렀습니다. ^^

 

 

business logic, business tier, business object... business만 들어가면 무슨 말인지 이해가 안되네요.