RoundPi
RoundPi

Reputation: 5947

Is this simple but useful pattern too simple to be a real pattern?

Overwrite a derived function behaviour while still calling the same function of it's parent, see C::foo() for example.It still have the behaviour of A::foo but extended it. Is it too simple to be a pattern ?

class A
{
public:
    virtual ~A() {}
    virtual void foo(){ MSG("A::foo");}
};

class B : public A
{
public:
    virtual void foo(){ MSG("B::foo");}
};

class C : public B
{
public:
    virtual void foo(){ 
        A::foo(); //here still have the behaviour of A::foo but extended it
        MSG("C::foo");
    }
};

void callFoo(A* p)
{
    p->foo();
}

int main()
{
    boost::scoped_ptr<A> myPtr(new A());
    callFoo(myPtr.get());

    myPtr.reset(new B());
    callFoo(myPtr.get());

    myPtr.reset(new C());
    callFoo(myPtr.get());

    return 0;
}

Upvotes: 0

Views: 173

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254631

There's no requirement for a design element to be complicated to be called a "pattern".

However, there is a requirement that it be useful; that it makes it easier to produce correct, coherent, efficient and flexible designs. Implementing useful functionality in a base class, and then placing a burden on derived classes to remember to invoke it manually, doesn't really meet that requirement, and so I'd be tempted to label it an "anti-pattern". Adding an intermediate base class, and expecting derived class implementors to figure out which override(s) they actually want, is more along the lines of a "confusing mess".

If you want a bona fide pattern (described using capital letters in a famous book) for this situation, then the Template Method might be appropriate - the base class contains a non-virtual function which performs some common functionality, delegating part of the work to private, pure virtual functions that can be overridden. Personally, I'd go one step further and delegate to a separate class, since I like to give each class a single responsibility and avoid inheriting from anything except abstract interfaces, giving something along the lines of:

class FooInterface {
public:
    virtual ~FooInterface() {}
    virtual void foo() = 0;
};

class A {
public:
    void foo(FooInterface & impl) {
        MSG("A::foo"); // Happens whatever the implementation does
        impl.foo();
    }
};

class C : public FooInterface {
    virtual void foo() {
        // We don't have to worry about A at all
        MSG("C::foo");
    }
};

Upvotes: 2

Puppy
Puppy

Reputation: 146968

By "Simple but useful pattern" you mean "Language feature". You can't just use a language feature once and call it a pattern. It's not a pattern. It's just you using a language feature. I mean, congratulations, I also think that using language features is an important way to go about constructing programs in a language, but, it's a long way from any pattern anything.

Upvotes: 3

Related Questions