맨날 같은 형식으로만,맨날 반복되는 코드 ,같은 기능이지만 다른 성능....
좀더 효율적으로, 좀더 좋은 코드에 대한 욕심이 많다.
자바라는 언어를 쓰지만 자바의 특성을 살리면서 코드를 작성하지 못한것 같아 저번시간에는 자바에 대해 다시한번 공부했다.
-> 객체지향
이제는 조금 더 나아가 리팩토링에 대해 알아보려한다.
이 글은 '인프런 자바 리팩토링 -백기선 ' 강의를 듣고 정리한 글입니다
소프트웨어는 계속변하기때문에
시간이 갈수록 구조 변경으로 인한 수정등이 많아진다. 그럴수록 더 복잡하고 어려운 코드들을 효과적으로 수정 처리 하기 위함!
지금부터 코드의 안좋은점, 안좋은느낌, 은 '냄새' 로 표현을 합니다.
1. 함수 선언 변경하기
2. 변수 이름 바꾸기
3. 필드 이름 바꾸기
관련있는 코드끼리 묶여있어야 코드를 좀더 쉽게 이해할수있다.
함수에서 사용할 변수를 상단에 미리 선언하기보다는, 해당 변수를 사용하는 코드 바로 위에 선언하자.
관련 있는 코드끼리 묶은뒤 -> 함수추출하기
중복코드는 당장은 잘 동작하지만 미래에 버그를 만들어 낼 빌미를 제공한다. 수정시에도 다 수정 해야됌.
여러 하위 클래스에 동일한 코드가 있다면, 이 방법을 적용 해보자
상속시 하위클래스에서 중복되는 코드들을 위로 올려주는 방법
중복된코드를 상속 부모-자식 클래스 개념으로 나눈다.
한쪽만 고쳐도(부모) 양쪽(자식) 에게 영향을 줄수 있다.
완전똑같지 않고, 약간 다른경우 (위의 예시의 경우 파라미터) 에는 메서드 추출로 한번 감싸준다
함수에 "좋은 이름" 을 사용 했다면 해당 함수의 코드를 보지 않고도 이해할수 있어야한다
어떤 코드에 "주석" 을 남기고 싶다면, 주석 대신에 함수를 만들고 함수의 이름으로 "의도" 를 표현해보자
함수가 길어도 ‘의도’ 가 가 잘들어나있으면 괜찮고 함수가 한줄이여도 이해하기 어려운 ‘구현’ 에 가까우면 좋지 못한 코드이다.
1.함수로 분리 하면서 전달해야할 매개변수가 많아지면
- 임시 변수를 질의 함수로 바꾸기
- 매개변수 객체 만들기
- 객체 통쨰로 넘기기
함수 추출하기
조건문이 너무길다 => 조건문 분해하기
여러 switch => 조건문을 다형성으로 바꾸기
반복문 안에서 여러 작업을 하고 있어서 하나의 메소드로 추출하기 어렵다면 => 반복문 쪼개기
변수를 사용하면 반복해서 동일한 계신식도 피하며 "좋은 이름" 을 사용해 메서드 의미를 표현할수도 있다.
메서드로 추출해서 메서드에서 사용하는 매개변수 줄이기
Rate 를 메서드에게 전달하는게 아닌 ‘빼낸 메서드 안에서 호출해서 사용’ 하면 매개변수를 줄이면서 동작이 가능하도록 할수있다.
임시변수(함수추출)를 쿼리로 뺴냈을때 파라미터를 줄일수 있다.
메서드추출-> 메서드에 넣기(그안에서 추출한 메서드는 동작을 하니 매개변수로 안보내줘도됌)
2번 방법과 매우 흡사하지만 2번은 아예 그 파라미터들이 파생되어오는 레코드나 클래스드들이 없을떄 만들면서 바로 preserveWholeObject에 바로 적용되지만 3번은 이미 그파라미터들이 파생되어오는 레코드나 클래스들이 있을경우
파라미터로 객체를 넘겨준뒤 이 함수가 이객체에 의존하는게 맞는지 , 그 이후로는 메서드의 위치 를 생각해줘야한다.
이 메서드의 기능을 수행하기위해서 필요한것들은 다 Participant라는 클래스 안에 다 있다. 다만 우리가 필요한건 totalNumberOfEvents
그러면 totalNumberOfEvents 매개변수로 받으면 굳이 이건 여기에 위치하지 않아도 되지 않을까? 필요한건 저것뿐이니 저것만주면 동작을 정상적으로 하니까
원래 studyBoard클래스에 있던 getRate()라는 함수를 매개변수에 객체를 보내는대신에 그 자료타입에 해당되는 클래스로 위치를 옮겨줬다.
객체를 매개변수로 통쨰로 보내주지않고 필요한 매개변수만 가볍게 받도록 수정한 결과이다
= 필요한 요소가 적으면 굳이 객체를 통쨰로까지 받아오면서 그자리에 있을필요없다. 필요한 요소가 많은쪽으로 자리를 옮기며 나머지 요소를 매개변수로 받자
함수를 독립적인 객체인, Command 로 만들어 사용할 수 있다.(= 확장성 있는 함수를 따로 클래스로 분리하는 방법)
커맨드 패턴 적용시 장점은 더 복잡한 기능을 구현하는데 필요한 여러 메서드, 로직을 추가 할수있다.
커맨드 패턴의 단점으로는 그만큼 클래스가 늘어나 전체적으로 복잡해진다.
대부분 경우 "함수"를 사용하지만 커맨드 말고 다른 방법이 없는 경우에 사용
command로 뽑기 -> 추출한 부분을 따로 클래스를 만들어 넣어준뒤 이 메서드에 필요한 연관된 메서드들도 같이 옮겨준다
이렇게 만들어주면 이전보다 좀더 독립적인 command 가 생성된다.
기존부분을 따로 뺴서 만들어준 클래스로 바꿔준다. 똑같이 동작하지만 분리를 함으로써 나중에 분리시킨 메서드에 좀더 복잡한 내용이나 확장 수정등이 더 쉬워진다.
하지만 그만큼 클래스를 추가해야 함으로 전체적으로 복잡성은 올라간다.
한눈에 보기에 내용파악이 힘들다
함수 추출 기능을사용해 함수이름으로 그 의미를 표현해주자
세세한 내용은 직접 코드들을 봐야하지만 대략적으로 어떻게 돌아가는지 파악이 가능해졌다.
하지만 여기서 더간단하게 삼항 연산자로 만들어주면?
이렇게 한줄로 표현가능.
if -else 문 = 삼항연산자 생각해보자
보통 반복문 하나에 여러 기능 넣는게 성능도 좋고 그러지만 될수있으면 나누자 왜냐하면 나중에 오류나 수정시 전자는 전체코드를 수정하기때문(코드가 다 반복문 안에 있으니)
변경/수정 하기 쉬운 flexible한 코드가 좋은코드다. 그렇지 못한 코드는 개발비용과 효율성에 영향을 주기때문
각각 기능을 나누면 그만큼 독립적이라 서로에게 영향을 주지않는다.
일단 두가지 기능을 하나하나로 나눈다. 그뒤로 메서드 추출로 각각 추출해준다 ( 기능을 나눠준뒤에 각각 메서드추출)
메서드의 매개변수를 줄이고싶다면(매개변수는 그 메서드가 필요로하는것들) 매개변수와 메서드를 같이 묶어서 메서드 추출. => 필요로 하는것을 아예 안으로 내장 시켜버리기
공통으로 많이사용하면 클래스 필드로 올려버린다.
switch-case 구문은 case에 따라 실행코드가 달라진다
상속 부모-자식 관계 클래스들을 만들어준다.
자바의 다형성 으로 인해 자식마다 각각 다르게 동작하는 메서드를 오버라이딩 한다.
부모클래스 일부