《코드 정결의 길》의 총결을 읽다.
은 일찌감치'코드 깔끔의 길'(영문판 Clean Code)을 읽었는데, 당시 블로거는 풋풋한 풋내기로 팀을 위해 혼란스러운 코드를 만들고 있었다.다년간의 업무 중에 여러 차례 다른 사람의 코드에 의해 곤경에 빠졌는데, 그 당시 내가 남긴 코드를 회상하면 틀림없이 훗날의 동료들을 해쳤을 것이다.JDK 원본 코드나 다른 우수한 원본 프로젝트를 읽을 때 작가의 코드 구축이 훌륭하다고 탄복한다. 그들은 모두 공통된 특징을 가지고 있다. 바로 정확한 변수 이름, 적당한 디자인 모델, 상세하고 군더더기 없는 주석 등이다.이제 이 책을 다시 읽고 내용을 정리하고 자신의 견해를 덧붙여 여러분과 공유하겠습니다.
코드는 단체 소통 방식이다
업무의 소통은 전자메일이나 대면 언어 교류가 아니라 코드도 소통 방식 중의 하나이다.코드로 수요를 실현하는 것은 단지 만리장정의 첫걸음을 마쳤을 뿐이고 반드시 코드가 자신의 디자인 사상을 표현하도록 해야 한다.생각해 보아라. 당신이 맡은 기능은 다른 동료에게 맡겨져 있다. 만약 당신의 코드 구조가 명확하고 주석이 합리적이라면, 그는 빈번하게 코드의 의문점을 묻지 않고, 당신의 일을 끊지 않아도 된다.코드를 작성할 때 다른 사람의 읽기 느낌을 고려하여 읽기 장애를 줄이고 팀 전체를 위해 코드를 만들어야 한다. 너 자신이 아니라 팀 전체를 위해 코드를 만들어야 한다.
캠프를 올 때보다 더 깨끗하게
이것은 미국 보이스카우트의 속담으로 미국 보이스카우트는 반군사화 관리의 청소년 캠프에 해당한다.여름 캠프가 끝난 후 아이들은 캠프를 떠나서 청소를 깨끗이 하고 캠프를 올 때보다 더 깨끗하게 해야 한다.소프트웨어 개발 과정에서
,
로 이해할 수 있다.만약에 팀에서 코드 규범을 제정했다면 예를 들어 클래스 이름은 반드시 서브시스템 접두사가 있어야 한다. 예를 들어BiOrderService
(Bi는 BI 업무 부서를 가리킨다) 계속 따라간다.그리고 예를 들어 팀은 이미 공공 라이브러리, 예를 들어 MD5의 암호화를 제공했으니 새로운 MD5 라이브러리를 다시 도입하지 마세요.많은 신입 프로그래머들이 일을 맡은 후에 마음에 들지 않는 규범을 보고 다른 부뚜막을 짓는다. 어떤 공구류가 필요하면 늙은 운전자의 공공 라이브러리에 있는지 물어보지 않고 자신이 익숙한 라이브러리에 직접 도입하여 호환성이나 다른 문제를 초래한다.적합한 명칭
적당한 명칭은 신생아에게 좋은 이름을 지어주는 것만큼 중요하다.부적합한 명명은 통상
、 、
등인데, 영어가 우리의 모국어가 아니기 때문에 적당한 단어를 찾아 명명하는 것은 정말 어려운 것 같다.나는 먼저 업무를 분명히 하고 회의를 조직하여 상용 업무 영역의 단어를 정하고 팀원들이 각자 발명하는 것을 금지하는 것을 건의한다.예를 들어 코드에 canteen
를 사용하여 식당을 표시한다면 더 이상 발명하지 마라DinnerHall
. 수다스럽고 동료를 오도하지 마라.반례를 봐라.
//
String phone = “13421800409”;
//
private String getDiZhi();
//
private void modifyPassword(String password1 ,String password2)
정례를 봐라.
// mobileNo phone
String mobileNo= “13421800409”;
//
private String getAddress();
//
private void modifyPassword(String oldPassowrd,String newPassword)
자그마한 방법
방법이 얼마나 짧아야 적합한지는 정해지지 않았지만 500줄에 달하는 한 방법은 독서자들에게 살인심을 불러일으켰다.지나치게 긴 방법은 읽는 사람들로 하여금 어디서부터 보아야 할지 모르게 앞을 보고 뒤를 잊게 한다.복잡한 방법을 논리적으로 상대적으로 간단한 짧은 방법으로 나누다.
반례를 봐라.
//
private UserDTO getUserDTO(Integer userId)
{
//
… 10
//
… 30
// 、
… 30
return userDTO;
}
정례를 봐라.
//
private UserDTO getUserDTO(Integer userId)
{
//
UserDTO userDTO= getUserBasicInfo(userId);
//
userDTO.setUserLastOrder(getUserLastOrder(userId));
// 、
userDTO.setUserAccount(getUserAccount(userId));
return userDTO;
}
private UserDTO getUserBasicInfo(Integer userId);
private UserLastOrder getUserLastOrder(Integer userId);
private UserAccount getUserAccount(Integer userId);
if/else 중첩 감소
왜 플러그를 줄여야 하는지, 플러그가 스타일리시해 보이지 않나요?나는 일찍이 어떤 동료의 코드가 9층에 끼워져 있는 것을 보았는데, 그가 스스로 다시 관리하러 갔을 때 모두 멀미를 했다.코드를 과도하게 끼워 넣은 결과 원작자만 읽을 수 있었고, 리시버맨은 망연자실했다.
반례를 봐라.
// , 3 ,
public boolean modifyPassword(Integer userId, String oldPassword, String newPassword) {
if (userId != null && StringUtils.isNotBlank(newPassword) && SpringUtils.isNotBlank(oldPassword)) {
User user = getUserById(userId);
if (user != null) {
if (user.getPassword().equals(oldPassword) {
return updatePassword(userId, newPassword)
}
}
}
}
정례를 봐라.
//
Public Boolean modifyPassword(Integer userId, String oldPassword, String newPassword) {
if (userId == null || StringUtils.isBlank(newPassword) || StringUtils.isBlank(oldPassword)) {
return false;
}
User user = getUserById(userId);
if(user == null) {
return false;
}
if(!user.getPassword().equals(oldPassword) {
return false;
}
return updatePassword(userId, newPassword);
}
정례적으로 위문구를 채택하여 삽입을 줄였지만 모든 장면이 이렇게 개작하기에 적합한 것은 아니다.만약 적합하지 않다면 연관성이 높은 논리를 하나의 독립된 방법으로 추출하여 끼워 넣는 것을 줄일 수 있다.
try/catch 분리
여러분은 처음부터 끝까지try/catch에 의해 보살핌을 받는 아주 긴 방법을 본 적이 있습니까?블로거가 겪은 프로젝트 중에는 이런 무책임한 묘사가 비일비재하다.모든 줄 코드가 오류를 던지는 것은 아니다. 오류를 던지는 업무를 하나의 독립된 방법에 두기만 하면 된다.
반례를 봐라.
//
private UserDTO getUserDTO(Integer userId)
{
try {
//
... 10
// .
... 20
// 、
... 20
}catch (Exception e) {
logger.error(e);
return null;
}
}
return userDTO;
}
정례를 봐라.
//
private UserDTO getUserDTO(Integer userId)
{
//
UserDTO userDTO= getUserBasicInfo(userId);
//
userDTO.setUserLastOrder(getUserLastOrder(userId));
// 、
userDTO.setUserAccount(getUserAccount(userId));
return userDTO;
}
private UserDTO getUserBasicInfo(Integer userId);
private UserLastOrder getUserLastOrder(Integer userId);
private UserAccount getUserAccount(Integer userId){
try{
// TODO
} catch ( Exception e)
{ //TODO }
}
여러 매개변수 패키지화
방법 파라미터가 3개를 초과할 경우 클래스에 포장하는 것을 권장합니다. 그렇지 않으면 파라미터를 추가할 때 의미의 강한 결합으로 인해 호출자 문법 오류가 발생할 수 있습니다.백엔드 관리에서 페이지 조회 인터페이스는 종종 많은 조회 매개 변수가 있을 뿐만 아니라 증가할 수도 있어 봉인하는 것이 가장 좋다.
반례를 봐라.
// 6
public Page queryOrderByPage(Integer current,Integer size,String productName,Integer userId,Date startTime,Date endTime,Bigdecimal minAmount ,Bigdecimal maxAmount) {
}
정례를 봐라.
@Getter
@Setter
public class OrderQueryDTO extends PageDTO {
private String productName;
private Integer userId;
private Date startTime;
private Date endTime;
private Bigdecimal minAmount ;
private Bigdecimal maxAmount;
}
// 6
Public Page queryOrderByPage(OrderQueryDTO orderQueryDTO) {
}
타사 라이브러리
Lombok
Lombok 구성 요소는 주석을 통해 컴파일할 때 자동으로 속성 생성기, Getter/setter, equals,hashcode, toString 방법을 사용합니다. 예를 들면 다음과 같습니다. @Setter 주석은 클래스나 필드에 있고, 주석은 클래스에서 모든 필드에 setter 방법을 생성합니다. 주석은 필드에서 setter 방법만 생성합니다. @Getter 사용 방법은 Getter 방법을 만드는 것과 다릅니다. @Tostring 주석은 클래스에 있고, tostring 방법을 추가합니다. @EqualsAndHashCode는 클래스에 주석을 달고 hashCode와 equals 방법을 생성합니다. @NoArgsConstructor는 클래스에 주석을 달고 참조가 없는 구조 방법을 생성합니다. @RequiredArgsConstructor는 클래스에 주석을 달고, 클래스에 특수 처리가 필요한 필드를 구성합니다. 예를 들어final과 @NonNull에 주석이 달린 필드입니다. @AllArgsConstructor는 클래스에 주석을 달고 클래스의 모든 필드를 포함하는 구조 방법을 생성합니다. @데이터 주석은 클래스에서 setter/getter, equals, canEqual,hashCode,toString 방법을 생성하고final 속성이라면 이 속성에 setter 방법을 생성하지 않습니다.
일반 쓰기:
Public class Order {
private Integer userId;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
return this.userId = userId;
}
}
Lombok 사용:
@Getter
@Setter
Public class Order {
private Integer userId;
}
Apache Commons 제품군
Apache Commons 시리즈 구성 요소는 문자열, 컬렉션, 입출력 작업과 같은 도구 방법을 제공합니다.이 조립품들은 큰 보고로 많은 바퀴를 제공하였다.
구성 요소
소개하다.
beanUtils
JavaBean은 다양한 작업을 수행하며 객체, 속성 등을 복제합니다.
codec
자주 사용하는 인코딩 방법을 처리하는 도구 패키지입니다. 예를 들어 DES, SHA1, MD5,Base64 등입니다.
collections
java 집합 프레임워크 조작
configuration
java 응용 프로그램 설정 관리 라이브러리
io
io 도구 패키지
lang
Java 기본 대상 방법의 도구 클래스 패키지는 StringUtils,ArrayUtils 등입니다.
logging
제공된 로그 인터페이스
net
클라이언트 및 서버측 데이터 검증 프레임워크 제공
예:
1: :
CollectionUtils.isEmpty(null): true
CollectionUtils.isEmpty(new ArrayList()): true
CollectionUtils.isEmpty({a,b}): false
2: :
CollectionUtils.isNotEmpty(null): false
CollectionUtils.isNotEmpty(new ArrayList()): false
CollectionUtils.isNotEmpty({a,b}): true
3:2 :
a: {1,2,3,3,4,5}
b: {3,4,4,5,6,7}
CollectionUtils.union(a, b)( ): {1,2,3,3,4,4,5,6,7}
CollectionUtils.intersection(a, b)( ): {3,4,5}
CollectionUtils.disjunction(a, b)( ): {1,2,3,4,6,7}
CollectionUtils.disjunction(b, a)( ): {1,2,3,4,6,7}
CollectionUtils.subtract(a, b)(A B ): {1,2,3}
CollectionUtils.subtract(b, a)(B A ): {4,6,7}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.