본문 바로가기

refactoring

[Refactoring] 리펙토링을 안전하게 하기 위한 방법?! 1. 자신의 코딩 능력에 신념을 갖자.2. 자신이 놓친 에러는 컴파일러가 잡아서 처리하리란 믿음을 갖자.3. 컴파일러마저 놓친 에러는 테스트 스위트가 잡아 처리하리란 신뢰를 갖자.4. 테스트 스위트마저 놓친 에러는 코드 검수 단계에서 발견하리란 확신을 갖자. 더보기
[Refactoring] 하향 타입 변환을 캡슐화 메서드가 반환하는 객체를 호출 부분에서 하향 타입 변환해야 할 땐 하향타입 변환 기능을 메서드 안으로 옮기자 Object lastReading () {return readings.lastElement();} 아래와 같이 고친다. Reading lastReading () {return (Reading) readings.lastElement();} 하향 타입 변환은 필요악일 수도 있지만 웬만하면 사용하지 말아야한다. 클라이언트에게 불필요한 작업을 전가하기 때문이다. 더보기
[Refactoring] 생성자 메서드로 전환 객체를 생성할 때 단순한 생성만 수행하게 해야 할 땐 생성자를 팩토리 메서드로 교체하자. Employee (int type) {_type = type;} 위의 소스를 아래와 같이 생성자 메서드를 통해 생성하자. static Employee create (int type) {return new Employee(type);} 이 방법은 유지보수때 좋을 것 같다 새로운 클래스를 생성할때 생성 메서드에서 다른 클래스로 바꿔주기만 하면 모든 부분에 적용이 되기 때문이다. 더보기
[Refactoring] 메서드 은폐 리팩토링을 하다보면 메서드의 개방도를 바꿀 일이 많이 생긴다. + aMethod -> -aMethod 다른 클래스가 그 메서드를 사용한다면 개방도를 높여야 한다. 하지만 메서드의 개방도를 어떨 때는 낮춰야 할지를 판단하기는 비교적 어렵다. ps. 이런건 많은 경험이 필요하지 않을까 생가이 된다. 더보기
[Refactoring] 쓰기 메서드 제거 생성할 때 지정한 필드 값이 절대로 변경되지 말아야 할땐 그 필드를 설정하는 모든 쓰기 메서드를 삭제하자. setImmutaleValue -> 함수를 삭제 객체가 생성된 후에는 필드가 변경되지 말아야 한다면, 쓰기 메서드를 작성하지 않아야 한다. 그렇게 하면 확실히 의도가 달성되고 필드가 수정될 가능성을 차단할수 있다. 물론 속성쓰기 메서드를 생성자 안에까지 넣는다. 라는 생각을 가진다면 일관성 논쟁이 있을것 같다. ps. 어떻게 보면 당연한 내용일수도 있지만 이 항목을 읽어 보니 간단한거지만 참 심오한것 같다.. 더보기
[Refactoring] 매개변수 세트를 객체로 전환 여러개의 매개변수가 항상 붙어 다닐 땐 그 매개변수들을 객체로 바꾸자. amountInvoicedIn(start: Date, end:Date) -> amountInvoicedIn (DateRange)amountReceivedIn(start: Date, end:Date) -> amountReceivedIn (DateRange)amountOverdueIn(start: Date, end:Date) -> amountOverdueIn (DateRange) 특정 매겨변수들이 늘 함께 전달되는 경우를 흔히 볼 수 있다. 여러 메서드가 한 클래스나 여러 클래스에서 이 매개변수 집합을 사용할 가능성이 있다. 이런 클래스들은 데이터 뭉치 이므로 그 모든 데이터가 든 객체로 바꿀수 있다. 더보기
[Refactoring] 매개변수 세트를 메서드로 전환 객체가 A 메서드를 호출해서 그 결과를 B 메서드에 매개변수로 전달하는데, 결과를 매개변수로 받는 B 메서드도 직접 A메서드를 호출 할 수 있을 땐 매개변수를 업애고 A 메서드를 B메서드가 호출하게 하자 int basePrice = _quantity * _temPrice;discountLevel = getDiscountLevel();double finalPrice = discountedPrice (basePrice, discountLevel); 위의 코드를 보면 getDiscountLevel() 함수를 내부적으로 호출 할수 있다. 이것을 내부적으로 discountedPrice에서 호출하도록 한다. int basePrice = _quantity * _itemPrice;doble finalPrice = di.. 더보기
[Refactoring] 객체를 통째로 전달 객체에서 가져온 여러값을 메서드 호출에서 매개변수로 전달 할땐 그 객체를 통째로 전달하게 수정하자 void setFrame (int x, int y, int width, int height); 를 Rect라는 클래스를 만들어서 void setFrame (Rect rect); 위와 같이 바꾸자 장점은 코드 가독성 증가 및 새로운 값 전달시 편의성 증대가 있다 하지만 단점으로는 객체를 전달하기에 많은 값을 전달하지 않는 경우에는 하지 않는 것이 좋고 값을 전달할 때 호출되는 객체가 그 값들에 의존하게 되지만 값이 추출된 객체에는 의존하지 않게 된다는 점이다. 통 객체를 전달하게 되면 서로 의존하게 된다. 이것은 의존성 구조를 망가뜨릴 것 같으면 실시하지 않는 것이 좋다. 더보기
[Refactoring] 매개변수를 메서드로 전환 매개변수로 전달된 값에 따라 메서드가 다른 코드로 실행할땐 그 매개변수로 전달될 수 있는 모든 값에 대응하는 메서드를 각각 작성하자. void setValue (String name, int value) { if (name.equals("height")) {_height = value;return;} if (name.equals("width")) {_width = value;return;}Assert.shouldNeverReachHere(); } 위의 코드를 아래로 변환시킨다. void setHeight (int value) {_height = value;} void setWidth (int arg) {_width = arg;} 이렇게 만들면 조건문이 없어지기 때문에 코드가 간결해지고 컴파일 할때 검사가.. 더보기
[Refactoring] 메서드를 매개변수로 전환 기능은 비슷하지만 몇 가지 값에 따라 결과가 달라지는 메서드가 있을때 각 메서드를 전달된 매개변수에 따라 다른작업을 처리하는 하나의 메서드로 만들면 편리하다. class Employee { void tenPercentRaise () {salary *= 1.1;} void fivePercentRaise () {salary *= 1.05;} } 위의 함수들을 void raise (double factor) {salary *= (1 + factor);} 이와 같이 고치면 된다. 더보기