이 글에는 제가 주변 동료들의 Java 코드에서 본 대표적인 오류가 나열되어 있습니다. 분명히 정적 코드 분석(우리 팀은 qulice를 사용함)으로 모든 문제를 찾을 수는 없으므로 여기에 나열합니다.
누락된 내용이 있다고 생각되면 알려주시면 기꺼이 추가해 드리겠습니다.
아래 나열된 오류는 모두 기본적으로 객체 지향 프로그래밍, 특히 Java의 OOP와 관련이 있습니다.
물론 클래스와 인터페이스를 구별하기 위해 접두사나 접미사를 사용하지 마세요. 예를 들어 IRecord, IfaceEmployee 또는 RecordInterface와 같은 이름은 잘못되었습니다. 일반적으로 인터페이스 이름은 실제 엔터티의 이름이어야 하며, 클래스 이름은 구현 세부 사항을 설명해야 합니다. 구현에 특별한 것이 없다면 이를 Default, Simple 또는 이와 유사한 이름으로 부를 수 있습니다. 예:
class SimpleUser implements User {}; class DefaultRecord implements Record {}; class Suffixed implements Name {}; class Validated implements Content {};
메서드 이름
메서드는 값 또는 void를 반환할 수 있습니다. 메서드가 값을 반환하는 경우 해당 이름은 반환되는 내용을 설명해야 합니다. 예를 들어(접두사 get을 사용하지 마세요):
boolean isValid(String name); String content(); int ageOf(File file);
void를 반환하는 경우 해당 이름은 수행한 작업을 설명해야 합니다. 예:
void save(File file); void process(Work work); void append(File file, String line);
방금 언급한 규칙에는 단 하나의 예외가 있습니다. JUnit의 테스트 방법은 포함되지 않습니다. 이에 대해서는 아래에서 논의하겠습니다.
테스트 메소드 이름
JUnit 테스트 케이스에서 메소드 이름은 공백이 없는 영문명이어야 한다. 다음 예를 보면 더 명확해집니다.
/** * HttpRequest can return its content in Unicode. * @throws Exception If test fails */ public void returnsItsContentInUnicode() throws Exception { }
JavaDoc의 첫 번째 문장은 테스트하려는 클래스 이름으로 시작하고 그 뒤에 캔이 와야 합니다. 그러므로 첫 번째 문장은 "누군가는 뭔가를 할 수 있다"와 같아야 합니다.
메소드 이름도 동일하지만 테마가 없습니다. 메서드 이름 중간에 제목을 추가하면 위의 예와 같이 "HttpRequest가 해당 콘텐츠를 유니코드로 반환합니다."라는 완전한 문장을 얻게 됩니다.
시험법명은 캔으로 시작하지 않으니 주의하세요. JavaDoc의 주석만 can으로 시작됩니다. 또한 메소드 이름은 동사로 시작하면 안 됩니다.
실제로는 Exception을 발생시키는 테스트 메소드를 선언하는 것이 가장 좋습니다.
변수 이름
timeOfDay, firstItem 또는 httpRequest와 같은 변수 이름을 결합하지 마세요. 이는 클래스 변수와 메서드 내의 변수에 해당됩니다. 변수 이름은 표시 범위 내에서 모호함을 피할 수 있을 만큼 길어야 하지만 가능하면 너무 길면 안 됩니다. 이름은 단수 또는 복수 형태의 명사이거나 적절한 약어이어야 합니다. 예:
List<String> names; void sendThroughProxy(File file, Protocol proto); private File content; public HttpRequest request;
때때로 생성자가 입력 매개변수를 새로 초기화된 객체에 저장하려는 경우 해당 매개변수 이름과 클래스 속성 이름이 충돌할 수 있습니다. 이 경우 모음을 제거하고 약어를 사용하는 것이 좋습니다.
예:
public class Message { private String recipient; public Message(String rcpt) { this.recipient = rcpt; } }
클래스 이름을 보면 변수에 어떤 이름을 지정해야 하는지 알 수 있는 경우가 많습니다. 다음과 같이 신뢰할 수 있는 소문자 형식을 사용하세요.
File file; User user; Branch branch;
그러나 정수 숫자나 문자열 문자열과 같은 기본 유형에서는 이 작업을 수행하면 안 됩니다.
본질이 다른 변수가 여러 개인 경우 형용사 사용을 고려해 볼 수 있습니다. 예:
String contact(String left, String right);
생성자
예외를 고려하지 않는 경우 개체 변수에 데이터를 저장하는 데 사용되는 생성자는 하나만 있어야 합니다. 다른 생성자는 다른 매개변수를 사용하여 이 생성자를 호출합니다. 예:
public class Server { private String address; public Server(String uri) { this.address = uri; } public Server(URI uri) { this(uri.toString()); } }
일회용 변수
일회용 변수는 어떻게 해서든 피해야 합니다. 여기서 "일회성"이란 한 번만 사용되는 변수를 의미합니다. 예:
String name = "data.txt"; return new File(name);
위 변수는 한 번만 사용되므로 이 코드는 다음과 같이 재구성될 수 있습니다.
return new File("data.txt");
가끔 드문 경우지만 - 주로 서식 지정을 위해 더 보기 좋게 - 아마도 하나를 사용할 것입니다. -시간 변수. 그러나 이는 가능한 한 피해야 합니다.
예외
물론, 예외를 절대 스스로 삼키면 안 되고, 최대한 넘겨야 합니다. 개인 메소드는 항상 확인된 예외를 발생시켜야 합니다.
프로세스 제어에 예외를 사용하지 마세요. 예를 들어, 다음 코드는 잘못되었습니다.
int size; try { size = this.fileSize(); } catch (IOException ex) { size = 0; }
IOException이 "디스크가 꽉 찼습니다"라는 메시지를 표시하면 어떻게 해야 합니까? 아직도 파일 크기가 0이라고 생각하고 계속 처리하시겠습니까?
들여쓰기
들여쓰기의 주요 규칙은 여는 괄호가 줄의 끝에 있거나 같은 줄에서 닫혀야 한다는 것입니다(닫는 괄호의 경우 그 반대). 예를 들어, 다음은 첫 번째 여는 괄호가 같은 줄에서 닫히지 않고 그 뒤에 다른 문자가 있기 때문에 올바르지 않습니다. 두 번째 괄호에도 문제가 있습니다. 앞에 문자가 있지만 해당 여는 괄호가 같은 줄에 있지 않기 때문입니다.
final File file = new File(directory, "file.txt");
올바른 들여쓰기는 다음과 같아야 합니다.
StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join( Arrays.asList("a", "b") ) ), "separator" );
들여쓰기에 대하여 이제 두 번째 중요한 규칙은 한 줄에 최대한 많은 문자를 동시에 쓰는 것입니다. 최대 제한은 80자입니다. 위의 예는 이 점을 만족하지 않으며 축소될 수도 있습니다.
StringUtils.join( Arrays.asList( "first line", "second line", StringUtils.join(Arrays.asList("a", "b")) ), "separator" );
중복 상수
当你希望在类的方法中共享信息的时候,应当使用类常量,这些信息应该是你这个类所特有的。不要把常量当作字符串或数值字面量的替代品来使用——这是非常糟糕的实践方式,它会对代码造成污染。常量(正如OOP中的任何对象一样)应当在真实世界中有它自己的含义。看下这些常量在真实生活中的意思是什么:
class Document { private static final String D_LETTER = "D"; // bad practice private static final String EXTENSION = ".doc"; // good practice }
另一个常见的错误就是在单元测试中使用常量来避免测试方法中出现冗余的字符串或者数值的字面量。不要这么做!每个测试方法都应该有自己专属的输入值。
在每个新的测试方法中使用新的文本或者数值。它们是相互独立的。那么为什么它们还要共享同样的输入常量呢?
测试数据耦合
下面是测试方法中数据耦合的一个例子:
User user = new User("Jeff"); // maybe some other code here MatcherAssert.assertThat(user.name(), Matchers.equalTo("Jeff"));
最后一行中,”Jeff”和第一行中的同一个字符串字面值发生了耦合。如果过了几个月,有人想把第三行这个值换一下,那么他还得花时间找出同一个方法中哪里也使用了这个”Jeff”。
为了避免这种情况,你最好还是引入一个变量。
更多Java编程中的一些常见问题汇总相关文章请关注PHP中文网!