Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am facing a problem with changing behaviour of a library (thus cannot or don't want to change its internals because of future updates, etc.).

In this library there is an abstract class which shares few methods with all its subclasses. Now I need to change few methods in this abstract super class without changing the subclasses. I was wondering what pattern I should apply to this without rewriting the whole thing.

I use PHP, so I could use a trait to override these methods in my own sub-subclasses which I will then use in my client code. This would result in creating the sub-subclasses and adding a trait (which is a one-liner). But I need to run PHP 5.3 which doesn't support traits.

Is there a pattern that solves this problem?

EDIT 2: the point is I don't want to change the library code, I can extend the subclasses and use them in client code but I don't want to change the code in the library itself (so I can update the library easily).

EDIT: see simplified code below

abstract class SuperClass {
    protected function doMagic() { 
        ... I need to change this ...
    }

    abstract public function execute();
}

class SubClass1 extends SuperClass {
    protected public execute() {
        $this->doMagic();
        ... some other code ...
    }
}

class SubClass2 extends SuperClass {
    protected public execute() {
        $this->doMagic();
        ... some different code ...
    }
}
share|improve this question
    
The pattern is called functional programming (as opposed to OOP). –  Job Feb 19 '13 at 21:38
1  
couldn't you make another object, and forward all calls to the existing library. This way the abstract class does not need to be changed at all, but you get all the advantages of changed interface. –  tp1 Feb 19 '13 at 21:38
    
Would you mind sharing a code sample that illustrate your specific situation? –  marco-fiset Feb 19 '13 at 21:47
    
@tp1 I couldn't because the methods I need to change are used from within these subclasses. I edited the post –  redhead Feb 19 '13 at 21:58
    
What you want to do is against the open / closed principle. Are you sure you want to change the behaviour of an already implemented class and propagate this change to all its subclasses? –  Giorgio Feb 20 '13 at 9:21

3 Answers 3

First question--why do you need to change the logic of the abstract class? You seem to indicate that you don't want any of its current subclasses to inherit the changes, so I have to assume you want to write new subclasses which will. Given that the new subclasses don't exist yet, add a little indirection first:

abstract class SuperClass {
    protected function doMagic() { 
        ... I need to change this ...
    }

    abstract public function execute();
}

abstract class ExtendedSuperClass extends SuperClass {
    protected function doMagic() { 
        ... NEW CODE ...
    }
}


class SubClass1 extends SuperClass {
    protected public execute() {
        $this->doMagic();
        ... some other code ...
    }
}

class SubClass2 extends SuperClass {
    protected public execute() {
        $this->doMagic();
        ... some different code ...
    }
}

class SubClass3 extends ExtendedSuperClass {
    protected public execute() {
        $this->doMagic();
        ... yet more different code ...
    }
}

That is, extend the abstract class with a new abstract class, and have the classes needing the new logic extend THAT.

share|improve this answer
    
Sorry, maybe I wrote that wrong. There are no new classes, the subclasses already exist in the library and are using its abstract parent methods (that I need to change). So, basically I want the existing subclasses having the common behaviour (which is in the super class and which I need to change). To be concrete: in your code, there are 2 classes (1 and 2) which don't have the same changed behaviour as the new class (3), but this is exactly what I need. –  redhead Feb 19 '13 at 23:11
1  
@redhead So, if you change the behavior in the abstract class that the current subclasses are inheriting, do you want them to inherit the new behavior? If so, just change the logic in the abstract class and they'll inherit it. If you don't want them to inherit it, what's the point of changing the abstract class? –  Matthew Flynn Feb 19 '13 at 23:22
    
That's the thing, I don't want to touch these classes in the library (for sake of updating, etc.). I can use the subclasses in my client code (I can also extend them) but I don't want to touch the code in them. That's why I ask. If I just edit the code in the library what is the point of asking this question looking for a way not to edit it. –  redhead Feb 19 '13 at 23:29
    
@redhead Then if you can't edit any code, you can't change the behaviour. If the internals of a class are not doing what you want, you must crack it open and implement what you need. There is really no other way. –  marco-fiset Feb 20 '13 at 13:42
    
@redhead - Try copying the class that needs modifying into a new class (keeping the same names). Modify the copy. Put the modified copy ahead of the library in your class path (or use an AutoLoader or whatever you to in PHP?). –  Matthew Flynn Feb 20 '13 at 21:31

Abstract classes should be written without considering their subclasses in order to avoid tight coupling. I don't know what your specific situation is, but usually abstract classes are meant to be used for polymorphism, with each subclass implementing a specific behavior through an abstract method. If you find yourself changing code inside the base class which will break the subclasses, you have a coupling problem. Base classes should make calls to abtract methods which the subclasses will implement. Moreover, a subclass should limit the number of calls to parent methods.

share|improve this answer
    
I see what you mean. The thing is, the library is designed this way, so I have no power over it. The coupling problem is there - subclasses call its parent methods (which I need to change). –  redhead Feb 19 '13 at 22:06
    
@redhead well if you can change the abstract class, why not change the subclasses also ? –  marco-fiset Feb 20 '13 at 0:06
    
I don't want to change the abstract class (meaning the code of it), it's a library and I want to be able to update it later. I don't want to change any code in the library itself. I can extend the subclasses and then use them in client code. But I don't want to change the code of the library classes themselves. That's why I am asking. If I could edit the code in the abstract class I wouldn't be asking. –  redhead Feb 20 '13 at 0:59
    
Then what you can do is create another class yourself, which inherits the abstract class and provides the new behaviour by overriding the doMagic method, and then you can make your subclasses inherit from your new class, exactly like Matthew Flynn suggested. It seems like there is no other way. –  marco-fiset Feb 20 '13 at 13:38
    
But that way the existing subclasses in the library would have to be rewriten to use my own abstract class which is what I wanted to avoid. I think there is no other way after all.. :/ –  redhead Feb 20 '13 at 14:03

I see no design pattern, but, an algorithm.

Original Code:

 abstract class SuperClass {
     protected function doMagic() { 
         ... I need to change this ...
     }

     abstract public function execute();
 } // class

 class SubClass1 extends SuperClass {
     protected public execute() {
         $this->doMagic();
         ... some other code ...
     }
 } // class

 class SubClass2 extends SuperClass {
     protected public execute() {
         $this->doMagic();
         ... some different code ...
     }
 } // class

New Code:

 abstract class SuperClass {
     protected $UseNewSpell = false;

     protected function OldSpell() {
        // put previous code here
     }

     protected function NewSpell() {
        // put new code here
     }

     protected function doMagic() { 
         if ($this->UseNewSpell) {
            $this->NewSpell();
         }
         else {
            $this->OldSpell();
         }                 
     }

     abstract public function execute();
 } // class

 class SubClass1 extends SuperClass {
     protected public execute() {
         $this->UseNewSpell = false;

         $this->doMagic();
         ... some other code ...
     }
 } // class

 class SubClass2 extends SuperClass {
     protected public execute() {
         $this->UseNewSpell = false;

         $this->doMagic();
         ... some different code ...
     }
 } // class
share|improve this answer
    
But this means rewriting the library code. That isn't the way to go as I stated in the question. –  redhead Feb 19 '13 at 22:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.