WCF / SOA - Neden basit istekler için parametre nesneleri oluşturmalıyım?


12

Şirketimiz oldukça büyük bir SOA girişimine başlıyor. Birçok şeyi doğru yapıyoruz: iyi iletişim var; uygun olduğunda araçlar için para; ve geçiş konusunda bize yardımcı olacak bazı uzmanlıklar getirdik.

Grup olarak takip edebileceğimiz standartlar geliştirmeye çalışıyoruz ve önerilen standartlardan biri beni biraz rahatsız ediyor:

Her işlemin bir istek nesnesini aldığı ve bir yanıt nesnesini döndürdüğü model üzerinde standartlaştırdık.

Bunun birçok insan için az çok standart bir yaklaşım olduğunu fark ettim, ama neden rahatsız etmem gerektiğini soruyorum. (Alınan bilgelikte o kadar iyi değilim, nedenine ihtiyacım var).

Vereceğim hizmetlerin çoğu basit kurumsal meta veri alımıdır. Örneğin, belirli bir kullanıcının güvenlik ilkesini bulun. Bunun için bir kullanıcı kimliği gerekir ve başka bir şey gerekmez. Standart, bu isteği bir nesneye sarmam ve döndürülen ilkeyi bir yanıt nesnesine sarmam gerektiğini söylüyor.

Rahatsızlığım, sözleşmelerimizden üretilen WSDL'ye bir bakışla güçlendirildi. WCF otomatik olarak istek ve yanıt iletileri oluşturur ve hatta istek / yanıt nesnesini sarar.

Karmaşık bir istekte bulunursanız, karmaşık bir giriş nesnesinin garanti edildiğini tamamen anlıyorum. Hizmetler dahil olmasa bile bunu yapardınız.

Sorum şu: Neden istekleri ve yanıtları otomatik olarak sarmam gerekiyor?

  • Basit hizmetleri daha az etkileyici hale getirir
  • Karmaşık bir hizmet için yine de yapardınız
  • WCF yine de bir istek / yanıt mesajı oluşturur

Bu yaklaşım lehine aşağıdaki argümanları buldum:

İsteğe bağlı parametrelerin istek nesnesine kaydırılmasına izin vererek sürüm oluşturmayı destekler.

O günlerde, biraz COM yaptım ve bunu versiyonlama için neredeyse bir anti-desen olarak düşünürdüm. Bazı şeyler için, sanırım yardımcı olur, ama ben yardımcı olacağı yerde zaten zaten bir parametre nesnesi var bekliyoruz.

Ortak veri ve davranışın temel bir sınıfa ayrılmasını sağlar

Bu benimle biraz ağırlık taşıyor.

İnsanları bir RPC tarzı davranıştan ve bir mesajlaşma davranışına doğru yönlendirir

Bunu Microsoft'un sitesinde okudum ve gurumuzdan duydum, ancak ne anlama geldiklerini veya neden değerli olduklarını hala net bir şekilde bilmiyorum. Doğal görünümlü arayüzler insanları uzaktan servis çağırdıklarını unutmaya yöneltti mi?

Belki 300 yöntemin imzasını yeniden gözden geçirmeye çalışıyorum, bu yüzden bu önemsiz bir acı. Ben uygulamalarda büyük bir tutarlılık hayranıyım, bu yüzden acıyı üstlenmeye hazırım, sadece sonunda buna değeceğini bilmek yardımcı olacaktır.

Yanıtlar:


3

Bence versiyonlama muhtemelen en iyi argüman. Gibi mevcut bir işletme sözleşmeniz olduğunda

int GetPersons(int countryId);

daha sonra geliştirmek istediğiniz başka bir filtreyle

int GetPersons(int countryId, int age);

Benzersiz olması gerektiğinden, yeni bir işletme sözleşmesi ve yeni bir ad yazmanız gerekir. Ya da eski v1 geriye dönük uyumluluk için hala yanınızda olduğunda, adı saklar ve hizmetinizin yeni bir v2'sini yayınlarsınız.

Parametreyi bir nesneye sarırsanız, her zaman varsayılan / isteğe bağlı parametrelerle genişletebilirsiniz ve aynı işlem sözleşmesini yeniden kullandığınızda mevcut tüm istemcileriniz bundan etkilenmez.

Bununla birlikte, nesnelerinizi uygun şekilde adlandırmayı da isterim. Sadece bir int sararsa bile, IntMessageya da buna benzer bir şeyle başlarsanız, kendinizi genişleten bir iyilik yapmazsınız. Örneğin PersonFilter, en başından itibaren bu servis çağrısının semantik olarak parametre olarak ne beklemesi gerektiği ve dolayısıyla ne yapılması gerektiği hakkında biraz düşünmeniz gerektiği anlamına gelir. Belki (ve bu çok belirsiz olabilir) bu, doğru hizmetleri geliştirmeye ve iyi boyutta bir API sürdürmeye yardımcı olacaktır.

Ortak veri ve davranışın temel bir sınıfa ayrılmasını sağlar

Dikkatli olunması gereken bir şey. Miras ve veri sözleşmeleri birlikte iyi gitmiyor. Çalışıyor, ancak telin üzerinden geçebilecek sözleşmenin bilinen tüm alt türlerini belirtmeniz gerekecek, aksi takdirde veri sözleşmesi serileştiricisi bilinmeyen türlerden şikayetçi olamaz.

Ama ne olabilir yapmak (ama yine muhtemelen, hala bu konuda kararsız olduğum olmalı) farklı hizmetler arasında aynı mesajlar yeniden kullanımıdır. Ayrı bir dll veri sözleşmeleri koyarsanız, istemci ve hizmet arasında paylaşabilirsiniz ve temelde aynı iletiyi bekleyen farklı hizmetleri çağırdığınızda türleri arasında dönüştürmek gerekmez. Örneğin, bir PersonFilter oluşturursunuz ve kişilerin filtre listesini almak için bir servise, ardından başka bir servise gönderir ve istemcide aynı nesneleri bulundurursunuz. Bunun için iyi bir gerçek dünya örneği bulamıyorum ve tehlike her zaman veri sözleşmelerinin uzatılmasının bu sözleşmeyi kullanan tüm hizmetler için yeterince genel olmamasıdır.

Genel olarak, versiyonlama dışında, bu şekilde yapmanın katil nedenini gerçekten bulamıyorum.


Sanırım neden almamın nedeni
Andy Davis

(üzgünüm, yorum arayüzü bana keder veriyor) Cevap verdiğiniz için teşekkür ederim. Bu tür bir tuz tanesi ile versiyonlama argümanını almamın nedeni, yeni bir argüman eklerseniz muhtemelen anlambilimi değiştirmiş olmanızdır. (Örneğinizde olduğu gibi) henüz bir yaş eklediyseniz, anlambilim büyük olasılıkla arama amaçlıydı ve orada başlamak için bir "arama nesnesi" vardı.
Andy Davis

Şimdi güvenlik politikası örneğimi ele alalım. Belki de bir güvenlik politikasını doğru bir şekilde sağlamak için sadece kullanıcıyı değil, içinde çalıştıkları tesisi de bilmemiz gerektiğine karar veriyoruz. Bu bir argüman eklemekten çok daha fazlasıdır, çağrının anlamını değiştirdik. Bir şekilde önceki sürümün arayanı için bu bilgileri sağlayabildiğimizi varsayarsak, hizmet sözleşmesini sürümlendirmenin daha mantıklı olduğunu düşünüyorum. Daha sonra eski sürüm için uygulama izole edilebilir ve eski semantiği yeni ile karıştırmazsınız.
Andy Davis

0

Martin Fowler'in Veri Aktarım Nesnesi ile ilgili notlarının burada uygun olduğunu düşünüyorum.

Uzak Cephe (388) gibi bir uzak arabirimle çalışırken, ona yapılan her çağrı pahalıdır. Sonuç olarak, arama sayısını azaltmanız gerekir ve bu da her aramada daha fazla veri aktarmanız gerektiği anlamına gelir. Bunu yapmanın bir yolu çok sayıda parametre kullanmaktır. Bununla birlikte, bu genellikle programlamak için gariptir - aslında, Java gibi diller için yalnızca tek bir değer döndürmek genellikle imkansızdır.

Çözüm, çağrı için tüm verileri tutabilen bir Veri Aktarım Nesnesi oluşturmaktır. Bağlantıyı geçmek için serileştirilebilir olması gerekir. Genellikle DTO ve herhangi bir etki alanı nesnesi arasında veri aktarmak için sunucu tarafında bir montajcı kullanılır.

Aynısı istekler için de geçerli olabilir. RPC gelince, ve neden kötü:

Doğal görünümlü arayüzler insanları uzaktan servis çağırdıklarını unutmaya yöneltti mi?

Bence bu doğru, ama ana sebep değil. RPC'den kaçınmanın bir başka nedeni, sıkı bir şekilde bağlı müşterileri ve hizmetleri teşvik edebilmesidir.


Giriş için teşekkürler, ancak DTO tartışmasının bu kadar alakalı olduğunu düşünmüyorum. Aynı sayıda çağrıdır ve WSDL'ye bakarsanız, her şey otomatik olarak bir istek ve yanıt nesnesine paketlenir. Sözleşme görünür semantikle ilgilidir, yani insanlar bunu uzaktan yöntem çağrısının aksine bir istek ve yanıt olarak düşünmelidir.
Andy Davis

Sıkı birleştirilmiş müşterileri ve hizmetleri teşvik eden RPC'leri detaylandırmak ister misiniz? Bunun hizmeti hiç etkilediğini göremiyorum. Müşteri için, hiçbir şeyin gerçekten nasıl değiştiğini gerçekten görmüyorum. Her iki durumda da, bir hizmet tarafından sağlanan bir dizi işlemi açıklayan bir proxy tutan istemcim var. Hizmetin diğer tarafını gerçekten uygulayan, her durumda müşterinin işi değildir.
Andy Davis
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.