Bir nesne sahibinin çok şey biliyorsa bir kod kokusu mu?


9

Delphi 2007 uygulamamızda aşağıdaki yapıların çoğunu kullanıyoruz

FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData));

FindOwnerClass belirli bir sınıfı bulmak için geçerli bileşenin Sahip hiyerarşisini yukarı doğru hareket ettirir (TdmBasicData örneğinde). Sonuçta elde edilen nesne FdmBasic Alan değişkeninde saklanır. Bunu öncelikle veri modüllerini iletmek için kullanıyoruz.

Örnek: Bir rapor oluştururken, elde edilen veriler sıkıştırılır ve bir veri modülü TdmReportBaseData üzerinden erişilen bir tablonun Blob alanında depolanır. Uygulamamızın ayrı bir modülünde, ReportBuilder kullanarak rapordaki verileri Disk belleği biçiminde gösterme işlevi vardır. Bu modülün ana kodu (TdmRBReport), sıkıştırılmış blob verilerini Rapor Oluşturucusu çalışma zamanı rapor tasarımcısında kullanılabilen farklı tablolara dönüştürmek için bir TRBTempdatabase sınıfı kullanır. TdmRBReport, raporla ilgili her türlü veri (rapor türü, rapor hesaplama ayarları vb.) İçin TdmReportBaseData öğesine erişebilir. TRBTempDatabase, TdmRBReport içinde oluşturulmuştur, ancak TdmReportBasedata'ya erişimi olmalıdır. Yani bu şimdi yukarıdaki yapı kullanılarak yapılır:

constructor TRBTempDatabase.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);

  FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData;
end;{- .Create }

Benim duygu bu TRBTempDatabase sahibinin çok şey biliyor anlamına gelir ve bu bir tür kod kokusu veya Anti-desen olup olmadığını merak ediyordum.

Bunun hakkında görüşleriniz neler? Bu bir kod kokusu mu? Eğer öyleyse, daha iyi bir yol nedir?


1
Başka bir sınıf hakkında o kadar çok şey bilseydi, bunu yapmanın daha kolay bir yolu olurdu.
Loren Pechtel

Yanıtlar:


13

Bu tür, ilk olarak Martin Fowler tarafından tarif edilen (ortak bir anti-desen olarak tanımlanmıştır) bir Servis Bulucu Kalıbı gibi görünüyor.

Yapı tabanlı Bağımlılık Enjeksiyonu, ihtiyaç parametrelerinin görünürlüğünü teşvik ettiği ve daha basit Birim Testini desteklediği için Servis Bulucuya göre tercih edilir.

Bir Servis Bulucu kullanmayla ilgili sorun, belirli bir Servis Bulucu uygulamasına bağımlı olmanız değildir (bu da bir sorun olabilir), ancak bunun iyi niyetli bir anti-desen olmasıdır. API'nızın tüketicilerine korkunç bir geliştirici deneyimi yaşatacak ve yaptığınız her değişikliğin sonuçlarını kavramak için önemli miktarda beyin gücü kullanmanız gerekeceğinden, bir bakım geliştiricisi olarak hayatınızı daha da kötüleştirecektir.

Derleyici, Yapıcı Enjeksiyonu kullanıldığında hem tüketicilere hem de üreticilere çok fazla yardım sunabilir, ancak Servis Yardımı'na dayanan API'ler için bu yardımların hiçbiri mevcut değildir.

Ayrıca en önemlisi Demeter Yasasını da ihlal ediyor

Demeter Yasası (LoD) veya En Az Bilgi Prensibi, özellikle nesne yönelimli programlar olmak üzere yazılım geliştirmek için bir tasarım kılavuzudur. Genel haliyle, LoD belirli bir gevşek bağlantı örneğidir.

Demeter işlevleri için bir nesnenin O yönteminin M sadece aşağıdaki nesne türlerinin yöntemlerini çağırmasını gerektirir:

  1. O'nun kendisi
  2. M parametreleri
  3. M içinde yaratılan / örneklenen nesneler
  4. O'nun doğrudan bileşen nesneleri
  5. M kapsamında O tarafından erişilebilen küresel bir değişken

Özellikle, bir nesne, başka bir yöntemle döndürülen bir üye nesnenin yöntemlerini çağırmaktan kaçınmalıdır. Alan tanımlayıcısı olarak nokta kullanan birçok modern nesne yönelimli dilde, yasa basitçe "sadece bir nokta kullan" olarak ifade edilebilir. Yani, abMethod () kodu, a.Method () öğesinin yapmadığı yasayı ihlal eder. Basit bir örnek olarak, bir köpek yürümek istediğinde, köpeğin bacaklarına doğrudan yürümesini emretmek aptalca olurdu; bunun yerine kişi köpeğe kumanda eder ve kendi bacaklarına bakmasına izin verir.

Daha İyi Yol

Etkili bir şekilde daha iyi bir yol, sınıf içindeki hizmet bulucu çağrısını kaldırmak ve yapıcısının içinde bir parametre olarak doğru sahibi iletmektir. Bu, bir sahip araması yapan ve daha sonra bunu sınıf yapıcısına ileten bir hizmet sınıfınız olduğu anlamına gelse bile

constructor TRBTempDatabase.Create(aOwner: TComponent, ownerClass: IComponent);
begin
  inherited Create(aOwner);

  FdmReportBaseData := TdmRBReport(ownerClass).dmReportBaseData;
end;{- .Create }

3
Harika cevap ve bu harika benzetmeyi kimin geldiğine sahne:As a simple example, when one wants to walk a dog, it would be folly to command the dog's legs to walk directly; instead one commands the dog and lets it take care of its own legs.
Andy Hunt

3

Çocuk nesnelerin ebeveyn hakkında çok fazla bilgi sahibi olmasının zorluklarından biri, çok sıkı bir şekilde birleşebilen (ve çoğu zaman yapabilen) desenleri uygulamanızdır, bu da büyük bağımlılık baş ağrıları oluşturur ve daha sonra güvenli bir şekilde değiştirilmesi ve bakımı çok zor hale gelir. daha sonra.

İki sınıfınızın ne kadar derinlemesine bağlı olduğuna bağlı olarak, Fowler'in Özellik Kıskançlığı veya Uygunsuz Samimiyet kodu kokularının açıklaması açık gibi görünüyor.

Verileri içeren bir sınıfı yüklemeniz veya okumanız gerekiyor gibi görünüyor, bu durumda çocuk ve ebeveyn zinciri arasındaki bağımlılığı kırmak için bir dizi alternatif desen kullanabilirsiniz ve bu, erişim görevini devretmeniz gerektiği gibi geliyor veri erişimci sınıfını her şeyi kendisi yapmaktan sorumlu kılmak yerine veri sınıfınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.