제가 사용하는 모든 언어에서 저를 괴롭혔던 것은 if 문이 있지만 조건부 부분에 체크가 너무 많아서 여러 줄로 나누거나 중첩된 if 문을 사용하거나 그냥 못생겼다는 것을 인정하고 계속 살아가야 한다는 것이었습니다.
저와 같은 문제에 직면한 다른 사람에게 유용할 만한 다른 방법이 있나요?
예를 들어, 모두 한 줄로 정리하세요:
if (var1 = true && var2 = true && var2 = true && var3 = true && var4 = true && var5 = true && var6 = true)
{
예, 여러 줄:
if (var1 = true && var2 = true && var2 = true
&& var3 = true && var4 = true && var5 = true
&& var6 = true)
{
예제 중첩:
if (var1 = true && var2 = true && var2 = true && var3 = true)
{
if (var4 = true && var5 = true && var6 = true)
{
사용 후 컨디션이 분리하십시오 여러 불 (bool) 값들 마스터 부울입니다 조건으로.
bool isOpaque = object.Alpha == 1.0f;
bool isDrawable = object.CanDraw && object.Layer == currentLayer;
bool isHidden = hideList.Find(object);
bool isVisible = isOpaque && isDrawable && ! isHidden;
if(isVisible)
{
// ...
}
더 좋은 것은:
public bool IsVisible {
get
{
bool isOpaque = object.Alpha == 1.0f;
bool isDrawable = object.CanDraw && object.Layer == currentLayer;
bool isHidden = hideList.Find(object);
return isOpaque && isDrawable && ! isHidden;
}
}
void Draw()
{
if(IsVisible)
{
// ...
}
}
그 뜻을 나타내는 함수 이름 대신 스튜어리 com/go/4e6b330a_kr 제공하세요 합니다. 이 코드를 개발자가 유지에 큰 도움이 된다. 이 오류는 너!
<, http://www.refactoring.com/catalog/decomposeConditional.html>.
두 가지 문제를 해결할 수 있습니다. 가독성 및 이해도
이 " readability"; ) 은 문제 및 솔루션 등 열려 해석할 수 있습니다. 내 기본 로만스였나:
if (var1 == true && // Explanation of the check
var2 == true && // Explanation of the check
var3 == true && // Explanation of the check
var4 == true && // Explanation of the check
var5 == true && // Explanation of the check
var6 == true) // Explanation of the check
{ }
나 이:
if (var1 && // Explanation of the check
var2 && // Explanation of the check
var3 && // Explanation of the check
var4 && // Explanation of the check
var5 && // Explanation of the check
var6) // Explanation of the check
{ }
즉, 이 같은 복잡한 확인란 스캔할 때 정신적으로 상당히 어렵다 분석할 수 있는 코드 (특히 않을 경우 원래 작성자). 일부 등을 만드는 것을 고려해보십시오 복잡성입니다 helper 방법을 요약:
/// <Summary>
/// Tests whether all the conditions are appropriately met
/// </Summary>
private bool AreAllConditionsMet (
bool var1,
bool var2,
bool var3,
bool var4,
bool var5,
bool var6)
{
return (
var1 && // Explanation of the check
var2 && // Explanation of the check
var3 && // Explanation of the check
var4 && // Explanation of the check
var5 && // Explanation of the check
var6); // Explanation of the check
}
private void SomeMethod()
{
// Do some stuff (including declare the required variables)
if (AreAllConditionsMet (var1, var2, var3, var4, var5, var6))
{
// Do something
}
}
이 때, 이제 시각적으로 스캐만을 " SomeMethod". 그러나 실제 의미는 숨겨짐 테스트 방법, 복잡한 논리를 이해할 수 있도록 만든 인간은 아니했으니 개략적으로. 개발자가 이해하는 데 꼭 필요한 경우 아레올콘딧리옹스메 방법을 자세히 검사를 할 수 있다.
이것은 공식적으로 알려진 Conditional" 분해해야 "; 리팩토링 패턴화합니다 것 같네요. 같은 도구를 리샤퍼 또는 리팩터링 pro/무선! 이 일을 할 수 있는 종류의 리팩토링 쉽냐구요!
모든 경우에, 코드를 읽고 이해할 수 있는 현실적인 갖추고 주요 변수 이름을 사용할 수 있습니다. 예를 들어,,, 나 알고 있지만, 이것은 " var1" " var2" 등이 변수 이름을 사용할 수 없습니다. 기본 데이터 특성을 반영하는 이름을 가지고 한다는 의미입니다.
먼저, == true
부분을 모두 제거하면 50% 더 짧아집니다.)
큰 조건이 있을 때는 그 이유를 찾아봅니다. 다형성을 사용해야 할 때도 있고, 어떤 상태 객체를 추가해야 할 때도 있습니다. 기본적으로 리팩터링이 필요하다는 것을 의미합니다(코드 냄새).
때때로 저는 부울 표현식을 약간 단순화하기 위해 De-Morgan의 법칙을 사용합니다.
[구축상의 패턴] [1] 에서 체크아웃합니다 켄트 벡 (. 이 상황에서 내가 도울 수 있는 특정 패턴을 생각하고 있습니다. it 호출됨 Guards" ";). 것보다 세제곱밀리미터 조건 때문에 아웃하라는 끊을 수 있습니다, 이는 부정적인 상태에 있는 붙여넣습니다 가드 선택해제합니다 메서드입니다.
예를 들어, 뭔가 않는 경우, 특정 조건을 메서드입니다 수축됐는데 shouldn& # 39 곳에 뭔가 아닌, t:
public void doSomething() {
if (condition1 && condition2 && condition3 && condition4) {
// do something
}
}
이를 변경할 수 있습니다.
public void doSomething() {
if (!condition1) {
return;
}
if (!condition2) {
return;
}
if (!condition3) {
return;
}
if (!condition4) {
return;
}
// do something
}
그나저나 나는 그 책을 것을 권장합니다.
[1]: http://www.amazon.com/implementation-patterns-addison-wesley-signature-kent/dp/ 0321413091
많은 사람과 편집자가 if 문에서 각 조건을 하나의 탭으로 들여쓰기를 하거나 열린 부모와 일치시키는 것을 보았습니다:
if (var1 == true
&& var2 == true
&& var3 == true
) {
/* do something.. */
}
저는 보통 마지막 조건과 같은 줄에 닫는 파렌을 넣습니다:
if (var1 == true
&& var2 == true
&& var3 == true) {
/* do something.. */
}
하지만 저는 이것이 그렇게 깔끔하지 않다고 생각합니다.
보고 시도하시겠습니까 함자 및 술어. 아파치 커먼즈 사업은 큰 개체 세트를 캡슐화됨 조건부 논리를 객체에는 수 있습니다. 예, 라일리 사용법을 O& [here] [1] # 39 에서 사용할 수 있습니다. 발췌문 코드 예제:
import org.apache.commons.collections.ClosureUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.NOPClosure;
Map predicateMap = new HashMap();
predicateMap.put( isHonorRoll, addToHonorRoll );
predicateMap.put( isProblem, flagForAttention );
predicateMap.put( null, ClosureUtils.nopClosure() );
Closure processStudents =
ClosureUtils.switchClosure( predicateMap );
CollectionUtils.forAllDo( allStudents, processStudents );
이제 그 모든 정보를 이오노럴 술어 및 폐쇄를 평가하는 데 사용되는 아니하시더라:
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.Predicate;
// Anonymous Predicate that decides if a student
// has made the honor roll.
Predicate isHonorRoll = new Predicate() {
public boolean evaluate(Object object) {
Student s = (Student) object;
return( ( s.getGrade().equals( "A" ) ) ||
( s.getGrade().equals( "B" ) &&
s.getAttendance() == PERFECT ) );
}
};
// Anonymous Predicate that decides if a student
// has a problem.
Predicate isProblem = new Predicate() {
public boolean evaluate(Object object) {
Student s = (Student) object;
return ( ( s.getGrade().equals( "D" ) ||
s.getGrade().equals( "F" ) ) ||
s.getStatus() == SUSPENDED );
}
};
// Anonymous Closure that adds a student to the
// honor roll
Closure addToHonorRoll = new Closure() {
public void execute(Object object) {
Student s = (Student) object;
// Add an award to student record
s.addAward( "honor roll", 2005 );
Database.saveStudent( s );
}
};
// Anonymous Closure flags a student for attention
Closure flagForAttention = new Closure() {
public void execute(Object object) {
Student s = (Student) object;
// Flag student for special attention
s.addNote( "talk to student", 2005 );
s.addNote( "meeting with parents", 2005 );
Database.saveStudent( s );
}
};
[1]: 페이지 (http://www.onjava.com/pub/a/onjava/2004/12/22/jakarta-gems-1.html) = 2?
다차원 테이블을 사용합니다. 각 변수는, 테이블에 인덱스화할 역할을 합니다 if 문은 테이블 검색 및 바뀝니다. 예를 들어 (크기) = 3 & &; 무게 >. 70) 테이블에 구체화합니다 초급형 진단트리 [크기] [weight_group]
[1]: http://www.amazon.com/code-complete-practical-handbook-construction/dp/ sr_1_1? 키드 = 0735619670, 1219037602, s = = = ie /ref utf8& books& & sr = 1-1.
뭐, first off, 왜안돼요:
>. if (var1 & &; var2 & &; var2 & &; var3 & &; var4 & &; var5 & &; var6) { >. .
또한 매우 어려운 추상적인 리팩터링 it& # 39 의 코드 예제. 이 경우 구체적인 예를 들어 더 나은 패턴을 식별하기 쉽게 맞게 될 것으로 보인다.
(다음 방법을 단락 첫 번째 테스트는 테스트, 모든 것을 부울을 경우에도 실행하십시오 거짓. 아닌 권장됨 패턴화합니다 모르면 할 때 항상 실행 코드를 살펴보기 위해 내 모든 복귀하기 전에 - 덕분에 pto마토 실수!)
>. 부울입니다 확인 = cond1. >. 확인 = cond2 &; >. 확인 = cond3 &; >. 확인 = cond4 &; >. 확인 = cond5 &; >. 확인 = cond6 &;
이는 같은 as:< /strike> strike> <;;; (위 참고 http://schmidt. devlib. 다릅니다!)
>. 확인 = (cond1 & &; cond2 & &; cond3 & &; cond4 & &; cond5 & &; cond6);
if ( (condition_A)
&& (condition_B)
&& (condition_C)
&& (condition_D)
&& (condition_E)
&& (condition_F)
)
{
...
}
반대로
if (condition_A) {
if (condition_B) {
if (condition_C) {
if (condition_D) {
if (condition_E) {
if (condition_F) {
...
}
}
}
}
}
}
및
if ( ( (condition_A)
&& (condition_B)
)
|| ( (condition_C)
&& (condition_D)
)
|| ( (condition_E)
&& (condition_F)
)
)
{
do_this_same_thing();
}
반대로
if (condition_A && condition_B) {
do_this_same_thing();
}
if (condition_C && (condition_D) {
do_this_same_thing();
}
if (condition_E && condition_F) {
do_this_same_thing();
}
대부분의 경우 코드 정적 분석 툴을 조건식의 명시성 괄호를 사용하지 않는 것을 받아 표현식에서는 조사하기 위한 여러 불만이 커질 것으로 보인다 의존하지 않고 작동자 우선 순위 규칙 및 분석, 적은 수의 괄호.
중괄호 ({}, 오픈 들여쓰려면 수준의 오픈 / vertical alignment 동시에 닫으십시오 괄호 () 는, 연산자, 괄호 닫으십시오 조건식의 왼쪽에 있는 것이 아닌, 이 코드의 가독성, 투명성을 높일 수 있는 매우 유용하게 사용할 수 있는 모든 현상이 크게 가능성이 높아, 세로 정렬을 한 줄로 걸린 관용으로충만하신 샌을 공백이나 괄호
까다로운 규칙이 & &, 연산자 우선순위를 정한다. (예: 이 보다 우선 순위가 높은 순위에 비해 높지만, & &;
따라서.
if (expr_A & expr_B || expr_C | expr_D & expr_E || expr_E && expr_F & expr_G || expr_H {
}
참으로 쉬운 것은 잘못 읽고 여러 조건 표현식 평가하십시오 그쳤다.
if ( ( (expr_A)
& (expr_B)
)
|| ( (expr_C)
| ( (expr_D)
& (expr_E)
)
)
|| ( (expr_E)
&& ( (expr_F)
& (expr_G)
)
)
|| (expr_H)
)
{
}
별 문제가 가로, 세로 배치, 또는 공간 (linefeed) 평가, 이 모든 것을 가독성 및 선명도 향상 지도 표현식에서는 명시성 괄호
그래서 내가 좋아하는 그들을 분할하려면 하락한 단위로레벨에서 I& 다음과 같은 형식을 너회가 예제에서와 # 39; d
if (var1 = true
&& var2 = true
&& var2 = true
&& var3 = true
&& var4 = true
&& var5 = true
&& var6 = true){
if ((var1 = true && var2 = true)
&& ((var2 = true && var3 = true)
&& (var4 = true && var5 = true))
&& (var6 = true)){
>>> L = [True, True, True, False, True]
>>> all(L) # True, only if all elements of L are True.
False
>>> any(L) # True, if any elements of L are True.
True
해당 기능을 유지됩니까 자국어로 (C #? Java?). # 39 의 비활성화되면 that& 지적도 나오고 깨끗한 외곽진입.
@tweakt >. # 39 의 no better, 그렇다면 it& I& # 39, ve done in the past. >. >. 부울입니다 확인 = cond1. >. 확인 = cond2 &; >. 확인 = cond3 &; >. 확인 = cond4 &; >. 확인 = cond5 &; >. 확인 = cond6 &; >. >, 원하는거요 동일합니까: >. >. 확인 = (cond1 & &; cond2 & &; cond3 & &; cond4 & &; cond5 & &; cond6);
대부분의 언어에서 이 두 가지 사실 같지 않습니다. 두 번째 표현식에서는 조건 중 하나로 평가되고 있다 는 일반적으로 정지점을 곧 큰 성능 향상을 평가 = false 될 수 있는 조건을 경우 비용이 너무 많이 든다.
개인적으로 # 39, 마이크 Stone& 제안한 포지셔닝하십시오 쉽게 구별할 수 있도록 한다. # 39 의 it& 자세하게 설명, 모두 보존할 수 있어 초기 수 있다는 계산이 나온다. # 39 의 기능을 수행할 수 있습니다; d 의 경우 동일한 기술을 인라인 it& 혼란을 执行 코드에서 사용 중인 다른 평가 멀리 조건부 이동할 수 있다. # 39 의 it& 수 있지만 항상 다음과 같은 일을 조금 손 가득
do {
if (!cond1)
break;
if (!cond2)
break;
if (!cond3)
break;
...
DoSomething();
} while (false);
그 동안 (false) 는 같은 손 가득. I wish 언어 영역, once" 연산자입니다 " 불렀으매 했다. 또는 생각하신거야 아웃해야 쉽게 끊을 수 있습니다.
I like to break 로 각 찼음을 설명식 com/go/4e6b330a_kr.
bool isVar1Valid, isVar2Valid, isVar3Valid, isVar4Valid;
isVar1Valid = ( var1 == 1 )
isVar2Valid = ( var2.Count >= 2 )
isVar3Valid = ( var3 != null )
isVar4Valid = ( var4 != null && var4.IsEmpty() == false )
if ( isVar1Valid && isVar2Valid && isVar3Valid && isVar4Valid ) {
//do code
}