Re: Chatting about Extract Class

J Arrizza <[email protected]> Tue, 16 Mar 2010 17:43:00 -0700
Newsgroups gmane.comp.programming.refactoring
Message-ID <[email protected]>
> I'm curious about how other people view the Extract Class refactoring. For
instance, do you use it much, ...

I don't think it's about "how often?" as it is of "which is more
important?". You will Extract Methods more often (5x? 10x?) but it's usually
a stepping stone to an Extract Class refactoring. In general the flow looks
like:

      - extract method 1 as a private method
            ...
     - extract method n as a private method
     - extract a subset of the private methods into a class and make them
public.
     - add UTs around the new class
     - refactor  the new class if necessary (rename is usually the common
one at this point)
     - repeat

At some point the original class is "bare bones" or "minimal" or "singular"
or "focused" or whatever you use to describe a final, well-defined, class.
Usually the class becomes static then and does not change for a very long
time (normally only if an enhancement is added to it).

The extract class refactoring is more important because it is one of the
final steps in a better OO design. The extract method just simplifies the
original class enough to get you to the point where you can do the extract
class.

(Note this is all generally speaking, there are exceptions everywhere in the
process)

> how do you go about it

Three basic ways:

1) Extract methods and look for associations between a subset of methods and
one (or perhaps a few) instance variables. e.g. if 4 methods and only 4
methods work on variable mXYZ, then extract the 4 methods and variable mXYZ
as a class.

Watch out for variables that are attributes of other variables. e.g.
mBgColor is an attribute of mCar. They usually extract out together into a
new class. As a counterexample to "usually", see for example Kent Beck's
currency class where an attribute of money (currency) is extracted out as a
class all by itself.

Sometimes I think of the process from the perspective of database theory's
Normal Forms. A well-designed class (in fifth NF?) has one main variable
(the "key") that the methods strongly relate to but may have additional
variables ("attributes") that relate to the main variable and can't exist
independently of it.

2) Look for commonality in the method signatures. Common signatures implies
methods strongly associated with the values/variables being passed into
them.

3) Sheer luck. I see a pattern in the names of the methods, or some
commonality in how they behave, or a commonality in the instance variables,
or something even less tangible e.g. "I* know* there's a class in there...
somewhere."

I extract the methods and variables out, see how it feels, and if it sucks,
I back out the refactoring. Sometimes the clue that it's been done badly is
that the original class looks like it's been given a haircut with a
chainsaw. Sometimes adding the UTs around the new class start to give off
that dead mammal smell.

I guess it's bad to admit I use this "technique", but the benefits I get
from extracting the class generally outweigh the risks the few(!) times it's
done badly. The key is to recognize when it is bad and back out the
refactoring ASAP otherwise you end up facing Developer Inertia.

Having said all that, I also recognize there are reasons to create classes
other than to encapsulate variables. The rules of thumb above won't help you
much with that kind of refactoring.

> what would help you do it more often?
It think it's very easy to extract a class. I think you mean "What would
help you do it correctly more often?"

In that case a couple of things would help me: time or a brain the size of a
planet or better yet both.

John


[Non-text portions of this message have been removed]



------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/refactoring/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/refactoring/join
    (Yahoo! ID required)

<*> To change settings via email:
    [email protected] 
    [email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/