首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编程范例;想知道是否需要重写/重构

编程范例;想知道是否需要重写/重构
EN

Stack Overflow用户
提问于 2012-11-15 11:28:03
回答 3查看 662关注 0票数 10

相当一段时间以来,我一直在处理一个应用程序。因为编程只是一种爱好,这个项目已经花了很长时间,但这不是重点。我现在正处在这样一个时刻,每一个“问题”都变得非常难以解决。我正在考虑重构代码,但是这会导致“完全”重写。

让我解释一下这个问题,以及我目前是如何解决的。基本上我有数据,我让事情发生在这些数据上(嗯,我描述了每个程序,不是吗?)所发生的是:

数据->要求查看器显示->查看器根据实际数据查看器显示数据,返回用户输入->数据->要求“执行器”执行它->新数据。

现在这个方法很好用,我最初的想法是“嘿,我可以通过qt或windows更改命令提示符--甚至接受外部命令提示符(C#),只需调用这个程序”。

然而,随着这个项目的发展,它变得越来越令人厌烦。最重要的是,数据以不同的方式显示,这取决于数据是什么和-more (重要的是数据所在的位置)。因此,我回到树中,添加了某种方式来“跟踪”父行是什么“,然后普通查看器将搜索最具体的实际小部件,它使用带有位置的列表;小部件值,并找到最佳匹配的位置。

当更新新的“数据”时,问题就开始了--我必须检查所有的资产--查看器、保存程序等等。更新检查机制给我带来了很多错误。比如“嘿,为什么它现在又显示错了小部件?”

现在我可以完全交换这个了。而不是调用通用查看器的树数据结构。我会使用OO“内部”树功能。节点将是childs (&当需要一个新的查看器或保存机制时,将形成一个新的子节点)。

这将消除困难的检查机制,在这里我检查树中的位置。然而,它可能会打开另一罐蠕虫。我想对此发表评论吗?我是否应该将查看器保持完全独立--在检查数据时有困难?或者说新的方法更好,但是它将数据和执行结合到一个节点中。(因此,如果我想从qt改为cli/C#,这几乎是不可能的)

最后我应该采取什么方法呢?还有什么我能做的吗?为了使查看器保持独立,但又不需要进行检查来查看应该显示哪些小部件?

编辑,只是为了显示一些“代码”和我的程序如何工作。不确定这是否有任何好处,正如我已经说过的,它已经变成了一堆方法。

它的目的是将多个“游戏制造者项目”合并在一起(因为通用汽车:工作室奇怪地缺乏这一功能)。游戏制造者项目文件只是一组xml文件。(主xml文件仅包含指向其他xml文件的链接,并为每个资源-object、雪碧、声音、空间等提供一个xml文件)。然而,也有一些“怪癖”使得无法真正使用诸如boost属性树或qt: 1)属性/子节点的顺序在文件的某些部分读取是非常重要的。2)空白常常被忽略,但在其他方面,保持空白是非常重要的。

尽管如此,也有许多节点完全相同的点。比如背景可以有<width>200</width>,房间也可以有。然而,对于用户来说,他谈论的宽度是相当重要的。

无论如何,“普通查看器”(AskGUIFn)有以下类型来处理这个问题:

代码语言:javascript
运行
复制
    typedef int (AskGUIFn::*MemberFn)(const GMProject::pTree& tOut, const GMProject::pTree& tIn, int) const;
    typedef std::vector<std::pair<boost::regex, MemberFn> > DisplaySubMap_Ty;
    typedef std::map<RESOURCE_TYPES, std::pair<DisplaySubMap_Ty, MemberFn> > DisplayMap_Ty;

其中"GMProject::pTree“是一个树节点,RESOURCE_TYPES是一个常数,用于跟踪我目前所处的资源类型(精灵、对象等)。在这里,"memberFn“只是加载一个小部件的东西。(当然,AskGUIFn不是唯一的普通查看器,但只有当其他“自动”-overwrite、skip、重命名处理程序失败时,才会打开这个查看器)。

现在,要显示这些映射是如何初始化的(名称空间"MW“中的所有内容都是qt小部件):

代码语言:javascript
运行
复制
AskGUIFn::DisplayMap_Ty AskGUIFn::DisplayFunctionMap_INIT() {
    DisplayMap_Ty t;
        DisplaySubMap_Ty tmp;

        tmp.push_back(std::pair<boost::regex, AskGUIFn::MemberFn> (boost::regex("^instances "), &AskGUIFn::ExecuteFn<MW::RoomInstanceDialog>));
        tmp.push_back(std::pair<boost::regex, AskGUIFn::MemberFn> (boost::regex("^code $"), &AskGUIFn::ExecuteFn<MW::RoomStringDialog>));
        tmp.push_back(std::pair<boost::regex, AskGUIFn::MemberFn> (boost::regex("^(isometric|persistent|showcolour|enableViews|clearViewBackground) $"), &AskGUIFn::ExecuteFn<MW::ResourceBoolDialog>));
        //etc etc etc
    t[RT_ROOM] = std::pair<DisplaySubMap_Ty, MemberFn> (tmp, &AskGUIFn::ExecuteFn<MW::RoomStdDialog>);

        tmp.clear();
        //repeat above
    t[RT_SPRITE] = std::pair<DisplaySubMap_Ty, MemberFn>(tmp, &AskGUIFn::ExecuteFn<MW::RoomStdDialog>);
    //for each resource type.

然后,当树数据结构告诉普通查看器希望显示它时,查看器执行以下函数:

代码语言:javascript
运行
复制
AskGUIFn::MemberFn AskGUIFn::FindFirstMatch() const {
    auto map_loc(DisplayFunctionMap.find(res_type));
    if (map_loc != DisplayFunctionMap.end()) {
        std::string stack(CallStackSerialize());
        for (auto iter(map_loc->second.first.begin()); iter != map_loc->second.first.end(); ++iter) {
            if (boost::regex_search(stack, iter->first)) {
                return iter->second;
            }
        }
        return map_loc->second.second;
    }

    return BackupScreen;
}

和这是问题开始坦率的地方。CallStackSerialize()函数依赖于调用堆栈。但是,call_stack存储在“处理程序”中。我把它储存在那里,因为一切都是从处理程序开始的。我不太确定我该把这个"call_stack“放在哪里。引入另一个对象来跟踪发生了什么?我试着用节点本身存储父节点的路由。(防止需要调用堆栈)。然而,这并不如我所愿:每个节点都有一个包含其子节点的向量。所以使用指针是不可能指向父母笔记的..。(PS:也许我应该在另一个问题上改革这个问题。)

EN

回答 3

Stack Overflow用户

发布于 2012-11-16 14:36:07

欢迎来到编程世界!

您所描述的是应用程序的典型生命周期,从一个小的简单应用程序开始,然后它得到越来越多的特性,直到它不再可维护。你无法想象我在最后一个崩溃阶段看到了多少项目!

你需要重构吗?你当然知道!一直!你需要重写所有东西吗?不太确定。

事实上,好的解决方案是按周期工作:你设计你需要的代码,编码它,你需要更多的功能,你设计这个新的功能,你重构代码以便你可以集成新的代码,等等。如果你不这样做的话,你就会达到这样的程度,重写然后重构的代价会更低。拿到这本书:重构-马丁·福勒。如果你喜欢的话,那就拿这个:重构到模式。

票数 1
EN

Stack Overflow用户

发布于 2012-11-21 23:49:08

正如Pedro NF所说,Martin “重构”是熟悉它的好地方。

票数 0
EN

Stack Overflow用户

发布于 2012-11-22 00:36:20

我建议购买Robert“C#中的敏捷原则、模式和实践”的副本,他介绍了一些非常实用的案例研究,展示了如何克服这样的维护问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13396589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档