Hiding By Delegating

You want to hide some methods, but you can't or don't want to make them private for some reason. Perhaps someone else needs access, or perhaps your language doesn't support it.

Say you have (in C++):

    class Client {
    public:
        void method() {
            method1();
            method2();
            method3();
        }

public: void method1(); void method2(); void method3(); };

and you want to hide the inner methods. Here's a way. First, apply MethodObject, then push the inner methods down into a subclass. Then you can make them private in the base class but public in the subclass. Use the factory pattern to hide the subclass. Like:

    class Method {
    public:
        static Method *factory();
        virtual ~Method() {};
        virtual void method();
    };

class Client { public: void method() { Method *pMethod = Method::factory(); pMethod->method(); delete pMethod; } };

class MethodImp : public Method { public: virtual void method();

void method1(); void method2(); void method3(); }; static Method *Method::factory() { return new MethodImp; }

Because pMethod is of type Method, it can't be used to get at the members of MethodImp. They are not even in scope for Client. They are effectively hidden. However, classes which need them can still access them by creating a MethodImp directly.


This idea was mentioned in the Eiffel newsgroup a long time ago, as a way of faking "private". Eiffel, like Smalltalk, does not actually have "private" or any way of hiding members from subclasses of itself. In practice you may not need MethodImp - just moving the methods into Method may be enough to put people off using them.

I remembered it while reading UnitTestingNonPublicMemberFunctions. The unit test was the code that had legitimate reason to call method1 et al. Presumably the author did not want to couple the test to the Client code by using "friend". Again we may not need MethodImp if we are happy to use "friend" in Method itself.

I don't know whether this idiom has been used often enough to be called a pattern. Perhaps ask in Eiffel circles?


See also: PrivateInterface, ContractiveDelegation


EditText of this page (last edited September 15, 2004) or FindPage with title or text search