Changing an object’s (apparent) class at runtime

design-patternslanguage-agnostic

I'm looking for a design pattern to solve the following problem:

An object (let's say representing a document) can change its type dynamically during its lifetime (e.g. when it is saved with a different file extension).

The object contains many virtual methods so that depending on the object type it can behave in different ways (e.g. different syntax highlighting).

The application contains many references to the object, which should not become invalid when the object's type changes. So it won't do to destroy the object and create a new one of the new type.

An 'obvious' solution is to use composition, so that the object seen by the application (the outer object) never changes, but it forwards all calls to a contained object that can be destroyed and recreated whenever the type changes.

But this requires a method in the outer object for each virtual method in the contained object to forward the call.

Is there a design pattern that avoids this need for forwarding methods?

(Ideally I'd like a pattern that doesn't require the language to support interfaces.)


Update

Thanks to comments below, I've identified that the State design pattern implements what I want, except that it requires explicitly forwarding every method from the wrapper class to the wrapee class.

So another (perhaps clearer?) way of stating my original question is this: Is there an alternative design pattern that implements the functionality of the State design pattern in (virtually) any object oriented language without needing explicitly to forward every method?

('No' is a perfectly valid answer by the way as long as you can justify it.)

Best Answer

The solution you describe in your question is usually called the "bridge pattern". Depending on the language in use, there may be a way of implementing it without manually managing all the delegating methods. For example, in Ruby one can simply define the "method_missing" method to perform a dynamic lookup on the target object and dispatch to a method with the same name as the called method. In Java you may be able to use a bytecode generation library to achieve a similar effect, e.g Javassist.

Related Topic