'좋은 코드/나쁜 코드 학습 디자인 입문'읽고 신경 쓴 일 노트
개시하다
화제가 된'좋은 코드/나쁜 코드로 학습한 디자인 입문-지속적인 성장을 유지하기 쉬운 코드의 쓰기'출판사 페이지를 읽었다.
총체적으로 말하자면, 대부분의 경우 '응, 그래' 에 동의할 수 있다.
물론 처음 보는 생각과 생각, 기교도 있다.
한편, 신경 쓰이는 일과 조금 걸리는 일도 있으니 미리 적어두자.
필기일 뿐이라고 결론이 나지 않는다.
p.55: HitPoint.isZero
HitPoint
류는 isZero
방법이 있다."적중점이 0이면 진짜"라는 구체적인 실시는 다음과 같다.
목록 4.25
private static final int MIN = 0;
목록 4.25 boolean isZero() {
return amount == MIN;
}
나는 왜 '0' 을 나타내는 필드의 이름이 ZERO
이 아니라 MIN
인지 매우 궁금하다.값이 0이 아니어도 상관없지만 규격상'안전타점이 0'이라고 표시하면
MIN
은 ZERO
이 좋다.'규격상 인기점은 제로,
amount
장의 값은 MIN
반과 같다'HitPoint
반의 디자인은 isZero
방법 이외의 코드에서는 볼 수 없다.p.90: 초기return
나도 초기 리턴의 목적과 장점을 이해할 생각이다.
그런데 리스트 6.9의 코드가 좀 끊겼어요.
목록 6.9
if (hitPointRate == 0) return HealthCondition.dead;
if (hitPointRate < 0.3) return HealthCondition.danger;
if (hitPointRate < 0.5) return HealthCondition.caution;
return HealthCondition.fine;
변경 전 코드(리스트 6.7 또는 리스트 6.8) 중else
가 사라지면 조건이 보기 어려워진다.예를 들어 세 번째 줄
if (hitPointRate < 0.5) ...
.생명상태는'주의(caution)'란
hitPointRate
가 0.30.5 범위에 있는 경우를 뜻하지만'0.3이상'은 앞줄을 보지 않으면 모른다.또 앞으로'위험'과'주의(caution)'사이에 또 하나의 생명상태가 추가되는 상황에서 그것을 판단하는if문은 반드시 2행과 3행 사이에 틀리지 않게 추가되어야 한다.
else
가 사라진 후 편의가 개선되었지만 코드를 읽을 때else
와 같은 선행if문이 있는 조건도 보이지 않는다. 그러면 else
한 쪽과 앞쪽이 연결되는 것이 더욱 명확하고 이해하기 쉽지 않겠는가. 이것이 바로 이런 상황을 일으키는 원인이다.글쎄, 내가 쓰기에 익숙하지 않고 읽기에 익숙하지 않은 이유도 있을 거야.
목록 6.4의 초기 리턴과 목록 3.4의 보호 섹션은 전혀 이의가 없다.
이세계의 컬렉션
나는 수치의 대상을 이세계로 설정하는 생각도 알고 그 장점도 이해하려고 했다.
다만, 지금까지 그 소장품들까지 음소거판으로 바꿔야 하는 것은 익숙하지 않아 좀 놀랐다.
원본(Java Edition)
우선 전제다.
Party
종류Member
대상의 소장.목록 7.11
class Party {
private final List<Member> members;
Party() {
members = new ArrayList<Member>();
}
}
그리고 Party
류 실례에 Member
대상add
을 추가한다.이때
Party
류가 정음편이라는 것을 유지하기 위해add
방법은 새로운Party
류의 실례를 생성하고 되돌아오고 있다.목록 7.13
class Party {
// 中略
Party add(final Member newMember) {
List<Member> adding = new ArrayList<>(members);
adding.add(newMember);
return new Party(adding);
}
또한 다음 구조기가 추가되었습니다.목록 7.14
private Party(List<Member> members) {
this.members = members;
}
C++ 버전
이 글을 읽고 생각난 건'C++면 어떻게 이루어질까'였어요.
C++의 경우 대상은 인용된 의미뿐만 아니라 값의 의미로도 처리할 수 있다.
도대체
Party
대상이 가지고 있는 Member
대상의 디자인이 적합한지 아직 잘 모르겠어요. 일단 이렇게 정할게요.목록 7.11과 같은
Party
클래스를 C++로 써 보면 이렇게 될까요?std::vector
유형의 데이터 구성원을const로 설정하는 데 익숙하지 않아 신선합니다.class Party {
public:
Party() = default;
private:
const std::vector<Member> members_;
};
다음에 우리는 std::vector<Member>
유형의 수용 가능한 대상의 구조기와 add
구성원 함수를 추가하려고 시도할 것이다.class Party {
public:
Party() = default;
Party add(const Member &newMember) {
std::vector<Member> adding{std::move(members_)};
adding.push_back(newMember);
return Party{std::move(adding)};
}
private:
const std::vector<Member> members_;
explicit Party(std::vector<Member> &&members)
: members_{std::move(members)} {
}
};
완료.원래의 자바 버전과 달리
add
구성원 함수에서 Member
유형의 대상이 복제되었는데 이것은 부득이한 것이다.rvalue reference를 매개 변수로 하는 구성원 함수
add(Member &&member)
를 불러오면 사용할 쪽을 선택할 수 있습니다.그럼 이
Party
급을 사용하는 쪽의 인코딩은 이렇습니다. auto newParty = currentParty.add(newMember);
의 문제는 add
구성원 함수에서 자신의 members_
데이터 구성원을 이동한 것이다.멤버 추가 후 추가 전 대상
currentParty
도 방문할 수 있어 위험하다[1].이를 막기 위해 이동하지 않고 복제할 수 있지만, 새로운
Member
대상을 추가할 때마다 기존의 Member
대상은 모두 복제돼 실행 시간이나 메모리 사용량에 상관없이 받아들여지기 어렵다.다만,
add
라는 구성원 함수에서 이동되는 것은 놀라운 최소 원칙에 어긋나 좋지 않다.문장 첫머리에 방치된 이 과제의 해결은 분야를 잘 분석하고 모델링한 뒤다.
도대체
Party
대상이 가지고 있는 Member
대상의 디자인이 적합한지 아직 잘 모르겠어요. 일단 이렇게 정할게요.이 상황에서 나 자신이라면 지침이 아닐까 싶어요.
저자 미노 드라이버() 씨가 Rust로 다시 쓴다고 해서 조금 신경이 쓰인다.
p.139: Member.id
id
나는 필드가 원시 유형인 것을 매우 의식한다int
.제3장(학급설계)의 방침에 따르면 이것도 전용 학급이어야 한다고 생각합니다.
나는 이 책을 읽기 전부터 원시형(C++에서fundamental types)을 많이 쓰는 스타일에 위화감을 느꼈고, 주변에서도 "인터페이스에
bool
형을 제외하고fundamental types를 사용하지 말아야 한다"고 주장했다.또 "
bool
형 이외"라는 점은 타협의 결과였지만, 아래 기사를 읽으면서 생각이 바뀌었다.p.295: isDisabled
Customer
와 Comic
등류isEnabled
방법이 있다.보호절로 '비enabled' 인자를 제거할 때의 조건식은
!xxx.isEnabled()
이며, 그 중 읽기 어려운 부분이 약간 있습니다.따라서 논리적 부정
!
을 사용하지 않고도 추가isDisabled
방법을 판단할 수 있는 아이디어다.그렇구나, 그렇게 생각하지만 부정적인 의미를 갖게 하는 방법은 본래 이해하기 어려워질 수 있다.
isDisabled
직관적으로 이해할 수는 있지만 무엇이 좋고 무엇이 안 되는지에 대한 객관적 기준을 정하기 어려우니 이런 구분이 고민이라면 일률적으로 금지한다.그리고
!xxx.isDisabled()
라고 적힌 프로그래머가 나타나면 싫어할 거야...끝말
서문에도 썼지만, 이 책에서 저자가 주장하는 내용 대부분은 동의할 만한 이유를 담았다.
한두 개만 준다면 다른 사람들도 할 수 있겠지만 책에서 정리한 것이라 가치가 있다고 생각해요.
이런 상황에서 그런 경향이 있다'등'악마'발생과 관련된 조건과 환경도 언급돼 저자의 다년간의 디자인 개선으로 쌓은 노하우를 체감하게 한다.
먼저 흔히 볼 수 있는'나쁜 코드'를 선보여 독자가 문제점을 이해하게 한 뒤 최종적으로'좋은 코드'로 개선하는 절차는 이해하기 쉽다는 느낌을 준다.
행사가 우선이고 디자인의 품질과 보수성(변경 용이성) 등 사려 깊지 못한 현장도 있어 황금연휴가 끝나면 일자리를 넓히려 한다.
또 제16장(설계의 개발과정을 방해하는 싸움)은 지금 제 위치와 역할에 가장 적합한 내용이다.
참고로 실천하게 해주고 싶습니다.
나는 이 보도 노트 자체가 16.4.3(경의와 예의)의 내용을 따르는지 좀 걱정된다.
각주
std::vector
클래스 템플릿은 UB가 될 수 없습니다.↩︎ Reference
이 문제에 관하여('좋은 코드/나쁜 코드 학습 디자인 입문'읽고 신경 쓴 일 노트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mafafa/articles/d781c2dfdfc3a8720270텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)