Jump to content

Refactoring question (function side-effects, class globals)


dennis-fedco

Recommended Posts

Imagine 6 PHP classes (one each for a product line), that have very similar coding structures, that go like this:

//function that computes stuff inside each of 6 files:
//they vary slightly from file to file but essentially it is this:
function computeFunction
{
    $this->x = new X();

    $this->x->calcD();

    if ($this->x->dOk)
    {
        $this->x->calcE();
        $this->x->calcN();   
    }

    //more complicated logic that is essentially like above

    //and by the way!
    print $this->x->someVarThatIsUsedLater;
}

Then there is a single class like so :

class X
{
    function calcD()
    {
        //compute some condition

        if (<computed condition is met>) $this->dOk = true;
        else $this->dOk = false;

        //and by the way
        $this->someVarThatIsUsedLater = 4;
    }
}

Just to bring your attention to it, none of these functions return any result or value, but they nevertheless operate on variables of key interest via side-effects.  That is, they modify variables that essentially act like globals, and then use those variables later ($this->dOk and $this->someVarThatIsUsedLater are one more prominent examples).

 

I need to untangle this mess.  And make it clean and clear again, and make sense.  How do I best proceed?

 

I have been wrestling with some ideas... like $this->dOk, can within reason be turned into a return variable of calcD() function, and then be tested against like if ($this->x->calcD()) and I think it will be reasonable enough.  But then there are other functions that don't return anything and just act on variables via side-effects anyway so $this->dOk is one of the lesser troubles...

 

Other than that, what I am thinking of doing is getting rid of these mini-functions (calcE()calcN(), etc.), removing them as a funciton, and putting their body directly into the code, as a first step to refactor.  Many of the computations done inside are just a few lines of code anyway, and the functions kind of hide a lot of side-effects that happen, instead of actually encapsulating the behavior.  So while it may be counter-intuitive to dismantle the functions that appear to be doing something that normally can be encapsulated (computing key variables E, N, etc), I think dismantling them will actually clean things up as far as collecting all the side-effects inside a single parent function thereby making them more visible.

 

Caveat:  while doing so I will end up with 6 copies of untangled dismantled functions, because dismantling class X and putting its content into each of the 6 product line classes will have that effect.

 

But my hope is that from that point I will see more clearly to start identifying places where I can start to truly encapsulating the behavior via various structures, instead of masking it.

 

Problems / Questions:

  • I would like to but I am not entirely sure that I can skip that step of dismantling functions & the 6x multiplying effect. It's probably the same like skipping steps in solving polynomial equations.  Some can do it and some need to list each step of their work.
  • And I am not entirely sure what structures I can replace it with in the end after I dismantle the functions.
  • It also looks like a lot of work.  Is there a better way?

P.S. I already put tests on computeFunction() for each product line so I can be less paranoid about hacking stuff up.

Edited by dennis-fedco
Link to comment
Share on other sites

To add one important bit: class X has if-then-else statements testing for a specific product line, when using various formulas.  So when dismantling functions, I will actually be porting part of the functions back to their respective product lines.  Doing so still will result in duplication as some product lines use same code to do some things.

Link to comment
Share on other sites

If you've got enough duplicate code around disparate classes, I'd seriously consider creating an inheritance hierarchy. That way you could get rid of the if-then-else statements and instantiate specific sub-classes that extend a base class where most/all of the duplicate code is kept.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.