Bu, sorunuzun altındaki ilk yorumumun daha iyi oluşturulmuş bir transkripsiyonudur. OP tarafından yöneltilen soruların cevapları bu cevabın alt kısmında bulunabilir. Lütfen aynı yerde bulunan önemli notu da kontrol edin .
Şu anda açıkladığınız şey, Sipo, Aktif kayıt adı verilen bir tasarım modelidir . Her şeyde olduğu gibi, bu bile programcılar arasında yerini buldu, ancak basit bir nedenden dolayı ölçeklenebilirlik için depo ve veri eşleme desenleri lehine atıldı .
Kısacası, aktif bir kayıt bir nesnedir:
- alan adınızdaki bir nesneyi temsil eder (iş kurallarını içerir, bir kullanıcı adını değiştirip değiştiremeyeceğiniz gibi bir nesne üzerinde nasıl işlem yapılacağını bilir),
- Varlığın nasıl alınacağını, güncelleneceğini, kaydedileceğini ve silineceğini bilir.
Mevcut tasarımınızla ilgili birçok sorunu ele alıyorsunuz ve tasarımınızın ana problemi son 6'ncı noktaya (son fakat en az değil, sanırım) değiniyor. Bir kurucu tasarladığınız bir sınıfınız olduğunda ve kurucunun ne yapması gerektiğini bile bilmiyorsanız, sınıf muhtemelen yanlış bir şey yapıyor demektir. Bu senin davanda oldu.
Ancak tasarımın düzeltilmesi aslında varlık temsilini ve CRUD mantığını iki (veya daha fazla) sınıfa bölerek oldukça basittir.
Tasarımınız şu şekilde görünüyor:
Employee
- çalışan yapısı (öznitelikleri) hakkında bilgi içerir ve varlığı nasıl değiştireceğinize ilişkin yöntemler (değişebilir şekilde gitmeye karar verirseniz), Employee
varlık için CRUD mantığı içerir Employee
, bir Employee
nesne listesi döndürebilir , istediğiniz zaman bir nesneyi kabul edebilir bir çalışanı güncelleyin, tek Employee
bir yöntemlegetSingleById(id : string) : Employee
Vay, sınıf çok büyük görünüyor.
Önerilen çözüm bu olacaktır:
Employee
- çalışan yapısı (öznitelikleri) ve varlığın nasıl değiştirilebileceği hakkında yöntemler (değişebilir yoldan gitmeye karar verirseniz) hakkında bilgi içerir
EmployeeRepository
- için CRUD mantığı içerir Employee
listesini döndürebilir, varlık Employee
bir kabul, nesneler Employee
tek bir dönebilir, bir çalışan güncellemek istediğinizde nesne Employee
gibi bir yöntemlegetSingleById(id : string) : Employee
Endişelerin ayrıldığını duydunuz mu? Hayır, şimdi yapacaksın. Tek Sorumluluk İlkesinin daha az katı bir versiyonudur ve bir sınıfın aslında sadece bir sorumluluğu olması gerektiğini veya Bob Amca'nın dediği gibi:
Bir modülün değiştirmek için bir ve tek nedeni olmalıdır.
Başlangıç sınıfınızı hala iyi bir yuvarlak arabirime sahip olan ikiye bölebilirsem, ilk sınıf muhtemelen çok fazla şey yapıyormuş gibi görünüyor.
Depo deseni hakkında harika olan şey, sadece veritabanı (orta, katman, dosya, noSQL, SQL, nesne yönelimli olabilir) arasında orta bir katman sağlamak için bir soyutlama işlevi görmez, aynı zamanda somut olması bile gerekmez. sınıf. Birçok OO dilinde, arayüzü gerçek interface
(veya C ++ kullanıyorsanız saf sanal yöntemle bir sınıf) olarak tanımlayabilir ve daha sonra birden çok uygulamaya sahip olabilirsiniz.
Bu, bir havuzun gerçek bir uygulaması olup olmadığı kararını tamamen kaldırır ve interface
anahtar kelimeye sahip bir yapıya güvenerek arayüze güvenirsiniz . Ve depo tam olarak budur, veri katmanı soyutlaması için süslü bir terimdir, yani verileri alan adınızla eşleştirir ve tersi de geçerlidir.
(En azından) iki sınıfa ayırmakla ilgili bir başka harika şey, artık Employee
sınıfın kendi verilerini açıkça yönetebilmesi ve çok iyi yapabilmesidir, çünkü diğer zor şeylerle ilgilenmesine gerek yoktur.
Soru 6: Oluşturucu yeni oluşturulan Employee
sınıfta ne yapmalı ? Basit. Bağımsız değişkenleri almalı, geçerli olup olmadıklarını kontrol etmeli (örneğin, yaş muhtemelen negatif olmamalı veya ad boş olmamalıdır), veriler geçersiz olduğunda bir hata ortaya koymalı ve doğrulama başarılıysa bağımsız değişkenlere bağımsız değişkenler atamalıdır varlığın. Artık veritabanıyla iletişim kuramıyor çünkü nasıl yapılacağı hakkında hiçbir fikri yok.
Soru 4: Genel olarak değil, cevaplanamaz çünkü cevap büyük ölçüde tam olarak neye ihtiyacınız olduğuna bağlıdır.
Soru 5: Şimdi ikiye şişirilmiş sınıf ayrılmış göre, artık doğrudan çoklu güncelleme yöntemleri olabilir Employee
sınıfına gibi changeUsername
, markAsDeceased
ait verileri işlemek hangi Employee
sınıfta sadece RAM içinde ve sonra gibi bir yöntem tanıtmak olabilir registerDirty
dan Deponun bu nesnenin özellikleri değiştirdiğini ve commit
yöntemi çağırdıktan sonra güncelleştirilmesi gerektiğini bildireceği depo sınıfına yönelik Çalışma Birimi deseni .
Açıkçası, bir güncelleme için bir nesnenin bir kimliğe sahip olması ve bu nedenle zaten kaydedilmesi gerekir ve bu, ölçütlere uyulmadığında bunu algılamak ve bir hata oluşturmak için deponun sorumluluğudur.
Soru 3: İş Birimi modeli ile gitmeye karar verirseniz, create
yöntem şimdi olacaktır registerNew
. Eğer yoksa, muhtemelen çağırır save
yerine. Bir havuzun amacı, etki alanı ve veri katmanı arasında bir soyutlama sağlamaktır, çünkü bu nedenle bu yöntemin (ister registerNew
veya ister save
) Employee
nesneyi kabul etmesini ve özniteliklerin depo arayüzünü uygulayan sınıflara bağlı olmasını öneririm. kuruluştan çıkarılmaya karar verirler. Bir nesnenin tamamını iletmek daha iyidir, bu nedenle birçok isteğe bağlı parametreye sahip olmanız gerekmez.
Soru 2: Artık her iki yöntem de depo arayüzünün bir parçası olacak ve tek sorumluluk ilkesini ihlal etmeyecekler. Deponun sorumluluğu, Employee
nesneler için CRUD işlemleri sağlamaktır , yani yaptığı şeydir (Okuma ve Silme yanında, CRUD hem Oluşturma hem de Güncelleme anlamına gelir). Açıkçası, depoyu EmployeeUpdateRepository
ve benzerlerini kullanarak daha da bölebilirsiniz , ancak bu nadiren gereklidir ve tek bir uygulama genellikle tüm CRUD işlemlerini içerebilir.
Soru 1:Employee
Artık (diğer niteliklerin yanı sıra) kimliğine sahip olacak basit bir sınıfla sonuçlandınız. Kimliğin dolu veya boş (veya null
) olup olmadığı, nesnenin önceden kaydedilmiş olmasına bağlıdır. Bununla birlikte, bir kimlik hala işletmenin sahip olduğu bir niteliktir ve işletmenin sorumluluğu Employee
niteliklerine dikkat etmek ve dolayısıyla kimliğine dikkat etmektir.
Bir varlığın kimliğe sahip olup olmadığı, üzerinde bazı kalıcılık mantığı yapmaya çalışana kadar genellikle önemli değildir. 5. sorunun cevabında belirtildiği gibi, daha önce kaydedilmiş bir varlığı kaydetmeye çalışmadığınızı veya kimliği olmayan bir varlığı güncellemeye çalıştığınızı saptamak deponun sorumluluğundadır.
Önemli Not
Endişelerin ayrılması büyük olsa da, işlevsel bir depo katmanı tasarlamanın oldukça sıkıcı bir iş olduğunu ve benim deneyimime göre, aktif kayıt yaklaşımından daha doğru bir şekilde elde edilmesi biraz daha zor olduğunu lütfen unutmayın. Ancak, çok daha esnek ve ölçeklenebilir bir tasarıma sahip olacaksınız, bu da iyi bir şey olabilir.
Employee
soyutlama sağlamak için bir nesne almalıdır , 4. ve 5. sorular genellikle cevapsızdır, ihtiyaçlarınıza bağlıdır ve yapı ve CRUD işlemlerini iki sınıfa ayırırsanız, o zaman açıktır,Employee
veri getiremez artık db'den, böylece cevaplar 6.