jjzjj

c++ - 重构 3 个循环类

coder 2024-02-25 原文

我做了很大的修改,试图阐明我正在寻求什么帮助,并尝试使问题适合 Stack Overflow。

一般问题:我有一个现有的库类,它允许我查询服务器以获取信息。该库类被大量遗留软件广泛使用,因此我可以对其进行的更改有些受限。同样,以更好的方式重新实现它可能不值得花时间。

具体问题:我在下面使用 3 个类创建了我的方法的简化“玩具”模型。实际情况要复杂得多,因为存在多态变体、更多功能、错误处理等。

在下面包含的“玩具”模型代码中,Gateway 是现有的库类。我试图展示我想如何使用它,包括一个结果集和一种访问该结果集每个成员的方法。这个想法类似于一个实现良好的数据库 API 的外观,带有语句、结果和行——除了在我的例子中,语句类会被包含部分结果功能的糟糕设计所阻碍。

由于以下循环依赖性,下面的玩具示例将不会按原样编译。 Gateway 类包括 ResultSet 类并依赖于它,因为它返回一个 ResultSet 对象。 ResultSet 类依赖于 Member 类,因为它使用它将服务器返回的数据转换为原语(例如字符串)。但是 Member 类返回到 Gateway 类来访问该数据,因此存在一个循环。

我想找到一个可以提供ResultSetMember 功能的解决方案。

对于更简单的 2 类问题,我知道一个解决方案。它是创建一个父类(super class),其中一个类派生自 (is-a),而另一个类由 (has-a) 组成,这样两个原始类都依赖于第三个类,并且世界上一切都是正确的。 :-)

对于我的 3 类问题,出于某种原因,我无法全神贯注于如何重构它以使其工作。

// Gateway.h
#include "ResultSet.h"
class Gateway {
    ResultSet exec(string params);
};
// Gateway.cpp
ResultSet Gateway::exec(string p) { ... }

// ResultSet.h
#include "Member.h"
class ResultSet {
    ResultSet();    // ctor
    int     index;
    bool    next();
    string  getCurrent(Member member);
};
// ResultSet.cpp
ResultSet::ResultSet() { index = 0; }
bool    ResultSet::next() { ++index < length; }
string  ResultSet::getCurrent(Member member) { member.fetch(index) }

// Member.h
#include "Gateway.h"
class Member {
    Gateway gateway;
    string  fetch(int i);
};
// Member.cpp
string Member::fetch(int i) { return gateway.sGet(i); }

//最终 API 的期望用法示例。 主要的() { 网关; ResultSet集合; 成员(member)成员(member);

    set = gate.exec("...");

    while (set.next()) {
        cout << set.getCurrent(member) << endl;
    }
}

最佳答案

您的问题的解决方案是在头文件中转发声明重叠的类,然后从您的 .cpp 实现文件中包含它们的实际 .h 文件。

例如,为了避开GatewayResultSet的依赖,

// Gateway.h
class ResultSet;    

class Gateway {
    ResultSet exec(string params);
};

此转发声明类 ResultSet

现在在 Gateway.cpp 中,我们必须向编译器提供实际的接口(interface)。所以现在我们包含 ResultSet.h

// Gateway.cpp
#include "ResultSet.h"

ResultSet Gateway::exec(string p) { ... }

我们为您的其他循环关系执行此操作,然后您将拥有可以编译和构建的源代码。

对于ResultSet,我们将转发声明Member

// ResultSet.h
class Member;

class ResultSet {
    ResultSet();    // ctor
    int     index;
    bool    next();
    string  getCurrent(Member member);
};

在其实现文件中,我们最终将包含Member 的 header 。

// ResultSet.cpp
#include "Member.h"

ResultSet::ResultSet() { index = 0; }
bool    ResultSet::next() { ++index < length; }
string  ResultSet::getCurrent(Member member) { member.fetch(index) }

最后,Member...

// Member.h
class Gateway;

class Member {
    Gateway gateway;
    string  fetch(int i);
};

当然,Member.cpp 必须包含 Gateway 的信息。

// Member.cpp
#include "Gateway.h"
string Member::fetch(int i) { return gateway.sGet(i); }

现在没有循环依赖。

关于c++ - 重构 3 个循环类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28373973/

有关c++ - 重构 3 个循环类的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - 如何重构 "shared"方法? - 2

    我正在使用RubyonRails3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),这些方法实际上是相同的;所以我认为DRY方法是将这些方法放在“共享”模块或类似的东西中。实现该目标的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?注意:我正在寻找“RubyonRails制作东西的方式”。 最佳答案 一种流行的方法是使用ActiveSupport关注点

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby-on-rails - 在 haml View 中重构条件 - 2

    除了可访问性标准不鼓励使用这一事实指向当前页面的链接,我应该怎么做重构以下View代码?#navigation%ul.tabbed-ifcurrent_page?(new_profile_path)%li{:class=>"current_page_item"}=link_tot("new_profile"),new_profile_path-else%li=link_tot("new_profile"),new_profile_path-ifcurrent_page?(profiles_path)%li{:class=>"current_page_item"}=link_tot("p

  9. ruby - Ruby 中的闭包和 for 循环 - 2

    我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对

  10. ruby - 需要重构为新的 Ruby 1.9 哈希语法 - 2

    这个问题在这里已经有了答案:HashsyntaxinRuby[duplicate](1个回答)关闭5年前。我有一个Recipe,其中包含以下未通过lint测试的代码:service'apache'dosupports:status=>true,:restart=>true,:reload=>trueend失败并出现错误:UsethenewRuby1.9hashsyntax.supports:status=>true,:restart=>true,:reload=>true不确定新语法是什么样的...有人可以帮忙吗?

随机推荐