Frage

Nach ein paar Wochen auf diesem Forum zu lesen dachte ich, es war Zeit für mich meinen ersten Beitrag zu tun.

Ich bin derzeit rereading Code Complete. Ich denke, es ist 15 Jahre seit dem letzten Mal, und ich finde, dass ich noch keinen Code schreiben können ;-)

Wie auch immer, auf Seite 138 in Code Complete Sie das Coding Horror Beispiel finden. (Ich habe einen Teil des Codes entfernt)

class Emplyee {
public: 
 FullName GetName() const;
 Address GetAddress() const;
 PhoneNumber GetWorkPhone() const;
 ...

 bool IsZipCodeValid( Address address);
 ...

private: 
   ...
}

Was Steve denkt, ist schlecht ist, dass die Funktionen lose verwandt sind. Oder hat er schreibt: „Es gibt keine logische Verbindung zwischen den Mitarbeitern und Routinen, die Postleitzahlen überprüfen, Telefonnummern oder Arbeitsplatzbewertungs-“

Ok Ich bin vollkommen einverstanden mit ihm. so etwas wie das folgende Beispiel vielleicht besser ist.

class ZipCode
{
public:
 bool IsValid() const;
    ...
}

class Address {
public:
   ZipCode GetZipCode() const;
   ...
}

class Employee {
public: 
 Address GetAddress() const;
    ...
}

Bei der Prüfung, ob der Reißverschluss gültig ist, würden benötigen Sie so etwas wie dies zu tun.

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

Und das ist nicht gut in Bezug auf das Gesetz von Demeter .

Wenn Sie also zwei der drei Punkte zu entfernen, müssen Sie Delegation und ein paar Wrapper-Funktionen wie folgt verwenden.

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();

Aber dann wieder haben Sie Routinen, die keine logische Verbindung hat.

Ich persönlich denke, dass alle drei Beispiele in diesem Beitrag nicht schlecht sind. Ist es eine andere Art und Weise, dass ich nicht gedacht haben?

War es hilfreich?

Lösung

Es ist jetzt zahlen gegen Bezahlung später.

Sie können die Delegation und Wrapper-Funktionen vorne schreiben (jetzt zahlen) und dann weniger Arbeit haben später die Innereien von employee.IsZipCodeValid () zu ändern. Oder können Sie Tunnel durch IsZipCodeValid durch Schreiben

employee.GetAddress().GetZipCode().IsValid();
überall müssen Sie es im Code, aber später zahlen sollten Sie Ihre Klasse Design in einer Weise ändern sich entscheiden, die diesen Code bricht.

Sie erhalten Ihr Gift zu wählen. ;)

Andere Tipps

Sie fehlen die logische Verbindung:

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();

Da gibt es keine logische Verbindung zwischen der Employee-Klasse und Zip-Code-Validierung, können Sie die Zip-Code-Validierung in die Adressklasse setzen, wo es logisch gehört. Dann können Sie die Adresse der Klasse fragen, damit Sie die Postleitzahl überprüfen.

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

Dann sind Sie tun

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

Ich denke, das unter den Zwängen der logischen Verknüpfung und Gesetz von Demeter zufriedenstellend ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top