 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Bill Pierce Guest
|
Posted: Fri Sep 17, 2004 10:47 am Post subject: How to split an extremely large class? |
|
|
I recently inherited maintenance of a library that contains, among other
things, a class with nearly 1500 member functions. As a first step, I'd
like to split it in two obvious new classes. The problem is that there is
several programs in production that use this library that I can't break.
Conceptually, here's what I have:
class HugeMama : public LoLevelClass
{
public:
void Type1Function001( ... );
o
o
o
void Type1Function800( ... );
char data_array[10];
void Type2Function001( ... );
o
o
o
void Type2Function700( ... );
}
Class LoLevelClass has no data members. "data_array" is used only by Type1
functions. This is what I'm thinking of doing:
class Type1Class : public LoLevelClass
{
public:
void Type1Function001( ... );
o
o
o
void Type1Function800( ... );
char data_array[10];
}
class Type2Class : public LoLevelClass
{
public:
void Type2Function001( ... );
o
o
o
void Type2Function700( ... );
}
class HugeMama : public Type1Class, public Type2Class
{
}
New programs can use the new classes and existing programs will still
compile using class HugeMama until we can switch them over to the 2 new
classes. Obviously, a class with 800 member functions is still too big. This
is just a first step. I concerned over using multiple inheritance, even if
it's only temporary, hopefully. Is there a better way? Or, other things
that I need to consider?
Bill Pierce
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sat Sep 18, 2004 10:58 am Post subject: Re: How to split an extremely large class? |
|
|
Bill Pierce wrote:
| Quote: | I recently inherited maintenance of a library that contains, among other
things, a class with nearly 1500 member functions. As a first step, I'd
like to split it in two obvious new classes. The problem is that there is
several programs in production that use this library that I can't break.
Conceptually, here's what I have:
class HugeMama : public LoLevelClass
{
public:
void Type1Function001( ... );
o
o
o
void Type1Function800( ... );
char data_array[10];
void Type2Function001( ... );
o
o
o
void Type2Function700( ... );
}
Class LoLevelClass has no data members. "data_array" is used only
by Type1 functions.
|
This doesn't make any sense to me: all Type2* functions have no state
associated with them? In other words, they are just that, functions. They
neither need nor use 'this', so you'd be better off arranging these into
one namespace(or several, nested ones even).
As to what to do with the rest, I can only guess. I have never seen
anything the like, and considering the above, I wouldn't be surprised to
find that there are more serious flaws in the design. In the end, I fear
there are only two choices: keep your hands off it as far as possible or
refactor mercilessly. One choice will turn it into a proper design, the
other will keep it compatible - you know which one's which .
I'd be interested to hear what that class is and how it came to have 1k5
memberfunctions, even in private if that would be too far off topic for
here.
good luck!
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Sat Sep 18, 2004 2:35 pm Post subject: Re: How to split an extremely large class? |
|
|
[email]whpierce (AT) NOSPAM (DOT) comcast.net[/email] (Bill Pierce) wrote (abridged):
| Quote: | I recently inherited maintenance of a library that contains, among other
things, a class with nearly 1500 member functions. As a first step, I'd
like to split it in two obvious new classes. The problem is that there
is several programs in production that use this library that I
can't break.
class HugeMama : public LoLevelClass
class Type1Class : public LoLevelClass
class Type2Class : public LoLevelClass
class HugeMama : public Type1Class, public Type2Class
|
This uses non-virtual multiple inheritance, so any instance variables in
LoLevelClass will be duplicated in HugeMama, which will probably be wrong.
Member functions will also be duplicated, so the compiler will reject
calls as ambiguous.
You could try using virtual inheritance instead, but I wouldn't. You might
consider splitting off one class at a time:
class Type1Class : public LoLevelClass
class HugeMama : public Type1Class
Then change some clients to use Type1Class, then move to:
class Type1Class : public LoLevelClass
class HugeMama : public LoLevelClass
then repeat. The trick is to find a partition which will make this process
painless. Good luck.
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pavel Vozenilek Guest
|
Posted: Sat Sep 18, 2004 2:36 pm Post subject: Re: How to split an extremely large class? |
|
|
"Bill Pierce" wrote:
| Quote: | I recently inherited maintenance of a library that contains, among other
things, a class with nearly 1500 member functions.
Out of curiosity: what is such class main purpose? |
| Quote: | .... other things that I need to consider?
Try to create test cases which check this monster |
and smaller classes equivalents. This allows you
go step by step w/o fear too much got broken.
/Pavel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bill Pierce Guest
|
Posted: Sun Sep 19, 2004 10:48 am Post subject: Re: How to split an extremely large class? |
|
|
Thanks to all for the replies. I'm sorry for the slow response. We had a
hurricane blow through here and it sort put everything else on hold for a
while.
I found out a little more history of this class. It started out as 1400 "C"
software generated functions that somebody then wrapped into a class when
the projects switched from Sun/Solaris platforms to PC/Windows platforms.
The last 100 or so functions have been added by hand by various people over
the last 3 - 4 years.
Pavel, you may be particularly interested to hear that because the original
1400 functions were software generated, they have never been unit tested. In
fact, as best as I can tell, only a few of the hand coded functions have
ever been explicitly tested at all. In all other cases they either took it
on faith that the software generate code was right or did some quick sanity
checks of the production programs. This is one of the reasons that I want to
restructure it all. There is no chance that I'll get a big enough block of
time to sit down and write 1500 unit tests. But, if I can break it into
logical chunks first, maybe I can "eat the elephant one bite at a time."
Dave, the LoLevelClass has no data members, but I didn't think about the
function member ambiguity that would occur in HugeMama. I'll have to decide
whether I want to explicitly resolve those or try your other approach. The
problem with a piecemeal division is that it takes years for change requests
in the production code to work their way through our process. I'm the
impatient sort that doesn't want to have to live with this monster any
longer than I have to. So, any changes that I can make that remain invisible
to the client programs are much preferred.
Uli, the reason for your confusion is I didn't show the actual code. It's
nearly 56K lines, 2.5Mb in size. Most of the newer hand-coded 100 functions
use implied "this" to access the data_array and the other functions. Of
course the older software-generated, wrapped C code doesn't realize that it
does too. I hadn't considered using separate namespaces. I have to give it
some thought and research to see what advantages they would bring.
Thanks again to all.
Bill Pierce
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Balog Pal Guest
|
Posted: Sun Sep 19, 2004 10:25 pm Post subject: Re: How to split an extremely large class? |
|
|
"Bill Pierce" <whpierce (AT) NOSPAM (DOT) comcast.net> wrote
| Quote: | I found out a little more history of this class. It started out as 1400
"C"
software generated functions that somebody then wrapped into a class when
the projects switched from Sun/Solaris platforms to PC/Windows platforms.
|
And that wrapping didn't make sense in the first place -- so you'd better
think to undo it.
Remove the class{public:} and 'static' in front of the functions. Eliminate
the class.
You may introduce a namespace with the same name, then most calls will work
as before. The only places it dosn't where you have call the static
function through a redundant instance. Eliminate them.
| Quote: | The last 100 or so functions have been added by hand by various people
over
the last 3 - 4 years.
|
Then you'll have a class with just those 100 functions.
Class wrapping is only good to handle a common state. Like the set of
statics in an old C library. If there's no state classing do nothing useful
at all.
| Quote: | Uli, the reason for your confusion is I didn't show the actual code. It's
nearly 56K lines, 2.5Mb in size. Most of the newer hand-coded 100 functions |
use implied "this" to access the data_array and the other functions. Of
course the older software-generated, wrapped C code doesn't realize that it
does too.
Hopefully 'implied this' means toy just write foo() not this->foo().
Even if that is the case just globalreplace this-> to nothing. That breaks
only if your people use parameter names or local objects identical with
members. IUC there's just a single member, so you can chack for that
easily.
Paul
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Sep 20, 2004 3:31 pm Post subject: Re: How to split an extremely large class? |
|
|
In article <8cudnZ64tfxAwtHcRVn-jg (AT) comcast (DOT) com>, Bill Pierce
<whpierce (AT) NOSPAM (DOT) comcast.net> writes
| Quote: | I found out a little more history of this class. It started out as 1400 "C"
software generated functions that somebody then wrapped into a class when
the projects switched from Sun/Solaris platforms to PC/Windows platforms.
The last 100 or so functions have been added by hand by various people over
the last 3 - 4 years.
|
IOWs it was a totally inappropriate use of a class. Are they static
members of the class? If not, why not?
Have you considered changing to using a namespace? I think that is far
more appropriate. You could even then partition the namespace into
functions with unit tests in place and ones without. I think that
sensible use of using directives would allow you to move functions from
one partition to the other as the unit tests get written.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|