2016-03-20 23 views
0

erişimcileri. Temel veriler, değerin bir sendika tipi olduğu bir haritada tutulur. o /I veritabanı satırları erişim sağlayan sınıfları içeren bir kütüphane tasarlıyorum

  • özelliklerini
  • için erişimcilere sağlamak erişmesi gereken sütunlar için özellik eşlemesi eklemek

    class dbObject 
    { 
        protected: 
        // Get and set property values using generic name for property 
        union_type GetPropertyValue(string property_name); 
        void SetPropertyValue(string property_name, union_type value); 
    
        // Add mapping from generic property name to column name 
        void AddPropertyMapping(string property_name, string column_name); 
    
        private: 
        map<property_name, column_name> 
        map<column_name, union_type> 
    }; 
    

    dbObject devralır Her sınıf gerekecektir

    • için: Aşağıdaki temel sınıf düşünün

    kütüphane kullanıcıya sunulan nihai arayüz sınıfı uygun erişimcileri vardır ve altta yatan yapı/uygulanmasını gizler diye. Buradaki motivasyon, sınıfların çoğunun aynı verinin büyük bir yüzdesini paylaşmasıdır. Bu nedenle, her bir sınıf için ayrı ayrı yazmak yerine, erişim sağlayıcılarını ve kurulum kodunu eşleştirmelerini istiyoruz. Başlangıçta ben paylaşılan erişimci bazı kümesi içeren her türetilmiş sınıfları yapılandırarak edildi, örn: Gördüğünüz gibi

    class dbDerivedObjectOne : dbObject 
    { 
        public: 
        int GetPropertyOne(); 
        void SetPropertyOne(int value); 
        string GetPropertyTwo(); 
        void SetPropertyTwo(string value); 
    }; 
    
    class dbDerivedObjectTwo : dbDerivedObjectOne 
    { 
        public: 
        double GetPropertyThree(); 
        void SetPropertyThree(double value); 
        int GetPropertyFour(); 
        void SetPropertyFour(int value); 
    }; 
    
    // This is the API class which is presented to the library user 
    // It has inherited all the necessary accessors and setup code 
    class dbInterfaceClass : dbDerivedObjectTwo 
    { 
    }; 
    

    , bu hiyerarşi böylece yaprak/arabirim sınıfı erişimcileri dayalı olduğunu" yerine gerçek daha ihtiyacı -a doğru tasarımda görmeyi beklediğiniz ilişki. Bazı sınıf Zaten bir üst sınıfta maruz özelliklerin bazı alt erişmesi gerektiği, ama bazıları türetilmiş sınıf için varolmayan/anlamsız çünkü üst sınıf özelliklerini tüm maruz istemiyor sayede Ayrıca sorunlara yol var. , Şu anda tek bir özellik sınıfa türetilmiş sınıfları ayırır ve arabirim sınıfları oluşturmak için birden çok devralma kullanımı kapsamaktadır Refactor doğru eğilim referans için bilinen bir tasarım modeli olmadan

    .

    class dbObjectProperty 
    { 
        union_type GetProperty(string property_name) 
        void SetProperty(string property_name, union_type value) 
    }; 
    
    class dbPropertyOne : dbObjectProperty 
    { 
        // calls dbObjectProperty::GetProperty() with its property name 
        // returns the int from the union_type 
        int GetPropertyOne(); 
    
        // wraps the int in a union_type 
        // calls dbObjectProperty::SetProperty() with its property name 
        int SetPropertyOne(int value); 
    }; 
    
    class dbPropertyTwo : dbObjectProperty 
    { 
        // calls dbObjectProperty::GetProperty() with its property name 
        // returns the string from the union_type 
        string GetPropertyTwo(); 
    
        // wraps the string in a union_type 
        // calls dbObjectProperty::SetProperty() with its property name 
        void SetPropertyTwo(string value); 
    }; 
    
    class InterfaceClassOne : dbPropertyOne, dbPropertyTwo 
    { 
        // exposes all of the accessors from its parent classes 
    } 
    

    Bu çözelti çok daha ayrıntılı ve beni her biri kendi erişimci/mutator sağlar (potansiyel olarak ortak) bir dizi özellik ile her bir arayüz sınıf oluşturmak için olanak sağlar. Bununla birlikte, fiili uygulama, 25-30 farklı mülk sınıfından miras alan, korkutucu bir çoklu miras tasarımı gibi görünen sınıfları içerecektir. Ayrıca, bu miras kavramının kötüye kullanılması gibi görünüyor. arayüz sınıfları gerçekten oldukça onlar aslında bir koleksiyon konum ve biz bize erişimci kod çoğaltma önlemek için izin çoklu kalıtım olmana gerek yok, dbObjectProperty ile ilişkisi "Bir olan" uymaz.

    Sorular:

    1. ben bakıyor olmalıdır yapının bu tür bir tesis tasarım deseni var mı?
    2. erişimci kod tekrarı önlemek kaydıyla bu sorunu çözmek için başka/daha iyi bir yolu var mı?
    3. Birden fazla kalıtım çözümü, kötü/tehlikeli tasarımını mı düşündüğümde, ya da C++ sisteminin doğası beni daha az katı bir dilde daha kolay olacak bir şey elde etmek için sistemi kötüye kullanmaya zorluyor mu?

    cevap

    1

    Bu yüzden, anladığım kadarıyla yazarak bir şeyler yazmaya çalışıyorum. Makro öneririm ama bu konuda uzman değilim;), hatta çalışıp çalışmadıklarını bile bilmiyorum (bakmaya değer olabilir).

    ben başka bir çözüm buldunuz, burada basitleştirilmiş bir örnektir (vC++) var:

    template<typename T> 
    class Property { 
    private: 
        std::map<std::string, union_type>& map_ref; 
        const std::string name; 
    public: 
        Property(std::map<std::string, union_type>& my_map, std::string&& name) : map_ref(my_map), name(name) {} 
    
        T Get() const { 
         return static_cast<T>(map_ref[name]); 
        } 
    
        void Set(T new_value) const { 
         map_ref[name] = static_cast<union_type>(new_value); 
        } 
    }; 
    
    class MyObject { 
    private: 
        std::map<std::string, union_type> my_map; 
    public: 
        const Property<int> my_int{ my_map, "my_int" }; 
    }; 
    

    başkalarına senin union_type gitmek nasıl Özellikle bilmiyorum, bu yüzden statik atmalarını nereye buradan temsil etti. Bunun alt tarafı, almanın ve ayarlamanın biraz daha fazla çaba göstermesidir. my_object.my_int.Get(). Yine de, her çalışmacının ve ayarlayıcının yazmasına gerek kalmadan, size biraz iş kazandırmak gerekir.

    Bu başaşağı, (Ki, imho ... güzel) hala yerine vb sadece PropertyOne, PropertyTwo ait fiili özellik adını kullanarak erişebilir olması

    +0

    net olmak gerekirse, ben Sadece yazarak çalışmam için kendimi kurtarmaya çalışmıyorum, değiştirmek veya yeni özellikler eklemek gerektiğinde çok fazla bakım/uzatma baş ağrısından kaçınmaya çalışıyorum. "Çap" özelliği için erişim işlevini değiştirmek, 25 farklı sınıfta çoğaltıldığında bir kabus. Bu söyleniyor, bu bir çözüm kışkırtıcı bir çözümdür ve templated bir sınıf kullanmayı düşünmemiştim (geçmişe bakılırsa açık bir seçenek gibi görünüyor). Öneri için teşekkürler, cevap olarak işaretlemeden önce daha fazla cevap olup olmadığını görmek için biraz bekleyeceğim. – NAW

    +0

    Yeterli bir çözüm sunmazsam, kendi cevabınızı da gönderebilirsiniz. Bu, daha sonra bu soruyu arayan insanlara yardımcı olabilir. –