İndirim modellerine uygulanacak bir tasarım deseni var mı?


35

İndirim modellerini uygulamak için bilinen herhangi bir tasarım deseni var mı?

İndirim modelleriyle şunu kastediyorum:

  1. Bir müşteri Ürün X, Ürün Y ve Ürün Z'yi satın alırsa,% 10 veya 100 $ indirim alır.

  2. Bir müşteri 100 adet X Ürün satın alırsa,% 15 veya 500 $ indirim alır.

  3. Bir müşteri geçen yıl 100.000 ABD Dolarından fazla gelirse,% 20'lik sabit bir indirim alır.

  4. Bir müşteri 2 adet Ürün X satın aldıysa, 1 adet Ürün X (veya Ürün Y) ücretsiz alır.

  5. ...

Yukarıdaki senaryoların tümünü işlemek için uygulanabilecek genel bir kalıp var mı? Birkaç model düşünüyorum, ancak genel bir rastlamak mümkün değil.


IIRC indirimler içeren örneklerle gördüğüm tüm öğreticiler (çok sayıda var) önerilmektedir Strateji kalıbı
gnat

2
@Kanini Bu gerçek dünyadan bir sorun mu? Böyle bir durumda bu sistem gerçek zamanlı mı yoksa ertelenmiş zamanlı mı? Bu kurallar kural motoru ya da veritabanı değerleri olarak mı sunuluyor? İndirimler için arama önceliğe göre hiyerarşik midir? Strateji paterni çoğu durumda işe yarayacaktır, ancak kuralların işe
yaraması

3
Ayrıca eğer biri 2 birim Ürün X, bir Ürün Y ve bir Ürün Z satın alırsa, hem% 10 hem de ekstra bir ürün X olur mu?
Ubermensch,

@gnat bu eğiticilerin bazılarına bazı bağlantılar lütfen.
user16764

Yanıtlar:


18

Mesele, birden fazla indirim uygulamanız gerektiğinde, belirli koşullar altında, Sorumluluk Zinciri modelini göz önünde bulundurmak isteyebilirsiniz .

Özetle, işlemek istediğiniz bilgileri ilk işlemciye iletirsiniz ve sonucu döndürmeden önce diğer işlemcilere iletip iletmemeye karar verir.

Bu sayede çağıran kodu değiştirmeden işlemcilerin yapısını ve sırasını değiştirebilirsiniz.


Sorumluluk Zinciri başka bir iyi olanıdır. Belki bir strateji ile birleştirilebilir. Sadece bir indirimin uygulanabileceği bir durumda, her strateji bir başkasıyla zincirlenir. Her zincir indirimini (müşteri uygunsa) hesaplar, önceki indirim ile karşılaştırır ve müşteri, sipariş ve indirim verilerini bir sonraki zincire aktarır. +1.
Thomas Owens

1
Sadece benim görüşüme göre, ancak bu sorumluluk için "Sorumluluk Zinciri" nin aşırı tasarlanma olasılığı daha yüksek. Basit bir indirim model listesi (gerekirse sipariş numarası ile birlikte) bunu yapmalıdır. Tüm müşterilere eşit muamele edilmesi gerektiğinden listenin kendisi müşteriden ve siparişlerinden bağımsızdır. İndirim modeli listesi, çalışma zamanında oldukça dinamik bir şekilde çok sık değiştiğinde "sorumluluk zinciri" daha uygundur.
Doktor Brown

11

Strateji, Dekoratör ve Devlet kalıpları bana potansiyel başlangıç ​​noktaları olarak göze çarpıyor. Devlet 2 ya da 3 için özellikle faydalı olabilir, çünkü 2 siparişin durumuna ve 3 ise müşterinin durumuna göre değişir. Strateji ve Dekoratör diğerleri için öne çıkmaktadır, çünkü siparişe yeni indirimler eklemek için çoklu sipariş fiyatı hesaplama algoritmaları ve dekoratör uygulamak için stratejiyi kullanabilirsiniz.

Ancak, tasarım modellerinin sadece model olduğunu unutmayın. Uygulanan tek bir kalıp olmayabilir, daha çok bir kalıp sistemleri olabilir. Ayrıca, çözümünüze daha iyi uymaları için tarif edilen modellerde değişiklikler yapmayı düşünün. İyi bir tasarıma sahip olmak, sadece bir desene sahip olduğunuzu söyleme uğruna mutlaka yardımcı olmayacağı bir desene zorlamaktan daha iyidir.


Devlet modelinin yapması amaçlanan şey bu değil, değil mi?
pdr

@pdr Neden olmasın anlamıyorum. Ancak uygulamanıza bağlıdır. Müşteri hedefiniz müşteriye bağlı indirimleri takip ederse, müşterinin hak ettiği indirimleri iade etme işlemi yapılabilir. Müşteri bir şeyleri satın alırken, özellikler değişir ve bu yöntem uygulaması durum modeli ile değişir.
Thomas Owens

1
Hmm, ne demek istediğini anlıyorum. Müşterinin uygulamada yarı kalıcı bir nesne mi yoksa sadece veritabanında yaşayan ve güncellenmesi gereken bir şey mi olduğunu düşünüyorum. Bu sorudan net değil, bu yüzden yeterince adil. +1
pdr

3
Tecrübelerime göre, bu tür iskonto verme kuralları her zaman kararsız pazarlama / satış departmanları tarafından değiştiriliyor. Tamamen kodlu değil, verileri yönlendirmeli ve kullanıcı tarafından değiştirilebilmeleri için büyük ihtiyaç vardır. Bu, model seçimini nasıl etkiler?
jfrankcarr

@jfrankcarr Aklımda olmaz. Bir indirime yol açan kalem kümelerinin değerlerini, yüzde oranlarını düşürür ve bir tür konfigürasyondan elde ederim. Durum makinem dinamik olarak dekoratör ve stratejilerimin geçişlerini ve niteliklerini oluşturma.
Thomas Owens

10

Eh, "Önkoşul" yöntemlerini içeren bir sınıf olduğu "Önkoşul" ve "İndirim" olarak bir indirim modeli tasarlardım

  bool IsFulfilled(Customer c);

veya / ve

  bool IsFulfilled(Customer c, Order o);

ve İndirim'in bir yöntemi var void ApplyTo(Customer c). Bu size herhangi bir önkoşul türünü herhangi bir iskonto türü ile birleştirme imkanı verir (bence bu bir "köprü deseni" biçimidir).

Sabit sayıda ön koşula sahipseniz, sorunu belirli alt türler (strateji modeli) oluşturarak çözebilirsiniz. Bununla birlikte, ön koşullarınızın çok karmaşık olmasına izin verildiğinde, AND, OR ve NOT gibi mantıksal ifadelerle, koşullar için bir tür kural tercümanı daha iyi uygulayabilirsiniz. Kurallar, basit bir "etki alanına özgü dil" ile yazılmış düz bir metin dizesi olabilir.

Aynısı "İndirim" dersi için de geçerlidir, farklı indirimler için bazı alt tipler veya iskonto kurallarının bazı tercümanlar tarafından değerlendirilen metin biçiminde verildiği genel bir yaklaşım olabilir.



4
  • Muhtemelen bir IDiscount arayüzüne ihtiyaç duyar, çünkü tüm farklı indirimler aynı şeydir ve onlarla kavramsal olarak genel indirimler olarak ilgilenmek isteriz.

  • "Bu müşterinin siparişi" sınıfı muhtemelen bir İndirimler koleksiyonuna ihtiyaç duyar. Liste? Hash? Bağlantılı liste? Henüz umrumda değil. İndirimler müşteriye değil satın alma işlemine uygulanır!

  • İndirim örneğini Müşteri, Alışveriş Sepeti, Tarih, vb. Gibi ayrı tutun. Bu, jfrankcarr'ın işaret ettiği gibi çok değişecek.

  • Her indirim için algoritma ve parametreler çılgınca ve tahmin edilemez şekilde değiştiğinden, muhtemelen her indirim için farklı bir sınıf vardır.

  • İndirim hesaplamasının alışveriş sepetindeki değişikliklere yanıt vermesi ve bunun tersi için bir çok olay işleme görüyorum.

Tasarım Deseni Uygulaması

  • Bir bakın strategy pattern. IDiscount, farklı indirim algoritmaları uygulamak için kullanılan arayüzdür.
  • Bir bakın factory. Kesinlikle tam gelişmiş değil abstract factory pattern, analizde bu noktada tek bir sınıf var. Makul olarak, hangi indirimlerin uygulanacağına karar vermek ve daha sonra bunları oluşturmak için yeterli bağlamın olduğu tek bir yer olmalıdır. Bir sınıf. Bir Pazarlama Departmanı mantar partisi nedeniyle daha sonra indirimlerin uygulanmasıyla ilgili kurallar patlarsa, ilave bir İndirim İnşaatı mantığı hala bu temel fabrika sınıfında birleşmelidir.

  • Görebildiğim Chain of Responsibility. Bu, factoryfikre karşılıklı olarak dahil değildir . Bir indirim koleksiyonunu yinelemek yerine, her indirim bir sonraki adamı çağırır. "Müşterinin emri" sınıfı, bu durumda indirim tahsilatı yapmaz.

  • Sorumluluk Zinciri'ndeki "hmmmm ...." faktörü, sanırım, her İndirim bir diğerine atıfta bulunuyor. Bunun anlamı, emrin önemli olduğudur. Bu durum böyle değil. Ayrıca, CoR kavramı, bir nesnenin isteği üstesinden gelemediği için "bir sonraki yüksek otoriteye kadar" iletilir. Modelimiz farklı. Tek talep hesaplamaktır. Her indirim bunu yapar. Çıktı veya sonuç null olabilir, ancak her indirim hesaplar. İçgüdüsel olarak daha yüksek gerçek dünya sadakatine dayanırım.

Varsayımlar

  • İndirimler mevcut alışveriş sepetine ve / veya satın alma geçmişine dayanmaktadır
  • Sıfır veya daha fazla indirim geçerli olabilir. Karşılıklı özel indirim yoktur
  • Doğru hesaplama, indirimlerin uygulanma sırasına bağlı değildir.

Ne değişir, ne kalır?

  • İndirimler çok farklı. Her kuralı oluşturacak farklı sayı ve tür parametreler.

  • Uygun indirimler için argümanlar, alışveriş sepeti değiştikçe değişir.

  • Mevcut indirimlerdeki değişiklik sayısı

  • Bu müşterinin alışveriş sepeti değiştikçe yaptığı değişikliklerde hak kazandığı indirimler.

  • Alışveriş geçmişi bu satın alma bağlamında değişmiyor

  • Toplam maliyet, alım hatlarının ve uygulanan indirimlerin bir fonksiyonu olarak dinamik olarak değişmektedir.

  • İlk uygulamadan sonra, örneğin satın alma miktarı değiştikçe iskonto oranı değişebilir.


Harika ve eksiksiz cevap ... AMA sadece endişeliyim ve varsayımlar bölümünün orada olmaması gerekiyor, en azından cevabı yönlendirmemeliyim. Bütün fikir şudur ki, kalıp, "varsayımlar" hakkında tam olarak uyuşmaya ve unutmaya yardım eder, genel kural, hesaplamaların nasıl yapıldığını ve bağlamdan ayrıntılı bir uygulamanın ne kullandığını bilmek zorunda değildir. , Gündüz Saati, Sezon vb. Gerçekten de olsa tam yardım
le0diaz 27:17

Öndeki kurşunlar ve 'Varsayımlar' bölümü, tabii ki indirim modeli tasarımında sıkıntı yaratan sorunun kendisinin sebebi olan "işinizi gösterir". Örneğin, indirim yürütme emri ve karşılıklı bağımlılık konusundaki varsayımlarım Sorumluluk Zincirinin önemini vurgulamama neden oluyor. Desenin amacını düşündüğümü unutmayın, @docbrown'un yaptığı gibi karmaşıklığı değil. Ben, tasarıma niyetini yansıtan coşkulu bir savunucuyum.
Radarbob

1

Mantıksal olarak, bir indirim modeli herhangi bir şey olabilir , bu nedenle tüm vakaları önceden programlayabileceğinizi varsayamazsınız. Sorunuzu cevaplayan herhangi biri gerçekte neye ihtiyacınız olduğunu tam olarak bilemez. Ancak, gerçek dünyada bulunan her zamanki indirim türlerini aldığınızı varsayarsak ...

Büyük bir soru, indirimlerin programlanıp programlanmayacağı veya kullanıcıların girmesini isteyip istemediğinizdir. Yukarıda bahsedildiği gibi, hiçbir zaman programlanmalarını sağlayamazsınız , ancak genellikle amaç, hepsini sıralamaktan ziyade, ortak durumlar için daha fazla veri girişi yapmaya çalışmaktır. Bu, tüm indirimleri oluşturmak için programcılar kullanılsa bile bir dereceye kadar geçerlidir.

Martin Fowler, muhasebe sistemleri için "Gönderme Kuralları" nın nasıl uygulanacağının bir parçası olarak "Analiz kalıpları: yeniden kullanılabilir nesne modelleri" bölümünde "Bireysel Örnekleme Yöntemi" nden bahseder, ancak kurallar sizinkilere oldukça benzer görünüyor. Daha fazla detay verirdim ama bu telif hakkı alınmış bir iş ve

Bir kullanıcı arayüzü için, oldukça basit olan kullanım durumları bulmanız veya başka bir tercüman ve sorgu oluşturucu oluşturmanız gerekir. Muhtemelen her ikisi de, basit durumlar için bir tane ve bir tane daha gelişmiş. Bir tercüman yazarsanız, bu, Tercüman modelini kullanmak için oldukça iyi bir durumdur, çünkü ayrıştırıcı oluşturucuya göre kodlamak nispeten kolaydır ve daha yavaş ayrıştırma süresi muhtemelen gerçekten önemli olmaz. (Ayrıştırma jeneratörleri kullanmaktan hoşlanıyorsanız, sizi durdurmama izin vermeyin).

Her şeyi tercümanla yapmaya çalışmayın - bir noktada sadece kendi dilinizde programlama yapabilirsiniz, yani gerçek bir dil de kullanabilirsiniz. Tercüme edilmiş diliniz işlevleri destekliyorsa (muhtemelen onları çağırmayı desteklemeli - onları tanımlamak şüphelidir) bunlar gerçek bir dilde kodlanabilir. Bu yoldan gitmen gerekenden daha ileri gitme.

Ne yaparsanız yapın, sonunda birisi indirimin promosyondan sonraki 30 iş günü içerisinde satın alınıp alınmayacağına dayanmasını ister - iş günleri yalnızca mağazanın posta kodu veya müşterinin belirlediği bölgede tatil yapılmaması durumunda sayılır. posta kodu. Öyleyse, mükemmel sistemi önceden tasarlamaya çalışmayın - bazen yeni indirimler ve buna göre tasarım için kod yazmanız gerekeceğini varsayalım.


0

Bunun için faydalı bir kalıp olup olmadığını sormanın bir anlamı var mı? Ne tür bir kalıp gereklidir - yapısal mı yoksa davranışsal mı?

İdeal olarak, bunun için bir yazılım yazacak olsaydım, tek gereken bir algoritma . Toplam indirimi şu şekilde hesaplayan basit bir işlev:

cart.calculateDiscount(productVector);

Bundan daha fazlasına ihtiyacınız yok!

Açıklığa kavuşturmak için: Pek çok kuralın olacağını anladım - bu temsili en temel olanı bir rulebase (veri özellikleri kümesi ve buna karşı sonuçta elde edilen indirim) şeklinde olması ve yukarıdaki gibi bir fonksiyonun bunu hesaplamak için yinelemesini gerektiriyor. Kural eklenirse veya kaldırılırsa, kodu değiştirmeye son vermemelisiniz - yalnızca kural tabanını değiştirin.

Desen yalnızca birbirlerinin API'lerine erişmek veya bir görevi yerine getirmek için iletişim kurmak için farklı nesnelere ihtiyaç duyduğumuzda gerekli olacaktır.

Not: Bir güvenlik duvarı paketleri işlediğinde ve paketleri geçerken veya reddettiğinde (veya değiştirdiğinde) düşünün - hangi tasarım desenini kullanıyor? Cevap yukarıda açıklananların YOKTUR!


Elbette bundan daha fazlasına ihtiyacınız var !!!. Buradaki fikir, algoritmanın kod uygulaması ile sıkı sıkıya bağlantılı olmadığıdır. Senaryoları kontrol ederseniz, daha fazla senaryonun ortaya çıkması muhtemeldir, ayrıca bir şekilde bahsetmişsinizdir, gerçekten herhangi başka bir 'Kuralın' neye dayanacağını bilmiyor. Bir kuralın sadece ürün listesine bağlı olacağını düşünmek saf değildir, ancak gerçekte müşteriye, zamana, mevsime vb. Bağlıdır. Hangi Güvenlik Duvarı uygulamasını kontrol ettiğinizi bilmiyorum, ancak kontrol ettiklerim birçok yapısal / tasarım
desenine sahip değiller
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.