在这种情况下如何解耦

时间:2012-11-27 10:57:30

标签: c++ qt decouple

例如,以下代码片段执行以下操作:首先从数据库读取数据,然后转换数据,最后将结果写回数据库。更具体地说:

  1. 从数据库中读取数据并按记录存储到A类记录中。
  2. 转换存储在A类记录中的数据记录,B类做这项工作。
  3. 将所有结果存储在QVariantList中并批量写入数据库。
  4. 问题是A类,B类和ReadTransWrite类之间存在紧密关系 如果我想在A类中添加成员变量A4,则需要更改3个类。 请参阅评论以“// - >”

    开头

    如何解耦?会推荐任何模式吗?有什么建议吗?

    段:

    class A {
    public: 
        void trans(QSqlQuery query){
            A1 = query.record().field("A1").value().toString();
            A2 = query.record().field("A2").value().toDate();
            A3 = query.record().field("A3").value().toInt();
            //--> A4 = query.record().field("A4").value().toDouble();
        }
    public:
        QString A1;
        QDate A2;
        int A3;
        //--> double A4;
    };
    
    class B {
    public:
        void trans(const A& a){
            B1 = A1;
            B2 = A2;
            B3 = A3;
            //--> B4 = A4;
        }
    public:
        QString B1;
        QDate B2;
        int B3;
        //--> double B4;
    };
    
    class ReadTransWrite {
    .....
        void do();
    .....
    }
    
    void ReadTransWrite::do(){
        ....
        // prepare for batch insert into the database
        QVariantList B1s;
        QVariantList B2s;
        QVariantList B3s;
        //--> QVariantList B4s;
    
        A a;  // read record by record from data base
        B b;  // transform the results record by record
    
        QString sql_read = "select A1, A2, A3 from table0";
        //--> QString sql_read = "select A1, A2, A3, A4 from table0";
        QSqlQuery query_read;
        query_read.exec(sql_read);
        while(query_read.next()){
            a.trans(query_read);    // read record by record from data base
            b.trans(a);             // transform the results record by record
            B1s.push_back(b.B1);
            B2s.push_back(b.B2);
            B3s.push_back(b.B3);
            //--> B4s.push_back(b.B4);
        }
    
        QSqlQuery query_write;
        QString sql_write = "insert into table (B1, B2, B3) values (:B1, :B2, :B3)";
        //--> QString sql_write = "insert into table (B1, B2, B3, B4) values (:B1, :B2, :B3, :B4)";
        query_write.prepare(sql_write);
    
        query_write.bindValue(":B1",B1s);
        query_write.bindValue(":B2",B2s);
        query_write.bindValue(":B3",B3s);
        //--> query_write.bindValue(":B4",B4s);
    
        query_write.execBatch();
    }
    

1 个答案:

答案 0 :(得分:0)

你可以像这样制作A类:

#include <QtCore/QVariant>
#include <QtSql/QSqlRecord>

class A 
{
public: 
    void fillFromRecord( const QSqlRecord& record )
    {
        for( int iColumn = 0; iColumn < record.count(); iColumn++ )
        {
            _contentMap.insert( 
                record.fieldName( iColumn ), 
                record.value( iColumn )
                );
        }
    }

    inline QVariantMap getContentMap() const { return _contentMap; }

private:
    QVariantMap _contentMap;
};

注意:我没有测试编译错误的代码,但至少应该给你一个大致的想法。


这样,只要数据库发生变化,A类就永远不会改变。

另请注意,您可以如何要求QSqlRecord而不是QSqlQuery更多地参与评论中sehe链接的得墨忒耳定律。

您可以根据需要更改地图类型,例如QHash&lt; int,QVariant&gt;它只存储列索引而不是名称,并且不需要额外的QMap功能(基本上是排序)也可能就足够了。