ฉันควร encapsulate การเข้าถึงฐานข้อมูลได้อย่างไร


10

ตัวอย่างของโครงสร้างชั้นดีที่ใช้ในการจัดการการเข้าถึงฐานข้อมูลคืออะไร ฉันเป็นแฟนตัวยงของคลาสแค็ปซูลและต้องการให้คอนเทนเนอร์ (เช่นรถยนต์) ไม่ทำงานฐานข้อมูล

ฉันต้องการความสามารถในการปล่อยสิ่งต่าง ๆ เช่นแคชฐานข้อมูลในอนาคตได้อย่างง่ายดาย

ฉันมักจะใช้รูปแบบของคลาสคอนเทนเนอร์พร้อมด้วย getters และ setters สำหรับการตรวจสอบความถูกต้องและการเข้าถึงฐานข้อมูลที่ดำเนินการโดยคลาส singleton เดียว ที่ถูกกล่าวว่านี้มักจะผสมระหว่างคนทั้งสองและกลายเป็นค่อนข้างสับสน

ขออภัยถ้าคำถามของฉันยากที่จะเข้าใจ ฉันไม่แน่ใจเกี่ยวกับคำศัพท์เกี่ยวกับฐานข้อมูลอย่างแน่นอน โปรดสอบถามหากจำเป็น


คุณได้พิจารณาใช้ ORM เพื่อเชื่อมโยงคลาสกับฐานข้อมูลเช่นWt :: Dboหรือไม่?
user52875

คำตอบ:


11

ฉันชอบรูปแบบพื้นที่เก็บข้อมูลเพื่อห่อหุ้มการเข้าถึงข้อมูล โดยย่อที่เก็บมีหน้าที่ในการโหลดข้อมูลทั้งหมดที่จำเป็นสำหรับวัตถุที่เฉพาะเจาะจง สมมติว่าคุณมีวัตถุรถยนต์เช่นในตัวอย่างของคุณ แต่คุณสมบัติทั้งหมดสำหรับรถยนต์ยี่ห้อรุ่นปีเจ้าของคุณสมบัติ (เครื่องเล่นซีดี 4wd ฯลฯ ) จะถูกเก็บไว้ในตารางต่าง ๆ ทั่วฐานข้อมูล พื้นที่เก็บข้อมูลกำหนดวิธีการโหลดและบันทึกข้อมูล หากต้องการเคียวรีขนาดเล็กจำนวนมากจำเป็นต้องใช้ แต่รูปแบบที่เก็บต้องรู้เท่านั้น เซอร์วิสเลเยอร์ที่เรียกใช้ที่เก็บต้องทราบว่าที่เก็บที่จะเรียกใช้เท่านั้น

ที่สามารถนำมารวมกับหน่วยของรูปแบบการทำงาน ดังนั้นในตัวอย่างของคุณเลเยอร์บริการจะบอกว่าจำเป็นต้องโหลดเอนทิตีของรถมันมีตัวระบุบางอย่างที่ไม่เหมือนใครและส่งตัวระบุนั้นไปยังที่เก็บ ที่เก็บส่งคืนเอนทิตีของรถยนต์ รหัสอื่น ๆ ใช้กับเอ็นเตอร์ไพรซ์รถยนต์และส่งเอนทิตีนั้นกลับไปยังที่เก็บเพื่อให้สามารถบันทึกได้

หากคุณต้องการออกไปข้างนอกจริงๆเลเยอร์ที่เก็บจะเปิดเผยเฉพาะอินเทอร์เฟซเช่น ICarRepository ที่เก็บจะมีโรงงานซึ่งชั้นบริการจะใช้เพื่อรับส่วนต่อประสาน ICarRepository การเข้าถึงฐานข้อมูลทั้งหมดจะถูกซ่อนอยู่หลังส่วนต่อประสานซึ่งทำให้การทดสอบหน่วยง่ายขึ้นมาก


ทั้งหมดดียกเว้นบิตสุดท้ายเกี่ยวกับอินเทอร์เฟซซึ่งไม่มีอยู่ใน c ++ (ยกเว้นว่า OP ไม่ได้หมายถึงการติดแท็ก c ++) ฉันอยากรู้มากว่าจะเห็นการใช้รูปแบบพื้นที่เก็บข้อมูลใน C ++ ตามที่ฉันต้องการใช้กับ QT ฉันประหลาดใจที่ไม่มีสิ่งใดที่สามารถใช้งานออนไลน์ได้ = [
johnildergleidisson

6

ฉันใช้รูปแบบกลยุทธ์เพื่อห่อหุ้มการเข้าถึงข้อมูล รูปแบบนี้ช่วยให้คุณสามารถซ่อนประเภทของที่เก็บข้อมูลที่คุณใช้อยู่หลังอินเทอร์เฟซทั่วไป ในอินเทอร์เฟซให้กำหนดวิธีการเข้าถึงข้อมูลของคุณโดยไม่สนใจประเภทของพื้นที่เก็บข้อมูล (ไฟล์ฐานข้อมูลเว็บ) จากนั้นสำหรับตัวเลือกที่เก็บข้อมูลปัจจุบันของคุณในชั้นเรียนเพื่อตระหนักถึงส่วนต่อประสานกลยุทธ์ให้ใช้รายละเอียดการเข้าถึงข้อมูล วิธีนี้แอปพลิเคชันของคุณไม่สนใจแหล่งข้อมูลที่คุณใช้

คุณยังสามารถสร้างเลเยอร์บริการที่ใช้อินสแตนซ์กลยุทธ์การจัดเก็บข้อมูลปัจจุบันเพื่อกำหนดรายละเอียดเฉพาะแอปพลิเคชันเพิ่มเติมแทนที่จะผสมผสานการเข้าถึงข้อมูลและตรรกะทางธุรกิจเข้าด้วยกัน


ดังนั้นคุณจะเพิ่มคลาสการเข้าถึงสำหรับแต่ละประเภทหรือคลาสใหญ่หนึ่งชั้นสำหรับทั้งหมดหรือไม่
Will03uk

โดยส่วนตัวแล้วฉันจะพิจารณาการยอมรับการส่งข้อมูลที่ชัดเจนสำหรับทุกข้อมูลที่มาจากเซิร์ฟเวอร์ไปยังเซิร์ฟเวอร์ / แอปพลิเคชันของฉัน
user827992

+1 ฉันชอบรูปแบบของรูปแบบนี้ แต่ฉันรู้สึกว่า (ในระดับโครงการของฉัน) การจัดการแต่ละอัลกอริทึมแยกต่างหากสำหรับฐานข้อมูลจะยาก แม้ว่าฉันจะใช้มันในแอปพลิเคชั่นอื่นอย่างแน่นอน แลมบ์ดาต้องทำให้ดีขึ้นด้วย
Will03uk

1

นี่คือตัวอย่างของรูปแบบโรงงานฐานข้อมูล

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);
        }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.