I would move all object construction logic into a different class using the Factory_pattern.
In @MattDavey example the class Outer knows how to create items of type Inner.
(example in c#)
public Outer()
{
_inner = new Inner();
}
I would change this to
public Outer(Inner inner)
{
_inner = inner;
}
and let the factory create Outer items for you:
public class OuterFactory
{
// Existing behaviour - concrete Inner instantiation is hard coded
public virtual Outer createOuter(CreationParameters parameters)
{
Inner _inner = createInner(parameters);
Outer outer = new Outer(inner);
return outer;
}
public virtual Inner createInner(CreationParameters parameters)
{
Inner _inner = new Inner();
return _inner;
}
}
If you need a different inner class you can easily create a new factory that derives from the base factory:
public class MySpecialOuterFactory : OuterFactory
{
public overrrde Inner createInner(CreationParameters parameters)
{
Inner _inner = new SpecialInner();
return _inner;
}
}