코드 완료 2ED, 구성 및 대표단
-
19-09-2019 - |
문제
이 포럼에서 몇 주 동안 읽은 후 나는 첫 번째 게시물을 할 시간이라고 생각했습니다.
현재 코드를 다시 읽고 있습니다. 마지막으로 15 년이 지난 후에도 여전히 코드를 쓸 수 없다는 것을 알았습니다 .-)
어쨌든 코드 완료의 138 페이지 에이 코딩 공포 예를 찾을 수 있습니다. (코드 중 일부를 제거했습니다)
class Emplyee {
public:
FullName GetName() const;
Address GetAddress() const;
PhoneNumber GetWorkPhone() const;
...
bool IsZipCodeValid( Address address);
...
private:
...
}
Steve가 나쁜 것은 기능이 느슨하게 관련되어 있다는 것입니다. 또는 그는 "우편 번호, 전화 번호 또는 직무 분류를 확인하는 직원과 루틴간에 논리적 인 연결이 없다"고 썼다.
좋아, 나는 그에게 전적으로 동의합니다. 아래의 예와 같은 것이 더 나을 것입니다.
class ZipCode
{
public:
bool IsValid() const;
...
}
class Address {
public:
ZipCode GetZipCode() const;
...
}
class Employee {
public:
Address GetAddress() const;
...
}
지퍼가 유효한지 확인할 때는 이와 같은 작업을 수행해야합니다.
employee.GetAddress().GetZipCode().IsValid();
그리고 그것은 그것에 대해서는 좋지 않습니다 데메테르의 법칙.
따라서 세 개의 점 중 2 개를 제거하려면 대표단과 이와 같은 몇 개의 래퍼 기능을 사용해야합니다.
class ZipCode
{
public:
bool IsValid();
}
class Address {
public:
ZipCode GetZipCode() const;
bool IsZipCodeValid() {return GetZipCode()->IsValid());
}
class Employee {
public:
FullName GetName() const;
Address GetAddress() const;
bool IsZipCodeValid() {return GetAddress()->IsZipCodeValid());
PhoneNumber GetWorkPhone() const;
}
employee.IsZipCodeValid();
그러나 다시 논리적 인 연결이없는 루틴이 있습니다.
나는 개인적 으로이 게시물의 세 가지 예가 모두 나쁘다고 생각합니다. 내가 생각하지 않은 다른 방법입니까?
해결책
그것은 지금 지불하는 것과 나중에 지불합니다.
대표단과 래퍼 기능을 앞쪽으로 작성한 다음 (지금 지불) 직원의 내부를 변경하는 작업이 줄어들 수 있습니다. 또는, 당신은 글을 쓰면 Iszipcodevalid로 터널을 통과 할 수 있습니다.
employee.GetAddress().GetZipCode().IsValid();코드에 필요한 모든 곳에서는이 코드를 중단하는 방식으로 클래스 디자인을 변경하기로 결정하면 나중에 지불해야합니다.
당신은 당신의 독을 선택합니다. ;)
다른 팁
논리적 연결이 누락되었습니다.
class ZipCode
{
public:
bool IsValid();
}
class Address {
public:
ZipCode GetZipCode() const;
bool IsAddressValid();
bool IsValid() {return GetZipCode()->IsValid() && IsAddressValid());
}
class Employee {
public:
FullName GetName() const;
Address GetAddress() const;
bool IsEmployeeValid();
bool IsValid() {return GetAddress()->IseValid() && IsEmployeeValid());
PhoneNumber GetWorkPhone() const;
}
employee.IsValid();
직원 클래스와 지퍼 코드 검증간에 논리적 인 연결이 없으므로 우편 번호 검증을보다 논리적으로 속하는 주소 클래스에 넣을 수 있습니다. 그런 다음 주소 클래스에 우편 번호를 검증하도록 요청할 수 있습니다.
class Address
{
public:
static IsZipValid(ZipCode zip) { return zip.isValid(); }
};
그럼 당신은합니다
Address::IsZipValid(employee.GetAddress().GetZipCode());
나는 이것이 논리적 연관성과 데메테르의 법칙에 대한 당신의 제약에 따라 만족 스럽다고 생각합니다.