5

このフォーラムを数週間読んだ後、最初の投稿をする時が来たと思いました。

現在コードコンプリートを読み直しています。前回から 15 年経ったと思いますが、まだコードを書くことができません ;-)

とにかく、Code Complete の 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;
    ...
}

zipが有効かどうかを確認するときは、次のようなことをする必要があります。

employee.GetAddress().GetZipCode().IsValid();

そして、それはデメテルの法則に関しては良くありません。

したがって、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 つの例はすべて悪いと思います。それは私が考えていなかった他の方法ですか?

4

3 に答える 3

7

論理接続がありません:

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();
于 2010-03-11T17:04:42.080 に答える
1

今すぐ支払うか、後で支払うかです。

前もって委譲関数とラッパー関数を記述し (今すぐ支払う)、後で employee.IsZipCodeValid() の内部を変更する作業を減らすことができます。または、次のように記述して IsZipCodeValid にトンネリングできます。

employee.GetAddress().GetZipCode().IsValid();
コード内のどこでも必要ですが、このコードを壊すような方法でクラスの設計を変更することにした場合は、後で支払う必要があります。

あなたはあなたの毒を選ぶことができます。;)

于 2010-03-11T17:08:19.147 に答える
0

Employee クラスと郵便番号の検証の間には論理的なつながりがないため、郵便番号の検証をより論理的に属する Address クラスに入れることができます。次に、Address クラスに郵便番号の検証を依頼できます。

class Address
{
    public:
        static IsZipValid(ZipCode zip) { return zip.isValid(); }
};

その後、あなたは

Address::IsZipValid(employee.GetAddress().GetZipCode());

論理的関連とデメテルの法則の制約の下では、これで十分だと思います。

于 2010-03-11T17:27:37.933 に答える