Bir dizi işlem için en iyi OOP tasarım deseni


11

Ben bir modül aşağıdaki finansal işlemleri sırayla yapan bir uygulama üzerinde çalışıyorum:

Bir kullanıcı banka hesabına belirli bir tutarın aktarılmasını istediğinde:

  1. şimdi herhangi bir işlem olup olmadığını kontrol edin? (işlem sadece belirli bir zaman diliminde yapılabilir)
  2. kullanıcının minimum bir tutarın geri çekilmesini isteyip istemediğini kontrol edin
  3. kullanıcının herhangi bir varsayılan hesabı olup olmadığını kontrol edin

Yukarıdaki tüm eylemlerin sonucu günlüğe kaydedilmelidir.

Yukarıdaki koşulların tümü yerine getirilirse, işlem gerçekleştirilir. Gelecekte, bazı ek kontroller olabilir.

Hangi nesne yönelimli tasarım deseni yukarıdaki durum için en uygun olmalıdır?


3
Bir sorunu çözmek için asla bir tasarım deseni aramayın. Doğru çözümü iletmek için tasarım kalıplarını kullanın. programmers.stackexchange.com/questions/70877/… SOLID ilkelerine uyun ve çok fazla yanlış gitmeyeceksiniz.
pdr

2
Katılmıyorum. Kalıplar iletişimi kolaylaştıran isimlere sahiptir ve aynı zamanda çözümleri iletmek için de kullanılmalıdır. Ancak, "Bir sorunu çözmek için asla tasarım deseni arama" konusuna katılmıyorum. Sadece belirli sorunları çözmekle kalmazlar, aynı zamanda farklı güç ve kısıtlamalarla da uğraşırlar. "Proxy" ve "Dekoratör" e göz atın. Benzer görünüyorlar ancak farklı sorunları çözüyorlar. Benim düşünceme göre, bir sorunu kendiniz çözmeden önce, en azından her ikisinden de kazanç elde etmek için tanınmış tasarım modellerine, bir sorunu çözmek için standart bir yaklaşıma ve onu iletmenin kolay bir yoluna bakmalısınız.
Jonny Dee

10
İşte bir kalıbın ne olduğunun iyi bir karakterizasyonu: "Yazılım geliştirme sırasında, organizasyondan programlama bağlamlarına kadar belirli durumlarda tekrar tekrar ortaya çıkan sorunlara çalışma, somut ve uyarlanabilir çözümler sunuyorlar." [POSA5, s. 30] Dolayısıyla bu açıdan bakıldığında, uyarlanabilir bir çözüm olarak bir örüntü aramanın, meşru bir yaklaşım olduğu açıktır.
Jonny Dee

3
Eski yöntemsel programlamayı tanımlamak için nesne yönelimli bir yapı mı istiyorsunuz?
mouviciel

4
KISS prensibini takip edin. Şimdiye kadar sorununuz tek bir yöntemle 3 "if" ifadesi ile çözülebilir. Sadece serin olmak için tasarım deseni kullanmaya çalışmayın. Her ek ders yazışınızda, daima şunu düşünün: Gerçekten buna ihtiyacım var mı?
Eiver

Yanıtlar:


13

Aradığın şey bir Sorumluluk Zinciri . Bu durumda aşağıdaki sınıflara sahip olabilirsiniz:

  • TransactionValidatorBase soyut temel sınıf
  • TransactionTimeValidator
  • TransactionAmountValidator
  • TransactionAccountValidator

Bunlar, belirttiğiniz birçok kuralı uygulamak için birlikte zincirlenir.

Furter Okuma


11
Anladığım kadarıyla Sorumluluk Zinciri daha çok bir filtre - yani sorumlulukla başa çıkacak donanıma sahip olanı bulana kadar zinciri aşağı iniyoruz, o zaman bu "bağlantı" sorumluluğu ve çıkışı ele alacak. COR'daki pratik anlamda bir kusur, bunun bir değere dönmesini zorlaştırmasıdır, bunun için ihtiyaç duyabileceğiniz gibi görünüyor.
Amy Blankenship

Bence tek seviyeli bir R Zinciri olabilir. Ben bir Zincirden bir değer döndürmek zor değil, biraz abtracing sanmıyorum. Her seviyenin belirli bir ilkel arayüze bağlı kalarak iletişim kurması gerekecektir ve bu tür girişler ilkel arayüze uygun olduğu sürece, aşağıdan gelen girişi kabul etmesi gerekecektir. Daha sıkı bir şekilde bağlanmış iki Zincir seviyesi arasında arayüz zenginliği gerektiğinde, bunu desteklemek için çıkarma poli-morphed edilebilir.
Andyz Smith

3

Adım diziniz çoğunlukla (göründüğünüz gibi) doğrulama görevlerini yapıyorsa, girdileri değiştirmeden, @pswg tarafından verilen cevabında açıklandığı gibi gerçekten "Sorumluluk Zinciri" desenini düşünürdüm

Ancak sorunuz biraz daha genel olduğundan, "Boru Hattı işleme" yi de eklemek istiyorum, çünkü bununla birlikte, bir adım bir sonraki adım için girdi olacak bir çıktı üretecektir (böylece orijinal girişi mutasyona uğrar) .

İşte bu konuda iki makale:
Martin Fowler tarafından hazırlanan boru hattı koleksiyonu
Model hakkında daha fazla teorik tartışma


2

Burada doğru örüntü gerçekten bir bağlama bağlıdır. Herhangi bir kalıbı seçmeden önce, bu soruların cevaplarını bulmaya çalışacağım:

  • Çalışma zamanında (1,2,3) kontrollerin farklı kombinasyonlarının oluşturulması gerekli midir?
  • Eylemlerini gerçekleştirmek için aynı değişkenlere ihtiyaçları var mı yoksa çok farklı mılar?
  • Hata mesajları ne kadar kesin olmalıdır?
  • Arıza durumunda, kullanıcı her zaman (1). Adımdan tekrar dener mi?
  • Eşzamanlılık nasıl ele alınır?
  • Her yöntem isteğe bir şey ekler mi yoksa sadece doğrular mı? (Varsayılan acct id deyin?)

Bağırsak hissine dayanarak, bunları hata kodları için toplama parametresi ile düz bir yöntem olarak kodlarım.

public void DoTransaction(IErrorAgregator error, TransactionRequest request)
{
    if(!IsTransactionInCertainTimePeriod(request, error)) return;
    if(!IsTransactionAmountInUserBounds(request, error)) return;
    if(!UserHaveDefaultAccount(request, error)) return;
    bankingTransactor.PerformTransaction(request);
}

DoTransaction'ı "ITransactionValidationStragegy" arayüzüne koymak ve doğrulama kaynak plakası içerecek bir katman süper türü oluşturmak iyi bir fikir olabilir.

Ancak, bu tasarımda geçerlilik mantığının derleme zamanında belirlendiğini varsayıyorum.


0

Desenler burada daha önce belirtilmiş olsa da, kullandığınız çerçevelere dayanarak, uygulamanızda nasıl kullanmak istediğinizi düşünmenizi öneririm.

Örneğin, yapmak istediğiniz doğrulama, büyük olasılıkla zaman ilerlemesi olarak ve ne zaman değişmeye devam edecektir (ileride işlemleri günde 10 ile sınırlandıran yeni bir doğrulama eklemek isteyebilirsiniz). Ayrıca, gerçek işletme hizmetiniz veya entegrasyon kodunuz devreye girmeden önce doğrulamayı yapmak istemeyebilirsiniz. Doğrulamaları yapılandırılabilir olarak ekleyebilmeniz iyi olur.

Struts kullanıyorsanız, önleyici kullanmak iyi bir fikir olabilir. Bahar durumunda, bağımlılık olarak fasulye enjeksiyonu size daha fazla esneklik sağlar. Benim önerim sadece kalıplara / deyimlere bakmak değil, aynı zamanda uygulamayı inşa etmek için kullandığınız çerçeveye bakmak ve fütüristik bir bakış açısından gereksiniminize en iyi nasıl uyabileceğinizi görmek.


-2

Anladığım kadarıyla, gerekli olan her şey aşağıdaki gibi komut düzenine yerleştirilebilir. Sınıf tasarımı aşağıdaki gibi yapılabilir.

interface Transaction{
void performAction();
}

class Banking{

void moneyValidation(){
//Validate Here
}

void timeValidation(){
//validate Here
}
}

class TimeValidation implements Transaction{

public Banking bank;

public TimeValidation (Banking bnk){
bank=bnk;
}

void performAction(){
bnk.timeValidation();
}


class MoneyValidation Implements Transaction{

public Banking bank;

public MoneyValidation(Banking bnk;){
bank=bnk;
}

void performAction(){
bnk.moneyValidation();
}
}


class Control{

private List val_list=new ArrayList();

void storeValidation(Transaction trans){
val_list.add(trans);
trans.performAction(val_list.getFirstAndRemove());
}
}

//Same for other validation classes

Müşteri sınıfınız aşağıdaki kod snippet'ini içerecektir:

Banking bnk = new Banking();
MoneyValidation m_val = new MoneyValidation (bnk);
TimeValidation t_val = new TimeValidation (bnk);
Control ctrl = new Control();
ctrl.storeValidation(m_val);
ctrl.storeValidation(t_val);

Anladığım kadarıyla, yukarıda verilen senaryo ile.


Kötü çünkü para doğrulaması başarısız olduğunda, zaman doğrulaması işe yaramaz ama yine de yapılacak
Ewoks
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.