if else 쓰기 권장사항
왜 우리가 쓴 코드는if-else입니까?
프로그래머는 반드시 이런 장면을 겪었을 것이다. 처음에 자신이 쓴 코드는 매우 간결하고 논리가 뚜렷하며 함수가 간결하고if-else가 하나도 없다. 코드 논리가 끊임없이 보완되고 업무의 순식간에 변화할 수 있다. 예를 들어 인삼에 대해 유형과 값을 판단해야 한다.대상이null인지 아닌지 판단하기;유형에 따라 다른 절차를 집행한다.착지에서 구체적인 실현에 이르기까지 쉬지 않고if-else를 넣어서 처리할 수 밖에 없다. 점점 코드가 거대해지고 함수도 점점 길어진다. 파일 줄 수도 수천 줄을 신속하게 돌파하고 유지 보수의 난이도도 점점 높아지며 후기에는 기본적으로 유지하기 어려운 상태에 이르렀다.
비록 우리는 모두if-else 코드를 가득 쓰고 싶지 않지만 논리적으로는 특수한 판단이 필요하고 절망적이지만 피할 방법이 없다.
사실 자신의 코드를 돌아보고if-else를 쓰는 것은 두 가지 장면을 제외하고는 이상 논리 처리와 서로 다른 상태 처리이다.
양자의 가장 주요한 차이점은 이상 논리 처리는 단지 하나의 지점만 정상적인 절차이고 서로 다른 상태 처리는 모든 지점이 정상적인 절차라는 것이다.
어떻게 이해해요?예를 들면 다음과 같습니다.
// :
Object obj = getObj();
if (obj != null) {
//do something
}else{
//do something
}
// :
Object obj = getObj();
if (obj.getType == 1) {
//do something
}else if (obj.getType == 2) {
//do something
}else{
//do something
}
첫 번째 예
if (obj != null)
는 이상 처리이고 코드의 건장성 판단이며if안에서만 정상적인 처리 프로세스이고 else
분지는 오류 처리 프로세스이다.두 번째 예는 type이 1, 2든 다른 상황이든 모두 업무의 정상적인 절차에 속한다.이 두 가지 상황을 재구성하는 방법도 다르다.
코드if-else 코드가 너무 많으면 어떤 단점이 있습니까?
단점이 상당히 뚜렷해졌다.
최적화할 수 있는 좋은 방법이 있습니까?어떻게 재구성합니까?
if-else를 재구성할 때 마음속에 항상 하나의 원칙을 파악한다.
가능한 한 정상적인 프로세스 코드를 가장 바깥쪽에 유지하세요.
if-else 문장을 쓸 수 있을 때 반드시 메인 코드를 정상적인 절차로 유지하고 지나치게 깊이 박히지 않도록 해야 한다는 뜻이다.
실현의 수단은 끼워넣기 감소, 임시 변수 제거, 조건 추출 반판단, 합병 조건 표현식 등이 있다.
다음은 몇 가지 실례를 들어 이러한 재구성 방법을 설명한다.
예외 논리 처리형 재구성 방법의 실례 1:
재구성 전:
double disablityAmount(){
if(_seniority < 2)
return 0;
if(_monthsDisabled > 12)
return 0;
if(_isPartTime)
return 0;
//do somethig
}
재구성 후:
double disablityAmount(){
if(_seniority < 2 || _monthsDisabled > 12 || _isPartTime)
return 0;
//do somethig
}
이곳의 재구성 기법은 합병 조건 표현식이라고 한다. 만약에 일련의 조건 테스트가 모두 같은 결과를 얻으면 이 결과 테스트를 하나의 조건 표현식으로 통합시킨다.
이 재구성 기법은 간단하고 이해하기 쉬우며 가져오는 효과도 매우 뚜렷하고if문장을 효과적으로 적게 할 수 있으며 코드량을 줄일 수 있어 논리적으로도 더욱 이해하기 쉽다.
예외 논리 처리형 재구성 방법의 실례 2:
재구성 전:
double getPayAmount(){
double result;
if(_isDead) {
result = deadAmount();
}else{
if(_isSeparated){
result = separatedAmount();
}
else{
if(_isRetired){
result = retiredAmount();
else{
result = normalPayAmount();
}
}
}
}
return result;
재구성 후:
double getPayAmount(){
if(_isDead)
return deadAmount();
if(_isSeparated)
return separatedAmount();
if(_isRetired)
return retiredAmount();
return normalPayAmount();
}
어때요?두 판본에 비해 재구성된 판본은 논리가 뚜렷하고 간결하여 알기 쉽다.
재구성 전과는 도대체 어떤 차이가 있습니까?
가장 큰 차이점은if-else 플러그인을 줄이는 것이다.
보시다시피 최초 버전인if-else의 가장 깊은 삽입은 세 층으로 되어 있어 논리적인 구분이 매우 많고 안으로 들어가면 기본적으로 어지러워진다.사실 플러그 안에 있는if-else와 가장 바깥쪽은 연관성이 없어 맨 윗부분을 추출할 수 있다.
포함 관계가 아닌 평행 관계로 바뀌었고if-else 수량은 변화가 없지만 논리가 명확하고 일목요연하다.
또 다른 재구성점은 임시 변수
result
를 폐지하고 바로return으로 되돌아오는 것이다.장점도 명백히 절차를 직접 끝내고 이상 지점을 단축하는 것이다.원래의 방법은result에 먼저 값을 부여하고 마지막return을 통일시킨다. 그러면 마지막return의 값이 도대체 그 함수가 되돌아오는 결과가 명확하지 않아 이해난이도를 증가시켰다.요약 재구성 요점:if-else 플러그인이 관련성이 없으면 1층으로 직접 추출하고 논리적 플러그인이 너무 깊지 않도록 해야 한다.임시 변수를 최대한 줄여서 리턴으로 되돌려줍니다.
비정상적 논리 처리형 재구성 방법의 실례 3:
재구성 전:
public double getAdjustedCapital(){
double result = 0.0;
if(_capital > 0.0 ){
if(_intRate > 0 && _duration >0){
resutl = (_income / _duration) *ADJ_FACTOR;
}
}
return result;
}
첫 번째, 첫 번째: 중첩 감소 및 임시 변수 제거:
public double getAdjustedCapital(){
if(_capital <= 0.0 ){
return 0.0;
}
if(_intRate > 0 && _duration >0){
return (_income / _duration) *ADJ_FACTOR;
}
return 0.0;
}
이렇게 재구성한 후에도 주요 문장
(_income / _duration) * ADJ_FACTOR
이 부족하다.if 내부에서 가장 바깥쪽이 아니라 최적화 원칙(가능한 한 정상적인 프로세스 코드를 가장 바깥쪽에 유지)에 따라 재구성할 수 있다.public double getAdjustedCapital(){
if(_capital <= 0.0 ){
return 0.0;
}
if(_intRate <= 0 || _duration <= 0){
return 0.0;
}
return (_income / _duration) *ADJ_FACTOR;
}
이것이야말로 좋은 코드 스타일로 논리가 뚜렷하고 일목요연하며if-else 플러그인이 없으면 이해하기 어려운 절차이다.
여기에 사용된 재구성 방법은 조건을 반전시켜 이상 상황을 먼저 퇴출시키고 정상적인 프로세스를 주요 프로세스로 유지하는 것이다.
예외 논리 처리형 재구성 방법의 예 4:
재구성 전:
/* 18 */
public ArrayList getStudents(int uid){
ArrayList result = new ArrayList();
Student stu = getStudentByUid(uid);
if (stu != null) {
Teacher teacher = stu.getTeacher();
if(teacher != null){
ArrayList students = teacher.getStudents();
if(students != null){
for(Student student : students){
if(student.getAge() > = 18 && student.getGender() == MALE){
result.add(student);
}
}
}else {
logger.error(" ");
}
}else {
logger.error(" ");
}
} else {
logger.error(" ");
}
return result;
}
전형적인'화살표형'코드는 가장 큰 문제는 너무 깊이 끼워 넣는 것이다. 해결 방법은 이상 조건이 먼저 퇴출되고 주요 절차를 유지하는 것이 핵심 절차이다.
재구성 후:
/* 18 */
public ArrayList getStudents(int uid){
ArrayList result = new ArrayList();
Student stu = getStudentByUid(uid);
if (stu == null) {
logger.error(" ");
return result;
}
Teacher teacher = stu.getTeacher();
if(teacher == null){
logger.error(" ");
return result;
}
ArrayList students = teacher.getStudents();
if(students == null){
logger.error(" ");
return result;
}
for(Student student : students){
if(student.getAge() > 18 && student.getGender() == MALE){
result.add(student);
}
}
return result;
}
상태 처리형 재구성 방법 실례 1
재구성 전:
double getPayAmount(){
Object obj = getObj();
double money = 0;
if (obj.getType == 1) {
ObjectA objA = obj.getObjectA();
money = objA.getMoney()*obj.getNormalMoneryA();
}
else if (obj.getType == 2) {
ObjectB objB = obj.getObjectB();
money = objB.getMoney()*obj.getNormalMoneryB()+1000;
}
}
재구성 후:
double getPayAmount(){
Object obj = getObj();
if (obj.getType == 1) {
return getType1Money(obj);
}
else if (obj.getType == 2) {
return getType2Money(obj);
}
}
double getType1Money(Object obj){
ObjectA objA = obj.getObjectA();
return objA.getMoney()*obj.getNormalMoneryA();
}
double getType2Money(Object obj){
ObjectB objB = obj.getObjectB();
return objB.getMoney()*obj.getNormalMoneryB()+1000;
}
여기에 사용된 재구성 방법은if-else 내의 코드를 모두 공공 함수로 봉인하는 것이다.함수의 장점은 내부 실현을 차단하고if-else 지점의 코드를 단축하는 것이다.코드 구조와 논리적으로 명확하여 모든 조건 내에서 하는 기능을 한눈에 볼 수 있다.
상태 처리형 재구성 방법 실례2
상태 처리 코드에 대해 우아한 방법은 조건 표현식을 다중으로 대체하는 것이다(<재구성> 추천 방법).
대상 유형에 따라 다른 행동을 선택하는 조건 표현식이 있습니다.이 표현식의 각 지점을 하위 클래스 내의 복사 함수에 넣고 원시 함수를 추상 함수로 성명합니다.
재구성 전:
double getSpeed(){
switch(_type){
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed)?0:getBaseSpeed(_voltage);
}
}
재구성 후:
class Bird{
abstract double getSpeed();
}
class European extends Bird{
double getSpeed(){
return getBaseSpeed();
}
}
class African extends Bird{
double getSpeed(){
return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
}
}
class NorwegianBlue extends Bird{
double getSpeed(){
return (_isNailed)?0:getBaseSpeed(_voltage);
}
}
이를 통해 알 수 있듯이 다중태를 사용한 후if-else가 직접 없어졌지만 다중태를 사용하여 원래 코드를 너무 많이 수정했기 때문에 시간이 필요하다.가장 좋은 것은 설계 초기에 다태적인 방식을 사용하는 것이다.
총결산
if-else 코드는 모든 프로그래머가 가장 쉽게 쓸 수 있는 코드이자 썩기 쉬운 코드이다. 조금만 주의하지 않으면 유지보수와 논리가 혼란스러운 코드가 무더기로 발생한다.
조건부 코드 재구성을 위한 원칙 파악:
가능한 한 정상적인 프로세스 코드를 가장 바깥쪽에 유지하고 주요 프로세스를 유지하는 것이 정상적인 핵심 프로세스이다.
이 원칙을 유지하기 위해 합병 조건 표현식은if문장의 수를 효과적으로 줄일 수 있다.플러그를 줄이면 심층 논리를 줄일 수 있다.
이상 조건이 먼저 물러나면 자연스러운 메인 프로세스가 정상적인 프로세스다.
상태 처리형 재구성 방법은 두 가지가 있다. 하나는 서로 다른 상태의 조작을 함수로 봉인하고if-else 내 코드 행수를 간단하게 하는 것이다.다른 하나는 대상을 향한 다태적 특성을 이용하여 조건 판단을 직접 해치우는 것이다.
이제 자신의 코드를 돌아보고 어떤 전형적인 오류를 범했는지 얼른 이런 재구성 방법을 활용하여 코드를 재구성하세요!!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.