Pertanyaan Pemuatan malas - apa pendekatan terbaik?


Saya telah melihat banyak contoh pemuatan malas - apa pilihan Anda?

Mengingat kelas model misalnya:

public class Person
{
    private IList<Child> _children;
    public IList<Child> Children
    {
        get {
            if (_children == null)
                LoadChildren();
            return _children;
        }
    }
}

Kelas Orang seharusnya tidak tahu apa-apa tentang bagaimana anak-anak dimuat ... atau haruskah itu? Tentunya harus mengontrol ketika properti dihuni, atau tidak?

Apakah Anda memiliki repositori yang memadukan Orang dengan koleksi anak-anaknya atau apakah Anda akan menggunakan pendekatan yang berbeda, seperti menggunakan a lazyload kelas - bahkan saat itu, saya tidak ingin kelas malas membaur dalam arsitektur model saya.

Bagaimana Anda akan menangani kinerja jika pertama meminta Orang dan kemudian Anak-anaknya (yaitu tidak malas memuat dalam hal ini) atau bermalas-malasan dengan cara apa pun.

Apakah semua ini menjadi pilihan pribadi?


14
2018-02-07 16:33


asal


Jawaban:


Pemuatan malas terbaik adalah menghindarinya;) Keamanan benang adalah masalah langsung yang harus Anda tangani. Saya tidak memiliki hitungan seberapa sering saya melihat sistem produksi dengan 8 core cpu yang menjalankan pemuatan malas 8 kali setiap pola pemuatan malas digunakan. Setidaknya pada startup server semua core server memiliki kecenderungan untuk berakhir di tempat yang sama.

Biarkan kerangka DI membangunnya untuk Anda, jika memungkinkan. Dan jika Anda tidak bisa, saya masih lebih suka konstruksi eksplisit. Jadi semua jenis sihir AOP tidak memotongnya dengan saya, pergi untuk konstruksi eksplisit di luar kelas. Jangan memasukkannya ke dalam kelas orang, buatlah layanan yang membangun objek dengan cara yang tepat.

Memperkenalkan lapisan "ajaib" yang lebih atau kurang transparan melakukan hal-hal ini terlihat seperti ide yang bagus, tetapi saya belum menemukan implementasi yang tidak memiliki konsekuensi yang tidak perlu dan bermasalah.


14
2018-02-07 16:47



Anda dapat menggunakan Lazy<T> kelas yang saya bicarakan di sini: Apa cara yang tepat untuk menyuntikkan ketergantungan akses data untuk pemuatan malas?

Ada juga tautan ke posting blog yang lebih detail di sana ...


4
2018-02-07 17:14



Saya berbicara tentang solusi yang saya gunakan untuk menyelesaikan pemuatan malas sini


1
2018-02-07 17:01



Anda dapat menggunakan Proxy Virtual pola, bersama dengan Pola pengamat. Ini akan memberi Anda pemuatan malas tanpa kelas Orang yang memiliki pengetahuan eksplisit tentang bagaimana Anak-anak dimuat.


1
2018-02-07 17:35



Saya berpikir bahwa ini tepat jenis masalah yang paling baik ditangani oleh AOP (mis., PostSharp). Muat pemuatan malas Anda sebagai suatu aspek dan kemudian gunakan untuk menghias properti apa pun yang Anda inginkan untuk dimuat dengan malas. Penafian: belum mencobanya; hanya memikirkan itu harus kerja.


0
2018-02-07 16:39



Saya baru saja mengajukan pertanyaan terkait sini, tapi itu lebih berat pada taktik Immutability & Thread Safety. Banyak jawaban dan komentar yang bagus. Anda mungkin merasa itu berguna.


0
2018-03-18 02:56



Berikut ini contoh penerapan pemuatan malas menggunakan pola Proxy

Kelas Orang yang akan tinggal dengan sisa model Anda. Anak-anak ditandai sebagai virtual sehingga dapat dikesampingkan di dalam kelas PersonProxy.

public class Person {
    public int Id;
    public virtual IList<Child> Children { get; set; }
}

Kelas PersonRepository yang akan hidup dengan sisa repositori Anda. Saya menyertakan metode untuk mendapatkan anak-anak di kelas ini tetapi Anda dapat memilikinya di kelas ChildRepository jika Anda menginginkannya.

public class PersonRepository {
    public Person FindById(int id) {
        // Notice we are creating PersonProxy and not Person
        Person person = new PersonProxy();

        // Set person properties based on data from the database

        return person;
    }

    public IList<Child> GetChildrenForPerson(int personId) {
        // Return your list of children from the database
    }
}

Kelas PersonProxy yang hidup dengan repositori Anda. Ini mewarisi dari Orang dan akan melakukan pemuatan malas. Anda juga bisa menggunakan boolean untuk memeriksa apakah sudah dimuat alih-alih memeriksa untuk melihat apakah Children == null.

public class PersonProxy : Person {
    private PersonRepository _personRepository = new PersonRepository();

    public override IList<Child> Children {
        get {
            if (base.Children == null)
                base.Children = _personRepository.GetChildrenForPerson(this.Id);

            return base.Children;
        }
        set { base.Children = value; }
    }
}

Anda bisa menggunakannya seperti itu

Person person = new PersonRepository().FindById(1);
Console.WriteLine(person.Children.Count);

Tentu saja Anda bisa memiliki PersonProxy mengambil antarmuka ke PersonRepository dan mengaksesnya melalui layanan jika Anda tidak ingin memanggil PersonRepository secara langsung.


0
2018-01-31 02:01