a class refactoring problem.

Discussion in 'Java' started by Roedy Green, May 2, 2009.

  1. Roedy Green

    Roedy Green Guest

    Let us say you wanted to end up with a class structure something like
    this:

    class Core : contains data fields and intelligent accessors and
    virtual fields.

    Stage1 extends Core

    Stage2 extends Core

    Stage3 extends Core

    Stage1 Stage2 and Stage3 have nothing whatsoever to do with each
    other.

    Then you create a Core object and somehow invoke:

    Stage1.doEverithing()
    Stage2.doEverything();
    Stage3.doEverything();

    on your Core object.

    Let us presume you have everything in one giant Core class now where
    all the code is this.based.

    In my particular case, long ago I have a similar problem where
    refactored it like this:

    Stage1 extends Core
    Stage2 extends Stage1
    Stage3 extends Stage2

    This turned out to confusing, creating too many "adhesions" between
    Stage1 Stage2 and Stage3. The compiler did not help enforce placement
    of Stage3 code purely in class Stage3.

    It looks as if I will need to pass a delegate Core object to Stage1,
    Stage2 and Stage3. It then must do one of two things that I am
    reluctant to do

    1. have each Stage extend Core, and then in a copy-constructor copy
    the values of all the individual fields to this.xxx (a maintenance
    and debugging nightmare.) Java has no facility for creating code for a
    copy constructor for the Dog Field to converta Dog to a Dalmatian,
    even though in assembler it is just a single instruction.

    2. use a delegate object. This means changing every reference to every
    field in the entire code body.

    Can you think of lower-labour approach?

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "Species evolve exactly as if they were adapting as best they could to a changing world, and not at all as if they were moving toward a set goal."
    ~ George Gaylord Simpson
     
    Roedy Green, May 2, 2009
    #1
    1. Advertising

  2. Roedy Green

    Roedy Green Guest

    On Sat, 02 May 2009 12:19:36 -0700, "Peter Duniho"
    <> wrote, quoted or indirectly quoted
    someone who said :

    >Perhaps you could explain how you are supposed to be able to invoke three
    >different methods on three different unrelated classes extending the type
    >of the instance you did create. Are these to be static methods? If so,
    >why is the base type relevant at all? If they are not, how do you get
    > from the base type instance to the sub-class methods?



    Perhaps if I explained my particular case it would come clear. I
    though it would just cloud the issue and distract it from the point I
    am trying to make. It is probably best to talk about the actual
    problem since it may have solutions outside the box of the artificial
    example.


    I have a number of facts about a computer package I have written. The
    is a ton of stuff, much of it deduced from the basic facts e.g
    name of the project, main class files, is it an Applet, does it use
    JNI, it is signed, what languages are used...

    I then do various things with this basic core of data e.g.

    generate ant scripts to build /and or bundle a distribution zip,
    create aux files, check consistency with the prices database,
    create duplicates of various files, ensure various files are present
    and the version, release dates, file sizes etc are consistent in
    source code, docs, PADs etc, and in some cases patch files to make
    them consistent.

    The generating of a 4NT/Take Command DESCRIBE file to annotate all the
    files with their names has nothing at all to do with the generating of
    an ant build script, except that they use the common bank of core
    project data.

    On my most recent refactoring binge, I ended up refactoring it with a
    copy constructor in Core, with Stage1, Stage2 and Stage3 each
    extending the basic Core class of data.

    the Stage1 constructor takes a Core object. It passes it to the Core
    constructor that extracts the crucial data out of it, and regenerates
    the Core fields, rather that copying all the inferred data out of the
    Core object parameter, field by field. In this case the overhead is
    completely acceptable, though in general, I don't like it. You SHOULD
    be able to just set up the Core field in your extended Stage1 object
    with a code that generates a single move bytes instruction, the way an
    assembler programmer would do it.

    I pull the whole thing together like this:


    class StompOneProject() extends ProjectInfo
    {
    ....


    /**
    * do everything for this project, generate all files
    */
    void stomp()
    {
    ceateProjectDirectory();
    new SanityCheckProject( this ).stomp();
    deleteObsoletes();
    new MkAuxFiles( this ).stomp();
    new FixPads( this ).stomp();
    new MkAnt( this ).stomp();
    new MkDesc( this ).stomp();
    new CrossCheckProject( this ).stomp();
    }

    Where "this" is an extended ProjectInfo/Core object.

    Each of the other classes has a stomp Method does whatever that class
    does to a project.

    Stomp could an abstract method of ProjectInfo, part of an interface,
    or an arbirary name. The code would work just as well is if it had
    been written. There is no pressing reasons all the classes had to have
    a stomp method. It was just a way of naming a hierarchy of work.


    /**
    * do everything for this project, generate all files
    */
    void stomp()
    {
    ceateProjectDirectory();
    new SanityCheckProject( this ).checkSanity();
    deleteObsoletes();
    new MkAuxFiles( this ).generateMiscFiles();
    new FixPads( this ).PatchPADfiles();
    new MkAnt( this ).generateAntScripts();
    new MkDesc( this ).buildFileDecriptions();
    new CrossCheckProject( this ).crossCheckForConsistency();
    }


    If you want to see the actual code, have a look at the Subversion
    repository. You can view it with an ordinary browser. This is not code
    I distribute. It for my personal use.

    https://wush.net/websvn/mindprod/listing.php?repname=mindprod&path=/com/mindprod/stomp/
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "Species evolve exactly as if they were adapting as best they could to a changing world, and not at all as if they were moving toward a set goal."
    ~ George Gaylord Simpson
     
    Roedy Green, May 3, 2009
    #2
    1. Advertising

  3. Roedy Green

    Mark Space Guest

    Roedy Green wrote:

    > 1. have each Stage extend Core, and then in a copy-constructor copy
    > the values of all the individual fields to this.xxx (a maintenance
    > and debugging nightmare.) Java has no facility for creating code for a
    > copy constructor for the Dog Field to converta Dog to a Dalmatian,



    Would clone() help here?

    class Core implements Clonable
    {
    ....

    protected Core clone() // just a sketch, needs full clone() pattern
    {
    Core c = (Core) super.clone();
    // more stuff?
    return c;
    }
    }

    I wonder if you could use this in the copy constructors.

    class Stage1 extends Core
    {
    public Stage2 stage2()
    {
    Core c = super.clone();
    // turn this into stage2 somehow...
    return new Stage2( c );
    }
    }

    I'm not seeing the full pattern here but this might save you some
    maintenance hassle so you don't have to copy each field manually.
     
    Mark Space, May 3, 2009
    #3
  4. Roedy Green

    Mark Space Guest

    Roedy Green wrote:

    > The generating of a 4NT/Take Command DESCRIBE file to annotate all the
    > files with their names has nothing at all to do with the generating of
    > an ant build script, except that they use the common bank of core
    > project data.



    I'm weirdly reminded of the Visitor Pattern here, possibly because it
    just game up recently in another thread. But you have a hierarchy of
    objects, that you want to preform various operations on. The operations
    have nothing in common except they work with the hierarchy of objects.

    Hmmm....

    Note the gang-of-four considers the Visitor to be a bad idea if you
    frequently add new objects in the hierarchy. It's better if the
    hierarchy stays as is, and you mostly just add new visitors as you come
    up with new things to do.
     
    Mark Space, May 3, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Refactorit

    come learn all about refactoring

    Refactorit, Feb 22, 2004, in forum: Java
    Replies:
    0
    Views:
    344
    Refactorit
    Feb 22, 2004
  2. Sebastian Jekutsch

    Survey on refactoring activities using IDEs

    Sebastian Jekutsch, Jun 8, 2004, in forum: Java
    Replies:
    5
    Views:
    470
  3. E11
    Replies:
    1
    Views:
    4,781
    Thomas Weidenfeller
    Oct 12, 2005
  4. ennio

    Class rename refactoring

    ennio, Sep 7, 2006, in forum: Java
    Replies:
    0
    Views:
    319
    ennio
    Sep 7, 2006
  5. Roedy Green

    refactoring problem

    Roedy Green, Feb 3, 2013, in forum: Java
    Replies:
    34
    Views:
    665
    Arne Vajhøj
    Feb 9, 2013
Loading...

Share This Page