Veritabanı erişimini nasıl kapsüllemeliyim?


10

Veritabanı erişimini yönetmek için kullanılan iyi sınıf yapılarına bazı örnekler nelerdir? Ben sınıf kapsülleme hayranıyım ve kapsayıcılar (örneğin araba) veritabanı görevleri gerçekleştirmek için tercih etmem.

Ayrıca gelecekte bir veritabanı önbellek gibi şeylerde kolayca düşme yeteneği istiyorum.

Sık sık tek bir tek sınıf tarafından gerçekleştirilen doğrulama ve veritabanı erişimi için alıcılar ve ayarlayıcılarla birlikte kap sınıflarının modelini alıyorum. Bununla birlikte, bu genellikle ikisi arasında karışır ve oldukça kafa karıştırıcı hale gelir.

Sorumu anlamak zorsa özür dilerim; Veritabanlarıyla ilgili terimlerden kesinlikle emin değilim. Gerekirse lütfen açıklama istemekten çekinmeyin.


Sınıfları Wt :: Dbo gibi veritabanlarına bağlamak için ORM kullanmayı düşündünüz mü?
user52875

Yanıtlar:


11

Veri erişimini kapsüllemek için Havuz Kalıbı'nı tercih ederim . Özetle, depo belirli bir nesne için gerekli olan tüm verilerin yüklenmesinden sorumludur. Örneğinizde olduğu gibi bir Araba nesneniz olduğunu varsayalım. Ancak araba, marka, model, yıl, sahipler, özellikler (CD çalar, 4wd vb.) İçin tüm özellikler veritabanı boyunca çeşitli tablolarda saklanır. Depo, verilerin nasıl yükleneceğini ve kaydedileceğini belirler. Birden çok daha küçük sorgu gerekiyorsa, iyi, ancak bunu yalnızca havuz deseninin bilmesi gerekir. Havuzu çağıran hizmet katmanının yalnızca hangi havuzu çağıracağını bilmesi gerekir.

Bu daha sonra çalışma düzeni birimi ile birleştirilebilir . Örneğin, örnekte, hizmet katmanı bir araba varlığını yüklemesi gerektiğini söyler, bir tür benzersiz tanımlayıcıya sahiptir ve bu tanımlayıcıyı depoya gönderir. Depo araç varlığını döndürür. Başka bir kod araç varlığını manipüle eder ve o varlığı kaydedilebilmesi için depoya geri gönderir.

Gerçekten dışarı çıkmak istiyorsanız, depo katmanı yalnızca ICarRepository gibi arabirimleri gösterecektir. Depo , hizmet katmanının ICarRepository arabirimini almak için kullanacağı bir fabrika içerecektir . Tüm veritabanı erişimi, birim testini çok daha kolay hale getiren bir arayüzün arkasına gizlenecektir.


C ++ 'da mevcut olmayan arayüzler hakkında son bit dışında tüm güzel (OP c ++ etiketlemek anlamına gelmediği sürece). QT ile kullanmak istediğim için C ++ 'da bir Havuz Kalıbı uygulamasını görmeyi çok merak ediyorum. Çevrimiçi kullanılabilir hiçbir şey olmadığını şaşırdım = [
johnildergleidisson

6

Veri erişimini kapsüllemek için Strateji Kalıbı'nı kullandım . Bu desen, ortak bir arayüzün arkasında kullandığınız depolama türünü gizlemenizi sağlar. Arayüzde, veri erişim yöntemlerinizi depolama türünü (dosya, veritabanı, web) dikkate almayarak tanımlayın. Ardından, mevcut depolama alanı seçiminiz için, strateji arayüzünü gerçekleştiren bir sınıfta veri erişim ayrıntılarını uygulayın. Bu şekilde uygulamanız kullandığınız veri kaynağını önemsemez.

Ayrıca, veri erişimini ve iş mantığını birlikte karıştırmak yerine uygulamaya özgü daha fazla ayrıntı tanımlamak için mevcut veri depolama stratejisi örneğini kullanan bir hizmet katmanı da oluşturabilirsiniz.


Her tür için bir erişim sınıfı mı yoksa herkes için büyük bir sınıf mı eklersiniz?
Will03uk

şahsen ben de vahşi benim sunucu / uygulama gelen her veri için açık döküm benimsenmesi düşünün.
user827992

+1 Bu modelin görünümünü seviyorum, ancak (projemin ölçeğinde), her algoritmayı bir veritabanı için ayrı ayrı yönetmek zor olacak; buna rağmen diğer uygulamalarda kesinlikle kullanacağım. Lambdas bunu iyi tamamlamalıdır.
Will03uk

1

Bu veritabanı Fabrika modeli örneğidir;

using System.Reflection;
using System.Configuration;

public sealed class DatabaseFactory
{
    public static DatabaseFactorySectionHandler sectionHandler = (DatabaseFactorySectionHandler)ConfigurationManager.GetSection("DatabaseFactoryConfiguration");

    private DatabaseFactory() { }

    public static Database CreateDatabase()
    {
        // Verify a DatabaseFactoryConfiguration line exists in the web.config.
        if (sectionHandler.Name.Length == 0)
        {
            throw new Exception("Database name not defined in DatabaseFactoryConfiguration section of web.config.");
        }

        try
        {
            // Find the class
            Type database = Type.GetType(sectionHandler.Name);

            // Get it's constructor
            ConstructorInfo constructor = database.GetConstructor(new Type[] { });

            // Invoke it's constructor, which returns an instance.
            Database createdObject = (Database)constructor.Invoke(null);

            // Initialize the connection string property for the database.
            createdObject.connectionString = sectionHandler.ConnectionString;

            // Pass back the instance as a Database
            return createdObject;
        }
        catch (Exception excep)
        {
            throw new Exception("Error instantiating database " + sectionHandler.Name + ". " + excep.Message);
        }
    }
}
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.