Bağımlılık enjeksiyonu ile UI'de çılgın bir miktarda arayüzden nasıl kaçınılır?


8

Sorun
Son zamanlarda Singletons kötü ve bağımlılık enjeksiyon ("arayüzler kullanarak" olarak anlıyorum) nasıl daha iyi hakkında çok şey okudum. Bunun bir kısmını geri aramalar / arayüzler / DI ile uyguladığımda ve arayüz ayırma prensibine bağlı kaldığımda, oldukça karışıklık yaşadım.

Bir UI ebeveyninin temelde tüm çocuklarının birleşimlerinin bağımlılıkları, bu nedenle bir UI öğesi hiyerarşisi ne kadar yüksek olursa, kurucusu o kadar şişirilmişti.

UI hiyerarşisinin en üstünde, geçerli seçim hakkındaki bilgileri ve değişiklikleri yansıtması gereken bir 3B modele referans tutan bir Uygulama sınıfı vardı. Uygulama sınıfı 8 arayüz uyguluyordu ve bu gelecek ürünlerin (/ arayüzlerin) sadece beşte biri kadardı!

Şu anda mevcut seçimi ve kendilerini güncellemek için bir işlevi olan UI öğeleri tutan bir singleton ile çalışıyorum. Bu işlev, kullanıcı arabirimi ağacını ve kullanıcı arabirimi öğelerini kandırır ve ardından geçerli seçim single'ına gerektiği gibi erişir. Kod bana bu şekilde daha temiz görünüyor.

Soru
Bu proje için bir singleton belki uygun mu?
Değilse, DI'yi benim düşüncemde ve / veya uygulamamda çok hantal yapan temel bir kusur var mı?

Proje hakkında ek bilgi
Tür: çan ve ıslık ile daireler için alışveriş sepeti
Boyutu: kod ve UI için 2 adam-ay
Bakım: Çalışan güncelleme yok, ama belki "sürüm 2.0" sonra
Çevre: Bir Varlık kullanan Birlik C # kullanma Bileşen sistemi

Neredeyse tüm durumlarda, kullanıcı etkileşimi birkaç eylemi tetikler. Örneğin, kullanıcı bir öğe seçtiğinde

  • bu öğeyi ve açıklamasını gösteren kullanıcı arayüzü bölümünün güncellenmesi gerekir. Bunun için, fiyatı hesaplamak için bir 3d modelden biraz bilgi alması gerekir.
  • Kullanıcı arayüzüne ek olarak, toplam toplam fiyatın güncellenmesi gerekir
  • değişiklikleri burada görüntülemek için 3B modeldeki bir sınıftaki karşılık gelen bir işlevin çağrılması gerekir

DI sadece arayüzleri kullanmakla ilgili değil, özellikle birim test alanında yararlı olan betonları değiştirme yeteneğidir ...
Robbie Dee

1
Ayrıca, henüz bir singletonun tercih edilen çözüm olduğu bir sorun görmedim. İnsanların her zaman belirttikleri kanonik örnek bir günlük yazarıdır, ancak burada bile bir dizi farklı günlüğe (hata, hata ayıklama vb.) Yazmak isteyebilirsiniz.
Robbie Dee

@RobbieDee Evet, DI daha fazlası hakkında, ancak bir arayüz kullanmanın DI olmadığı bir durum göremiyorum. Ve eğer bir singleton tercih edilen çözüm değilse - ki ben de varsayıyorum - o zaman tercih edilen çözüm neden bu kadar dağınık? Bu benim asıl sorum, ama bazen genel kural geçerli olmadığı için açık tutmak istedim.
R. Schmitz

Arabirim-beton düzenlemesi aynı zamanda alaycı çerçevelerin bir özelliğidir. Onlar da birkaç on yıldır OO dillerinde ...
Robbie Dee

Ne demek istediğini anlamıyorum.
R. Schmitz

Yanıtlar:


4

Bence soru bir çözüm değil bir belirti.

Son zamanlarda Singletons kötü ve bağımlılık enjeksiyon ("arayüzler kullanarak" olarak anlıyorum) nasıl daha iyi hakkında çok şey okudum. Bunun bir kısmını geri aramalar / arayüzler / DI ile uyguladığımda ve arayüz ayırma prensibine bağlı kaldığımda, oldukça karışıklık yaşadım.

Sorun arayan bir çözüm; bu ve onu yanlış anlamak muhtemelen tasarımınızı bozuyor. DI vs Singleton, farklı kavramlar hakkında bu SO sorusunu okudun mu? Ben sadece bir singleton sarma olarak istemci okudum bir singleton ile uğraşmak zorunda değilsiniz. It.is.just.good.old.encapsulation. Bence bu nokta.


bir UI öğesi hiyerarşisi ne kadar yüksek olursa, kurucusu o kadar şişirilmiş olur.

Önce daha küçük bitleri oluşturun, sonra ait oldukları şeyin yapıcısına geçirin ve daha büyük olanı bir sonraki büyük şeyin yapıcısına geçirin ...

Karmaşık inşaat sorunlarınız varsa, fabrika veya üretici desenini kullanın. Alt satırda, karmaşık sınıfların diğer sınıfları temiz, temiz, anlaşılabilir vb.


Uygulama sınıfı 8 arayüz uyguluyordu ve bu gelecek ürünlerin (/ arayüzlerin) sadece beşte biri kadardı!

Bu, genişleme yeteneğinin yokluğu gibi görünüyor. Çekirdek tasarım eksik ve her şey üstten sıkışıyor. Aşağıdan yukarıya inşaat, kompozisyon ve kalıtım daha fazla olmalı.

Tasarımınızın "çok ağır" olup olmadığını merak ediyorum. Görünüşe göre, bir sınıfı olabileceği her şey ya da herhangi bir şey yapmaya çalışıyoruz. Endişelerin ayrılmasını gerçekten merak etmem için bir iş alanı sınıfı değil, bir UI sınıfı olması.

Tasarımınızı en baştan tekrar ziyaret edin ve daha karmaşık veya farklı kategori üretimleri yapmak için geliştirilebilecek sağlam, temel bir ürün soyutlaması olduğundan emin olun. O zaman bu şeylerin özel koleksiyonlarına sahip olsanız iyi olur, böylece "koleksiyon seviyesi" işlevselliğini koyabileceğiniz bir yer vardır - bahsettiğiniz "3. model" gibi.


... değişiklikleri yansıtması gereken 3d model.

Bunların çoğu özel koleksiyon sınıflarına uygun olabilir. Ayrıca derinlik ve karmaşıklık nedeniyle kendi başına bağımsız sınıf yapısı da olabilir. Bu iki şey birbirini dışlamaz.

Ziyaretçi kalıbı hakkında bilgi edinin. Tüm işlevsellik parçalarının soyut olarak farklı tiplere bağlanması fikri.


Tasarım ve DI

Yapacağınız tüm bağımlılık enjeksiyonunun% 90'ı yapıcı parametre geçişidir. Yani kitabı yazan quy diyor . Sınıflarınızı iyi tasarlayın ve bir DI kapsayıcısı kullanmaya ihtiyaç duyma konusunda bazı belirsiz kavramlarla bu düşünce sürecini kirletmekten kaçının. İhtiyacınız olursa, tasarımınız size söyleyecektir.


Apartman alışverişi modelleme odaklanın.

Tasarım için Jessica Simpson yaklaşımından kaçının : "Bunun ne anlama geldiğini tam olarak bilmiyorum, ama istiyorum."

Aşağıdakiler yanlış:

  • Arayüz kullanmam gerekiyor
  • Bir singleton kullanmamam gerekiyor
  • DI'ye ihtiyacım var (ne olursa olsun)
  • Kompozisyon kullanmam gerekiyor, kalıtım değil
  • Mirastan kaçınmam gerekiyor
  • Kalıpları kullanmam lazım

Kullandığım tüm tekillerden kurtulmaya çalıştım ve söylediğin bazı şeyler az çok otomatik olarak gerçekleşti. Gerisi de çok mantıklı ve ben de senin tavsiyeni alıp ziyaretçi kalıbı vb. Hakkında okuyacağım.
R. Schmitz

Sadece bir nokta ve burada bir yardım vampir olmaya çalışıyorum değilim, ama öyleydi tür sen gerçekten gerekiyordu olmadığını edilebilir görülüyor genel uzlaşma (ve geçerli nedenlere dayanmaktadır): Orijinal sorunun parçası bir singleton kullanın. "'Tekliton kullanmamam gerekiyor" yazıyorsunuz "yanlış" - hangi durumda bir tane kullanmak uygun olur?
R. Schmitz

Söylediğim tek şey "duruma bağlı". Çoğunlukla tam anlamıyla alınan maxımları görüyorum.
radarbob

3

"Sınıf heirarchy" biraz kırmızı bayraktır. Varsayımsal: 5 widget içeren bir web sayfası. Sayfa, widget'ların hiçbirinin atası değil. Bu widget'lara bir referans içerebilir. Ama bu bir ata değil. Sınıf heirarchy yerine kompozisyon kullanmayı düşünün. 5 pencere öğesinin her biri, diğer pencere öğelerine veya üst sayfaya başvurmadan kendi başına oluşturulabilir. Üst sayfa daha sonra temel bir sayfa oluşturmak ve kendisine aktarılan widget nesnelerini (Koleksiyon) düzenlemek için yeterli bilgi ile oluşturulur. Sayfa, yerleşimden vb. Sorumludur, ancak widget'ların oluşturulması ve mantığından sorumlu değildir.

Kompozisyon kullandıktan sonra, DI en iyi arkadaşınızdır. DI, DI'de tanımladığınız sürüm veya widget türü için her widget'ı değiştirmenize izin verir. Widget'ların yapımı DI'de yakalanır ve üst sayfadan ayrıdır. Belki de Koleksiyonun bileşimi DI'nizde tanımlanabilir. Üst sayfa, olması gerektiği gibi iletilen widget'lara göre düzen gerçekleştirir. Üst sayfa yapıcısında değişiklik yapılması gerekmez. Üst sayfa, yalnızca widget'ların düzenini gerçekleştirmek ve tanımlanan arayüzlere dayalı olarak widget'a / widget'tan bilgi aktarmak için mantığa ihtiyaç duyar.

Dinleyicileri kompozisyon zincirinde yukarı ve aşağı geçirmek yerine, ihtiyaç duyan widget'lara bir dizi dinleyici enjekte edin. Koleksiyona yayınlayabilmeleri için koleksiyonu yayıncıya enjekte edin. Koleksiyonu koleksiyona ekleyebilmeleri için koleksiyonu dinleyicilere enjekte edin. Koleksiyon, kompozisyon zincirindeki tüm nesneleri keser.


Maalesef, "sınıf hiyerarşisi" burada yanlış bir ifadeydi; aslında sınıf hiyerarşisi değil, UI hiyerarşisi idi. 'Widget'lar' uygulama sınıfının alt sınıfları değildir, ancak 'sayfa' kullanıcı arayüzü güncellemelerini yayınlamak için bunlara referanslar içerir. Bu yapı ile çok test edilebilirdi, ancak özellikle inşaatçılarda çok fazla yük vardı, sadece (UI) çocukları için çok fazla dinleyici geçti.
R. Schmitz

@ R.Schmitz: Genel gider önemli miydi? Kullanıcı arayüzü yavaş mıydı ve tanımladığınız tasarım suçlandı mı?
Robert Harvey

@ R.Schmitz "Çok fazla dinleyiciyi iletme" konusunu açıklayabilir misiniz? Belki C # ile DI ile olan deneyimim düşük, ama bir şey bana (en azından kurucuda) uygun tasarımla gerekli olmayacağını söylüyor.
Katana314

@RobertHarvey Performans kaybı yok, sadece okunabilirlikle ilgili.
R. Schmitz

@ Katana314 Örneğin, bir öğe eklendiğinde, 3d modelin güncellenmesi gerekir ve ürün kategorilerinin hiçbirine ait değildir, bu nedenle eklenen / kaldırılan / değiştirilen öğeleri dinleyen uygulama sınıfında referans verilir. Sonunda bu her ürün kategorisi için hemen hemen aynı olurdu. Diğer UI parçaları da tepki verir (ve dinler), ancak mesajın üste gitmesi gerekir, çünkü 3dmodel referansı ve gerçek veriler (daha sonra da güncellenir) buradadır.
R. Schmitz
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.