Re: How to extract class?
On Jan 5, 6:52 pm, legalize+jee...@mail.xmission.com (Richard) wrote:
[Please do not mail me a copy of your followup]
Immortal Nephi <Immortal_Ne...@hotmail.com> spake the secret code
<43fcca19-0161-493b-9a67-aa92c6d10...@d20g2000yqh.googlegroups.com> thusl=
y:
Ok...can you please tell me the exact book title name and ISBN. Is it
for C++? You mentioned -- Fowler.
The exact reference is "Refactoring: Improving the Design of Existing
Code" by Martin Fowler ISBN-10: 0201485672. Most refactoring is done
on "legacy code", i.e. code without unit tests. Refactoring without
unit tests must be done more carefully because you can't easily tell
if your refactoring changes have broken something. A good companion
to Refactoring is "Working Effectively With Legacy Code" by Michael
Feathers. I wrote a review of Feathers's book here:
<http://wp.me/pyVNs-6>
Fowler's book mostly uses Java as the example language, but the ideas
aren't tied to a particular language. Feathers's book uses Java and
C++ in the examples and some of the catalogued techniques he describes
are only available in one language or another. For instance, if the
technique uses reflection, that won't be a technique you can apply to
C++. Similarly, if the technique uses the preprocessor or link-time
tricks, that won't be a technique you can apply to Java.
The refactoring catalog from Fowler's book is online in an abbreviated
form at <http://refactoring.com>. The book contains more details
about each refactoring, including an example worked from start to
finish. You can read about "Replace Method with Method Object" there a=
t
<http://refactoring.com/catalog/replaceMethodWithMethodObject.html>
For refactorings I've written up, I've tried to follow Fowler's
format. I believe all the refactorings I've written up were in the
context of C++:
<http://legalizeadulthood.wordpress.com/category/computers/programming...=
You mention like I described my *first option*. Pass class Main's
data member to class A's member function's parameter in the reference.
Yes, you described several alternatives, but as I say its hard to
discuss the merits of the alternatives without specific code in front
of us.
You've chosen a solution that uses friendship. My advice is to avoi=
d
friendship whenever possible as it introduces tight coupling.
Like my second option. Consider that class A and class B are
private. Client is able to use class Main only, but they can't see
class A or class B. I continue to study refactoring. Thanks for yo=
ur
advice.
In "C++ Coding Standards", in the introduction to the chapter on class
design and inheritance on pg. 55 they say:
"[...] most of the items in this section are motivated pr=
imarily
or exclusively by dependency management. For example, =
inheritance
is the second-strongest relationship you can express in C=
++,
second only to friend; it should come as no surprise, the=
n, that
it's important to use such a powerful tool judiciously, c=
orrectly,
and well."
If that advice holds true for designs involving inheritance, then it
holds true a hundredfold for designs involving friendship.
In most of my refactoring of legacy C++ code, the uses of friendship
are often just because the person was too lazy to write an accessor or
mutator for data members. So they just made class B a friend of class
A and then B can shove its fingers into the pants of class A as much
as it likes. So much for encapsulation.
Friendship is present in C++ for a reason, but its the design
exception not the design norm. Most of the time you *don't* need
friendship and if you find yourself needing it for simple things like
"Replace Method with Method Object", then you should rethink what
you're doing and consider alternatives.
Thanks for the information about book. I do not understand what you
are referring "Replace Method with Method Object. The webpage
describes class Order and class PriceCalculator.
I think you are saying extract local variable into three variables.
price is one variable in class Order. primaryBasePrice,
secondaryBasePrice, and tertiaryBasePrice are three variables in class
PriceCalculator.
I do not extract local variable. I said earlier I made my decision
not to move class Main's data member to class A and class B. Both
class A and class B need to access class Main's data member directly.
There is no alternatives, but first option may be the answer.
Let me show you example.
class A
{
public:
void DoOperation_A( int &arg )
{
/* Do something to modify class Main's data member. */
}
};
class Main
{
public:
void Run()
{
DoOperation_A( data );
}
private:
int data;
};
Do you see that DoOperation_A()'s parameter has referance argument?
The DoOperation_A()'s body does not contain local variables. The
algorithm modifies class Main's data member through reference in the
parameter.
Do I explain clear? I guess that you pointed friendship should be
avoided unless it is necessary. Please let me know if you are able to
clarify.