zoukankan      html  css  js  c++  java
  • OO编程实践之“同步文件夹”——实现(1)

    标题写的是设计,其实这里应该是写测试。刚才开始很难写出测试来,因为传统编程思维的影响。如果是以前,这段代码也许很快就能写出个能用的版本。但现在我需要提高的我代码质量,不能永远停留在那个脚步。

    根据前面的需求,首先想到的是,我如何判断source中的文件比dest中的新。噢,我们只需比较最后的修改时间就行了。

    于是我写了关于修改时间的简单测试

        FileModifyTime source(std::time(NULL));
        FileModifyTime dest(std::time(NULL)-1000);
        CPPUNIT_ASSERT(source.isNewerThan(dest));
        CPPUNIT_ASSERT(!source.isNewerThan(source));
        CPPUNIT_ASSERT(!dest.isNewerThan(source));

      接着,我就写实现代码了。

        class FileModifyTime
        {
        public:
            FileModifyTime(time_t modifyTime) : itsModifyTime(modifyTime){}
            bool isNewerThan(const FileModifyTime& fi){ return itsModifyTime > fi.itsModifyTime;}
        private:
            time_t itsModifyTime;
        };

    运行测试,通过了。太简单了,离我实际应用太远了。

    对于第一次尝试TDD开发,我真不知道如何来写测试。考虑到测试一般而言,是给定一系列输入,然后查看输出是否与期望的相符合。在这个小程序中,我的输入是什么呢?我的输出又是什么呢?于是进入了漫长的思考中...

    考虑这个程序的核心作用在source中找出已经改动的文件或者文件夹,那么测试的输入应该是各种文件信息的输入,输出是应该是是否需要更新的bool值,于是测试代码大概是这样:

    Folder source("sourceFolder");
    Folder dest("destFolder");
    SynchronousSystem SS(&source,&dest);
    
    CPPUNIT_ASSERT(SS.isNeedUpdate("File1"));
    CPPUNIT_ASSERT(SS.isNeedUpdate("File2") == false);

    这一步可能跨度有点大,因为我需要写2个类。

    先写个空类能保持编译通过。

    class Folder
    {
    public:
        Folder(const std::string& path){}
    };
    class Folder;
    class SynchronousSystem
    {
    public:
        SynchronousSystem(Folder* source,Folder* dest){}
        bool isNeedUpdate(const std::string& filename)
        {
            return true;
        }
    };

    编译通过,但测试不通过。引文这里的我直接返回了true。为了使其通过测试,我修改了isNeedUpdate函数

        bool isNeedUpdate(const std::string& filename)
        {
            if(filename == "File1")
                return true;
            else
                return false;
        }

    测试通过了,但isNeedUpdate的作用应该是判断文件修改时间,这个需要从source和dest中读取文件信息,于是继续编写测试代码:

        Folder source("sourceFolder");
        Folder dest("destFolder");
    
        CPPUNIT_ASSERT(source.getFileModifyTime("File1").isNewerThan(dest.getFileModifyTime("File1"));
        CPPUNIT_ASSERT(source.getFileModifyTime("File2").isNewerThan(dest.getFileModifyTime("File2") == false);

    于是在Folder中需要增加成员函数getFileModifyTime

        FileModifyTime getFileModifyTime(const std::string& filename)
        {
            return FileModifyTime(std::time(NULL));
        }

    为了使测试通过,我们需要在Folder中做一些工作。

    class Folder
    {
    public:
        Folder(const std::string& path):itsPath(path){}
        FileModifyTime getFileModifyTime(const std::string& filename)
        {
            if (filename == "File1" && itsPath == "destFolder")
                return FileModifyTime(std::time(NULL)-1000);
            if (filename == "File2" && itsPath == "sourceFolder")
                return FileModifyTime(std::time(NULL)-1000);
            return FileModifyTime(std::time(NULL));
        }
    private:
        std::string itsPath;
    };

    这样所有测试都通过了,再回过头来看SynchronousSystem,它的isNeedUpdate函数应该调用Folder看查询文件的修改时间,类SynchronousSystem修改为

    class SynchronousSystem
    {
    public:
        SynchronousSystem(Folder* source,Folder* dest):itsSourceFolder(source),itsDestFolder(dest){}
        bool isNeedUpdate(const std::string& filename)
        {
            return itsSourceFolder->getFileModifyTime(filename).isNewerThan(itsDestFolder->getFileModifyTime(filename));
        }
    private:
        Folder* itsSourceFolder;
        Folder* itsDestFolder;
    };

    一切很好,所有测试都通过了。

    这样看来,一个功能1差不多完成了,考虑功能2的情况,如果dest中的文件不存在,那么isNeedUpdate中应该返回true。测试代码:

        Folder source("sourceFolder");
        Folder dest("destFolder");
        SynchronousSystem SS(&source,&dest);
        CPPUNIT_ASSERT(SS.isNeedUpdate("FileNotExist"));

    测试不通过,我们更新isNeedUpdate函数

        bool isNeedUpdate(const std::string& filename)
        {
            if(!itsDestFolder->isExist(filename))
                return true;
            return itsSourceFolder->getFileModifyTime(filename).isNewerThan(itsDestFolder->getFileModifyTime(filename));
        }

    类Folder中增加

        bool isExist(const std::string& filename)
        {
            if(filename == "FileNotExist")
                return false;
            else
                return true;
        }

    测试通过了。

  • 相关阅读:
    存储过程语法二
    存储过程语法一
    存储过程的优点
    .NET中Redis安装部署及使用方法简介
    UEditor富文本web编辑器
    未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService
    comet 推送消息到客户端
    文本框 只能输入数字和小数点验证
    asp.net Cache
    Windows10放开Administrator权限
  • 原文地址:https://www.cnblogs.com/zhangyonghugo/p/2568608.html
Copyright © 2011-2022 走看看