Refactoring 3 cyclic classes

I made a big change, trying to clarify what kind of help I am asking, and try to make the question suitable for Stack Overflow.

The problem in general: I have an existing library class that allows me to request information about the server. This class of library is widely used by a lot of obsolete software, so I am somewhat limited in the changes that I can make to it. Likewise, re-executing this better cannot be spent long enough.

The problem is specific: I created a simplified "toy" model of my approach below with 3 classes. The real thing is more complicated since there are polymorphic variations, more functionality, error handling, etc.

In the toy model code below, the Gateway is an existing library class. I tried to show how I would like to use it, with a result set and a way to access each member of the set. The idea is similar to what a well-implemented database API might look like, with an expression, result, and string — except in my case, what would be the instruction class forged due to poor design, which includes some of the functionality of the result.

The following toy example will not compile as-because of the following circular dependency. The Gateway class includes and depends on the ResultSet class because it returns a ResultSet object. The ResultSet class depends on the Member class, because it uses it to convert the data returned from the server into primitives (for example, a string). But the Member class refers to the Gateway class to access this data, and therefore there is a loop.

I want to find a solution that will provide the ResultSet and Member functions.

For a simpler class 2 task, I know a solution. This is the creation of a superclass from which one class (is-a) derives, and the other class consists of (has-a), so both original classes depend on the third, and everything is correct with the world. :-)

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;       -;

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

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

, , .h .cpp.

, Gateway ResultSet,

// Gateway.h
class ResultSet;    

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

ResultSet.

Gateway.cpp . , 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.

// 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 .

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

.

+1

All Articles