Code Size Rules
이 룰셋은 문제를 발생시킬 수 있는 코드 사이즈에 관한 룰을 포한한다.
NPathComplexity
메소드의 복잡성는 많은 량의 비순환적인 실행 문(acyclic execution paths)을 의미한다. 일반적인 한계점은 한 메소드당 200이며, 이 한계점을 넘은 복잡성를 줄일 필요가 있다.
public class Foo { void bar() { //대량의 복잡한 코드 (200 paths 이상) } }
ExcessiveMethodLength
하나의 메소드가 과도한 기능을 수행하는 것은 이 룰을 위반하는 것이며, 메소드의 사이즈를 줄이기 위하여 메소드 내의 기능을 분산 위임하여 실행할 수 있는 helper methods를 생성하거나 복사 붙여넣기로 만든 모든 코드를 제거한다.
public class Foo { public void doSomething() { System.out.println("Hello world!"); System.out.println("Hello world!"); // 98개의 이상의 같은 라인들... 자세한 설명은 생략한다. } }
ExcessiveParameterList
너무 많은 전달인자는 VO(Variable Object)와 같은 하나의 객체로 묶어서 전달하자.
public class Foo { //전달 인자가 너무 많아 버그의 가능성이 있다. VO같은 객체로 전달하자. public void addData( int p0, int p1, int p2, int p3, int p4, int p5, int p5, int p6, int p7, int p8, int p9, int p10) { ... } //간결하고 인자를 더욱 간편하게 관리할 수 있다. public void addData(DataVO dataVO) { ... } }
ExcessiveClassLength
매우 긴 길이의 클래스 파일은 과도한 기능 수행을 의미한다. 해당 클래스를 나누고 사이즈를 줄여서 관리가능한 상태로 만들어야한다.
public class Foo { public void bar() { // 1000 라인 이상의 코드 } }
CyclomaticComplexity
순환복잡도는 메소드 내의 결정포인트(decision point)들의 수로 결정된다. 결정포인트란 일반적으로 if, while, for 및 case labels들을 의미하며, 1-4는 낮은 복잡도, 5-7은 중간 복잡도, 8-9는 높은 복잡도 그리고 11이상은 매우 높은 복잡도를 의미한다.
// 아래의 순환 복잡도는 12이다. public class Foo { 1 public void example() { 2 if (a == b) { 3 if (a1 == b1) { fiddle(); 4 } else if a2 == b2) { fiddle(); } else { fiddle(); } 5 } else if (c == d) { 6 while (c == d) { fiddle(); } 7 } else if (e == f) { 8 for (int n = 0; n < h; n++) { fiddle(); } } else{ switch (z) { 9 case 1: fiddle(); break; 10 case 2: fiddle(); break; 11 case 3: fiddle(); break; 12 default: fiddle(); break; } } } }
ExcessivePublicCount
하나의 클래스 안에 매우 많은 수의 public method들과 attributes들이 존재한다면, 반드시 조금 더 정확 기능별로 나누어진 세분화된 클래스들로 위임해야하며, 그렇지 않을 경우 테스트를 위해서 많은 시간과 노력이 필요하다.
public class Foo { public String value; public Bar something; public Variable var; // [... 더 많은 public attributes ...] public void doWork() {} public void doMoreWork() {} public void doWorkAgain() {} // [... 더 많은 public methods ...] }
TooManyFields
클래스가 너무 많은 수의 클래스 맴버 변수들을 갖고 있다면, 가능한한 연관성 있는 필드들은 그룹화된 오브젝트로 붂어야한다. 예를 들어, city/state/zip 이라는 필드들은 Address라는 하나의 오브젝트로 묶일 수 있다.
public class Person { String city; String state; String zip; //위와 같은 필드들은 아래와 같이 Address라는 하나의 오브젝트로 묶어야 한다. Addresss address; [... 더많은 public fields ...] }
NcssMethodCount
이 룰은 NCSS(Non Commenting Source Statements: 주석이 아닌 라인 수) algorithm을 사용하여 해당 메소드에 얼마나 많은 코드라인이 존재하는지를 측정한다. NCSS algorithm은 주석은 제외하고, 순수 실제 코드만 체크하여 카운트 한다.
public class Foo extends Bar { public int methd() { super.methd(); //이 메소드는 실제로 1개의 NCSS 라인을 갖고 있다. return 1; } }
NcssTypeCount
이 룰은 NCSS(Non Commenting Source Statements: 주석이 아닌 라인 수) algorithm을 사용하여 해당 타입에 얼마나 많은 코드라인이 존재하는지를 측정한다. NCSS algorithm은 주석은 제외하고, 순수 실제 코드만 체크하여 카운트 한다.
public class Foo extends Bar { public Foo() { //이 클래스는 6개의 NCSS 라인을 포함한다. super(); super.foo(); } }
NcssConstructorCount
이 룰은 NCSS(Non Commenting Source Statements: 주석이 아닌 라인 수) algorithm을 사용하여 해당 생성자에 얼마나 많은 코드라인이 존재하는지를 측정한다. NCSS algorithm은 주석은 제외하고, 순수 실제 코드만 체크하여 카운트 한다.
public class Foo extends Bar { public Foo() { super(); //이 생성자는 1개의 NCSS 라인을 포함한다. super.foo(); } }
TooManyMethods
하나의 클래스가 너무 많은 메소드를 포함하면, 클래스의 복잡도를 줄이고 결합도가 높은 오브잭트들로 클래스를 구성하기위하여 리펙토링을 해야한다. 기본적인 최대 메소드 값은 10이다.
//하나의 클래스안에 10개 이상의 메소드가 존재한다. //Foo, Loo, Aoo 메소드들을 각각 별개의 클래스로 분할할 수 있다. public class Foo extends Bar { public Foo1() { ... } public Foo2() { ... } public Foo3() { ... } public Foo4() { ... } public Loo1() { ... } public Loo2() { ... } public Loo3() { ... } public Loo4() { ... } public Loo5() { ... } public Aoo1() { ... } public Aoo2() { ... } public Aoo3() { ... } }
해당 URL: http://pmd.sourceforge.net/pmd-4.2.6/rules/codesize.html