2010-03-11 23 views
5

Birkaç hafta sonra bu forumda okumaya başladım, ilk mesajımı yapmanın tam zamanı olduğunu düşündüm.Kod 212, Kompozisyon ve yetkilendirme tamamlandı

Şu anda Code Complete'i okudum. Ben son kez bu yana 15 yıl olduğunu düşünüyorum ve hala kod yazabilirim buluyorum ;-)

Neyse, sayfa 138'de Kod tamamlandı, bu kodlama dehşet örneğini bulabilirsiniz. (Bazı kodları kaldırdım)

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

bool IsZipCodeValid(Address address); 
... 

private: 
    ... 
} 

Steve'in kötü olduğunu düşündüğü şey, işlevlerin gevşek bir şekilde bağlantılı olmasıdır. Ya da

Tamam ben tamamen ona katılıyorum "çalışanlar ve posta kodlarını, telefon numarası veya iş sınıflandırmaları kontrol rutinleri arasında hiçbir mantıksal bağ yok" yazıyor vardır. Belki de aşağıdaki örnek gibi bir şey daha iyidir.

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

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

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

Zip geçerli olup olmadığını denetlerken böyle bir şey yapmanız gerekir.

Ve bu Law of Demeter ile ilgili değil.

Üç noktadan ikisini çıkarmak isterseniz, bu şekilde temsilci ve birkaç sarıcı işlevini kullanmanız gerekir.

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

Ama sonra tekrar mantıksal bir bağlantıya sahip olmayan yordamlarınız var.

Şahsen bu yazının üç örneğinin de kötü olduğunu düşünüyorum. Düşünmediğim başka bir yolu var mı?

+0

Ben programcılar bir çok kodu tamamlandı sevdiğini biliyorum, ama dürüstçe ben yapmadım. Çok sıkıcı bir okumaydı. – JonH

+0

Bu, okuduğunuz zamana bağlı olarak değişir. Eğer bir junior geliştiricisiyseniz, iyi bir okumadır.Deneyimli bir geliştiriciyseniz, kitapta yazılanların sıra dışı bir şey olmaksızın mantıklı olduğunu düşünüyorum. –

+1

@JonH Katılıyorum - en iyi kitabı aslında birkaç kişinin okumuş olduğu "Hızlı Gelişim" dir - bu harika. –

cevap

1

Daha sonra ödeme vs şimdi ödemek var.

Sen heyeti ve sarıcı işlevleri ön (şimdi ödeme) ve ardından() sonradan employee.IsZipCodeValid bağırsaklar değişen daha az iş var yazabilirsiniz. Veya, can tünel kodda gerek, ama bu kodu kırar bir şekilde sınıf tasarımını değiştirmeye karar gerekir sonra öde her yerde

employee.GetAddress().GetZipCode().IsValid();
yazarak IsZipCodeValid kadar. Zehirinizi seçmeniz yeterlidir. ; Çalışan sınıfın ve posta kodu doğrulama arasında hiçbir mantıksal bağlantısı olmadığına göre)

+0

Bu muhtemelen en iyi cevaptır. Çünkü problem için herhangi bir zarif çözüm değildir. – Arlukin

7

Sen mantıksal bağlantısı eksik:

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

Yine de sonunda ZipCode :: IsValid() 'ye inmeniz gerekir. “Employee.IsValid()” diyorsunuz ve false döndürüyor. Tamam, çalışan neden geçerli değil? Yani "employee.GetAddress(). IsValid()' diyorsunuz ve false döndürüyor. Tamam, neden adres geçerli değil? Yani, “work.GetAddress(). GetZipCode(). IsValid()' diyorsunuz ve orijinal soruna geri döndünüz. – indiv

+0

Ayrıca, bir iletişim kutusunda veya web sayfasında çıktı almak için, ZipCode'da GetValue() öğesini çağırmak isteyebilirsiniz. Bu size aynı problemi verecektir. – Arlukin

+0

@indiv, eğer bu örneği yüz değerine getirecekseniz, o zaman evet, bu şekilde detaya girmeniz gerekecektir, ancak bunun yerine sizin için bunu yapan ve veri için hata verilerini/mesajlarını sunan bir yönteminiz olacaktır. giriş ekranı. Bu geçersiz durum, uygulamadaki kötü verilerin sonucuysa, cevabın, verileri modelinize enjekte etmeden önce temizlemeye bakmak olduğunu düşünüyorum. – Lazarus

0

, bunu daha mantıklı ait adres sınıfa Posta kodu doğrulama koyabilirim. Ardından, Adres sınıfının sizin için Zip kodunu doğrulamasını isteyebilirsiniz.

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

Sonra

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

bu mantıksal dernek ve Demeter Kanunun sizin kısıtlamalar altında tatmin edici olduğunu düşünüyorum

yapmak.

+0

Ama bununla gerçekten bir şey kazanıyor musunuz? Muhtemelen kişisel bir zevk meselesi, ama daha fazla noktanın okunması daha kolay olduğunu düşünüyorum. Adres :: IsZipValid (employee.GetAddress(). GetZipCode()); vs employee.GetAddress() GetZipCode(). IsZipValid(); – Arlukin

+0

@Arlukin: Hayır, bir şey kazandığına inanmıyorum. Ben sadece soruyu soru olarak yanıtlıyordum. Demeter benim için hiçbir yasa koymaz, bu yüzden onu work.GetAddress(). GetZipCode.IsZipValid() olarak uygulardım. Bu şekilde bana doğal geliyor. – indiv

+0

@Arlukin, bu kazanma ya da kaybetme ile ilgili değil, mantıklı bir model oluşturmakla ilgilidir. Günün sonunda, bir yol size göre daha doğalsa ve bir takımın parçası değilseniz (takım rehberliği alırsanız), o zaman sizin için anlamlı olan şeylerle gidin. Eminim bir odaya iki programcı alırsanız, belirli bir çözümü nasıl kodlayacağınıza dair altı fikir alırsınız;) – Lazarus

İlgili konular