Veri Odaklı Arabirimlere Programlama


9

Kod tabanımızın aşağıdaki tarzda yazılmış bir kısmı vardır:

// IScheduledTask.cs
public interface IScheduledTask
{
    string TaskName { get; set; }
    int TaskPriority { get; set; }
    List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein
}

// ScheduledTaskImpl.cs
public class ScheduledTaskImpl : IScheduledTask
{
    public string TaskName { get; set; }
    public int TaskPriority { get; set; }
    public List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein, 
    // perhaps a constructor or two for convenience.
}

Yani, her biri otomatik özelliklerle uygulayan tek bir karşılık gelen uygulama ile davranışsız bir dizi özelliği belirten çok sayıda arabirim vardır. Kod oldukça kıdemli biri tarafından yazılmıştır (kendimden çok daha fazla) ve arayüzlerin bu kullanımından makul prosedür kodu dışındadır. Başka kimsenin bu stille karşılaşıp karşılaşmadığını / kullanmış olup olmadığını ve sadece arayüzler olmadan her yerde beton DTO'ları kullanmanın herhangi bir avantajı olup olmadığını merak ediyordum.


1
Bunu yapmamın bir nedeni COM uyumluluğu içindir, ancak bu sizin nedeniniz gibi görünmüyor.
Mike

@Mike İlginç, hiç COM kullanmadım ve burada kullanılmıyor. Kodun bu bölümünün yazara COM veya herhangi bir şey kullanmayı planlayıp planlamadığını soracağım.
Walpen

Tahminimce, bu özelliklerden en az birini nispeten yakın gelecekte otomatik olmayan bir hale getirmeyi umuyor ve başlangıçta bu ortak plakayı yazmak, daha sonra uğraşmak için biraz zaman kazanmak için kazandığı bir alışkanlık. bir C # adam değil bu yüzden söyleyebileceğim tek şey bu.
Ixrec

6
IMHO, kodun uygulama değil arayüzlere aşırı takıntısı ve yanlış uygulanmasıdır . Anahtar bir anlatım tek uygulama . Arayüzlerin noktası polimorfizmdir, ancak sadece özellik sınıfı, bir anlamda sadece farklı değerlere sahip olarak polimorfiktir. Davranış - yöntemlerle bile - tek bir uygulama verildiği anlamına gelmez. Bu saçmalık, kod tabanımızın her yerinde ve en iyi şekilde bakımı engelliyor. Neden, ne ve nerede olduğunu sorarak çok fazla zaman harcıyorum. Neden yaptılar, hangi tasarımı görmüyorum ve diğer uygulamalar nerede?
radarbob

2
Önceki yorumların çoğu erken soyutlama tek bir uygulama "kod kokusu" gidin; bununla birlikte burada da bir anemik etki alanı modeli "kod kokusu" vardır, bakınız: martinfowler.com/bliki/AnemicDomainModel.html
Erik Eidt

Yanıtlar:


5

İşte iki sentim:

  • Bir DTO'nun asla en azından biraz davranış göstermeyeceğinden emin değiliz. Benim için gelecekte davranışları olan veya olmayan nesneler var.
  • Pek çok taban-uygulama sınıfları sahip olası bir nedeni tasarım eksikliği olduğunu görmek için başarısız örneğin ScheduledTask, ScheduledJob, ScheduledEvent, ScheduledInspection, vb tek ayrılmış olmalıdır Schedulableherhangi implementor zamanlanabilen yapma arayüzü.
  • İlk olarak arayüzler oluşturmak çok iyi bir uygulamadır, ihtiyacınız olan şey hakkında size fikir verir. Birçok arabirim hiç bir uygulamaya sahip olmadan başlar. Sonra birisi bir uygulama yazar ve buna sahiptir. İkinci noktada bahsettiğim şeyden kaçınırsanız, tek bir uygulamaya sahip olma durumu geçicidir. Bazı arayüzlerin hiçbir zaman üçüncü bir uygulamanın ikinci saniyesine sahip olmayacağını nereden biliyorsunuz?
  • İyi düşünülmüş bir arayüz için seçtiğimiz adın gelecekte değişme eğilimi vardır, bu nedenle bu arayüze bağımlılıklar etkilenmez. Öte yandan, somut bir sınıf, uygulanma biçiminde önemli bir şey değiştiğinde yeniden adlandırılmaya eğilimlidir, örneğin, adlandırılmış bir somut sınıf , önemli bir revizyon yapıldığından TaxSheetdeğişebilir SessionAwareTaxSheet, ancak arayüz ITaxSheetmuhtemelen kolayca yeniden adlandırılmayacaktır.

Sonuç olarak:

  • İyi tasarım uygulamaları DTO'lar için de geçerlidir.
  • DTO'lar yolda biraz davranış ekleyebilir.
  • Her arayüz sadece bir uygulamaya sahip olarak başlar.
  • Öte yandan, çok fazla tek arayüzlü bir sınıf kombinasyonunuz varsa, dikkat edilmesi gereken bir tasarım eksikliği olabilir. Ön konuşmanız haklı olabilir .

4
Cevabınızı onayladım, ancak ikinci merminiz, tüm sınıfların otomatik olarak karşılık gelen bir arayüze, asla kabul etmediğim bir konuma sahip olması gerektiğini ima ediyor. İkinci bir uygulamaya sahip olma olasılığınız üzerine arabirimler yazmak yalnızca arabirim çoğalmasına ve YAGNI'ya neden olur.
Robert Harvey

1

Arabirim kullanan DTO'larda gördüğüm özel bir sorun, buna izin vermesidir:

public interface ISomeDTO { string SomeProperty { get; set; }}

public class SomeDTO : ISomeDTO
{
    public string SomeProperty { get; set; }
    string ISomeDTO.SomeProperty { get { /* different behavior */ } set { SomeProperty = value; } }
}

Bu kalıbın bazı kritik davranışları uygulamak için hızlı, kirli bir saldırı olarak uygulandığını gördüm. Bu, çok kafa karıştırıcı davranışlara sahip olabilecek koda yol açar:

SomeDTO a = GetSomeDTO();
ISomeDTO ia = a;
Assert.IsTrue(a.SomeProperty == ia.SomeProperty); // assert fails!

Bu çözülmeyi veya yeniden düzenlemeyi denemek için bakımı ve kafa karıştırıcı zordur. IMO, DTO'lara davranış eklemek tek sorumluluk ilkesini ihlal ediyor. Bir DTO'nun amacı, bir kalıcılık çerçevesi tarafından kalıcı ve doldurulabilecek bir formattaki verileri temsil etmektir.

DTO'lar alan modeli değildir. DTO'lar anemikse endişelenmemeliyiz. Martin Fowler'in anemik alan modeli hakkındaki tartışmasını alıntılamak için :

Etki alanı nesnelerine davranış koymanın, etki alanı mantığını kalıcılık ve sunum sorumlulukları gibi şeylerden ayırmak için katman kullanmanın katı yaklaşımıyla çelişmemesi gerektiğini de vurgulamak gerekir .

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.