• 最近三周开发的桌面应用系统


    前三周开发了一个桌面应用系统。

    本来是不想参与这个小项目,因为这是个典型的“内部使用”一次性软件;需求说不清、也难以理清;麻雀虽小五脏俱全,有数据库存取、系统间导入导出、复杂的界面功能、很可能不断变化的业务功能;只有一点很明确:要求截止到3月15日开发完成,也就是最多三周!

    在即将正式开发时,经过多次激烈讨论,要做哪些功能总算弄清楚了,但功能究竟具体是什么样还比较模糊。系统技术方案和编程语言方案了反复改了几次,至少有三次非常大的改变,可以说是由谁主负责就有几个差别很大的解决方案。最后是我参与到该项目的设计编码中(总共2个开发人员),由于我不想让从我出手的软件开发成为垃圾软件,所以变成了由我绝对控制、主力实现的形式。

    虽然只有三周开发时间,但还是取得了明显的成绩:系统架构比去年软件更精巧完善、增加了两个通用性很强的插件模块、代码结构也较好。其开发合作方式也值得一提:我负责框架设计和实现,另一个同事负责业务功能的实现。

    image

    图1  系统基于插件框架构建

    image

    图2 系统分层架构

    image

    图3 应用外壳层

    image

    图4 内容视图层

    image

    图5 业务逻辑层

    image

    图6 对话框界面层

    image

    图7 数据层

    image

    图8 改变通知观察机制(ChangeObserver)

    新开发了一个通用应用程序内核模块AppUICore,基于该模块的应用程序代码可减少到50行内、只需要一个类。该模块同时实现了交互式界面布局机制、界面布局与界面内容实现分离。下面是AppUICore的工作流程:

    image

    图9 程序启动流程

    image

    图10 程序退出流程

    最为数据访问代理机制(DataAgent),在本项目中新开发出了数据库访问代理插件,可以按照以前XML访问那样的简化方式操作数据库,这样应用开发程序员就可以不关心数据库或XML实现细节,只需要关心如何操作逻辑数据。例如:

    Cx_Ptr TestConfigDB::OpenDatabase()
    {
        Cx_Interface<Ix_ConfigDBFactory> pIFFactory(CLSID_ConfigDBFactory);
        CPPUNIT_ASSERT(pIFFactory.IsNotNull());

        return pIFFactory->OpenAccessDB(m_wstrDbFile);
    }

    void TestConfigDB::testAddRecord()
    {
        Cx_Interface<Ix_ConfigData> pIFDatabase(OpenDatabase());
        CPPUNIT_ASSERT(pIFDatabase.IsNotNull());

        CConfigIOSection secRec(pIFDatabase->AddSection(NULL, L"book"));

        secRec->SetUInt32(L"id", 2);
        secRec->SetString(L"title", L"test1");
    }

    void TestConfigDB::testSelectSQL()
    {
        Cx_Interface<Ix_ConfigData> pIFDatabase(OpenDatabase());
        CPPUNIT_ASSERT(pIFDatabase.IsNotNull());

        CConfigIOSection secRecordset(pIFDatabase->GetSection(
            L"SELECT id,title FROM article WHERE id=4"));

        for (long iRec = 0; iRec < 99; iRec++)
        {
            CConfigIOSection secRec(secRecordset.GetSectionByIndex(L"", iRec));
            if (!secRec->IsValid())
                break;

            ULONG nID = secRec->GetUInt32(L"id");
            std::wstring wstrName = secRec->GetString(L"title");

            CPPUNIT_ASSERT(nID == 4);
        }
    }

    void TestConfigDB::testEditRecord()
    {
        Cx_Interface<Ix_ConfigData> pIFDatabase(OpenDatabase());
        CPPUNIT_ASSERT(pIFDatabase.IsNotNull());

        CConfigIOSection secRecordset(pIFDatabase->GetSection(NULL, L"book", L"id", 1));
        CConfigIOSection secRec(secRecordset.GetSectionByIndex(L"", 0));

        CPPUNIT_ASSERT_EQUAL(1L, secRecordset.GetSectionCount(L""));

        secRec->SetString(L"title", L"test3");
    }

  • 相关阅读:
    【2018.10.3】万圣节的快递
    【2018.10.3】万圣节的入场券
    【2018.10.2】纸条
    【2018.10.2】菌落合并
    【2018.10.2】Note of CXM
    【2018.10.1】【JSOI2016】最佳团体(bzoj4753)
    【2018.10.1】「JOI 2014 Final」年轮蛋糕
    【2018.9.26】K-D Tree详解
    Python中的numpy模块解析
    Python中xlrd模块解析
  • 原文地址:https://www.cnblogs.com/rhcad/p/1692232.html
Copyright © 2020-2023  润新知