コードコンプリート2ED、組成と委任
-
19-09-2019 - |
質問
このフォーラムで読んで数週間後、私はそれは私が私の最初の投稿を行うための時間だと思いました。
私は現在、コードコンプリート再読しています。私はそれが最後の時間以来、15年だと思う、と私はまだ;-)コードを書くことができないことがわかります。
とにかくコードで138ページで、このコーディングホラーの例を見つけるあなたを完了します。 (私は、コードの一部を削除した)
class Emplyee {
public:
FullName GetName() const;
Address GetAddress() const;
PhoneNumber GetWorkPhone() const;
...
bool IsZipCodeValid( Address address);
...
private:
...
}
何スティーブは悪いと思うことは機能が緩く関連していることです。それとも彼は書いた「従業員や郵便番号、電話番号や職種をチェックするルーチンの間には論理的な接続はありません」
[OK]を私は完全に彼に同意します。たぶん、下記の例のようなものが良いです。
class ZipCode
{
public:
bool IsValid() const;
...
}
class Address {
public:
ZipCode GetZipCode() const;
...
}
class Employee {
public:
Address GetAddress() const;
...
}
郵便番号が有効であるかどうかをチェックする場合は、あなたはこのような何かをする必要があります。
employee.GetAddress().GetZipCode().IsValid();
そして、それは、のhref="http://en.wikipedia.org/wiki/Law_of_Demeter" rel="nofollow noreferrer">法に係る良いではありません。
あなたは3つのドットのうちの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();
しかし、その後、再び、あなたは何の論理的な接続を持っていないルーチンを持っています。
私は個人的には、この記事ではすべての3つの例が悪いと思います。それは私が考えていない他のいくつかの方法は何ですか?
解決
これは、後に有料対今すぐ支払うのです。
あなたは、フロントまで(今支払う)、次に()後で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();
Employeeクラスと郵便番号の検証の間には論理的な接続はありませんので、あなたはそれがより論理的に属しているアドレスクラスに郵便番号の検証を置くことができます。そして、あなたはあなたのための郵便番号を検証するためにAddressクラスを求めることができます。
class Address
{
public:
static IsZipValid(ZipCode zip) { return zip.isValid(); }
};
そして、あなたが行う。
Address::IsZipValid(employee.GetAddress().GetZipCode());
私は、これは論理的な関連性とデメテルの法則のあなたの制約の下で満足だと思います。