AlaaShaker's Weblog

// untitled …

Secret Creator [Problem of the Week]

with 29 comments

After the Design Patterns course has ended in FCIS, and following up with the wicked problems of my friend, Fouad, I decided to post a code design problem I heard lately …

class Secret
{
    // TODO: class body goes here ..
}
class Creator
{
    // TODO: class body goes here ..
}

You have two classes: Secret and Creator.

Code both classes such that no other class than Creator is allowed to instantiate a local object of Secret. In other words, I can create an object of Secret as long as this code is inside Creator. If I’m inside any other class than Creator, I can’t!!!

The goal is to restrict the developer writing the code; creating an object of a certain class is restricted to another class, the only class allowed to perform such operation.

Note: The solution should be standard. No using “friend” classes and such keywords. Solve it in C/C++, C# or Java – standard code won’t differ!

As Fouad did, post your answers as comments. Comments will be moderated. Wrong answers will be posted, correct ones won’t πŸ˜›

The correct answer will be posted by next Friday, or if I get five correct answers – the earlier!

Solution Posted

Click her to see the winners list and my solution …

Advertisements

Written by AlaaShaker

August 16, 2008 at 5:05 pm

29 Responses

Subscribe to comments with RSS.

  1. i have an idea

    class Creator
    {
    private:
    class Secret
    {
    // TODO: class body goes here ..
    };
    // TODO: class body goes here ..
    };

    πŸ˜›

    Jaqoup

    August 16, 2008 at 6:02 pm

  2. Coding Secret as a private class inside Creator solution doesn’t match the problem definition. Now, class Secret is totally hidden from the whole application, no body said we wanted that. The two classes shall remain separate and publicly accessible.

    AlaaShaker

    August 16, 2008 at 6:16 pm

  3. class secret
    {
    public:

    virtual void ay7aga()=0;
    };

    class creator
    {
    private:
    class a: public secret
    {
    public:
    a(){}

    virtual void ay7aga()
    {
    //:)
    }
    };
    public:
    secret *getone()
    {
    return new a();
    }
    };
    int _tmain(int argc, _TCHAR* argv[])
    {
    creator obj;
    secret *s = obj.getone();
    s->ay7aga();
    return 0;
    }

    anonymous

    August 16, 2008 at 11:19 pm

  4. Sorry Mr.Anonymous, but your code doesn’t prevent me from doing this outside class Creator (as in the _tmain function for instance, or any other new class):
    Secret* s = new Secret();
    Think again … πŸ˜€

    AlaaShaker

    August 16, 2008 at 11:42 pm

  5. your code doesn’t prevent me from doing this outside class Creator (as in the _tmain function for instance, or any other new class):
    Secret* s = new Secret();
    at least you didn’t try to compile the line of code you argue and if you tried you will get the following error
    Error 1 error C2259: ‘secret’ : cannot instantiate abstract class

    anonymous

    August 17, 2008 at 8:03 am

  6. My apologies, I missed the “=0;” part in the virtual function. My bad!

    Still your solution isn’t completely right, that’s why I didn’t try compiling it. The rule is: Only Caller can instantiate Secret. I need to restrict the developer from doing elsewise, your code doesn’t!

    I could simply create a third class that subclasses Secret and implement the virtual function and then use it anywhere as much as I please (pretty much the same code as class a, but outside Caller). By doing so, I break the restriction, I break the rule.

    Give it another try πŸ˜€

    AlaaShaker

    August 17, 2008 at 11:27 am

  7. How about making the constructor of Secret protected and making Creator derive from it?
    Technically, any other class can do this but it more or less does the intended goal.

    A really big problem with this solution is that it violates the is-a rule of inheritance, because there’s no guarantee that Creator can be used anywhere Secret is used, and creator would inherit a lot of methods it doesn’t need.

    Thus my solution is good only as a trick/ puzzle answer and not recommended for practical code πŸ™‚

    Mohamed Samy

    August 17, 2008 at 6:46 pm

  8. First, let me thank you for giving it some time πŸ˜€

    Well, you said it yourself; any other class can do that.
    In this specific case, I’m more concerned about the restricting-the-developer part of the problem.

    AlaaShaker

    August 17, 2008 at 10:12 pm

  9. An implementation like this would prevent the developer from Creating Secret class from anywhere but Creator.

    Class Creator
    {
    public:
    secret* CreateSecretObject() ;

    private:
    Class Secret
    {
    }
    }

    This way the developer won’t be able to access Secret class except by Calling the CreateSecretObject from the Creator class , i guess πŸ˜€ πŸ˜€ !!!

    Mahmoud Osama

    August 17, 2008 at 11:15 pm

  10. Ok then how about:

    class Secret
    {
    private Secret(){}
    public static GiveInstanceTo(Creator c)
    {
    c._secretInstance = new Secret( );
    }
    }
    class Creator
    {
    public Secret _secretInstance;
    public Secret CreateSecret( )
    {
    Secret.GiveInstanceTo(this);
    return _secretInstance;
    }
    }

    This method is very cumbersome (not to mention non-threadsafe) so again not recommended for real apps.

    This method has a ‘hole’ in that I can derive from creator and use the ‘GiveInstanceTo’ on the derived object, or did you mean “Works only inside ‘Creator’ and its subclasses”?

    Mohamed Samy

    August 18, 2008 at 8:36 pm

  11. what about this /*JAVA*/

    public final class Creator
    {

    public final class secret
    {
    secret() //default modifier
    {
    . . .
    }
    };

    blah blah blah ...
    };

    Jaqoup

    August 19, 2008 at 9:57 am

  12. To Mohamed Samy:

    Your answer is the CLOSEST!
    The only problem with your code is that I could easily trick the code inside any other class using these 3 lines of code:
    Creator dummyCreator = new Creator();
    Secret.GiveInstanceTo(dummyCreator);
    Secret myWickedSecret = dummyCreator._secretInstance;

    (BTW, there’s no need to return the Secret object in Creator.CreateInstance() .. I meant to use the Secret object locally inside Creator, but it’s OK πŸ˜€ )

    Your answer, again, is the CLOSEST! You’re almost there, fadellak zalata as they say πŸ˜‰

    AlaaShaker

    August 19, 2008 at 12:28 pm

  13. To Abdallah:

    I’m sorry again. The keyword “final” will only prevent me from subclassing any of both classes.
    It doesn’t mean I can’t do something like:
    Creator.Secret s = new Creator.Secret();
    (I didn’t check the syntax, but you know what I mean)

    Try again πŸ˜€

    AlaaShaker

    August 19, 2008 at 12:31 pm

  14. HINTS:
    > Don’t go for inheritance. It’s not that way.
    > Think of the simplest design pattern, it would help refresh your brain.
    > Focus on the task: No instantiation outside Creator. Force the developer!

    AlaaShaker

    August 19, 2008 at 12:33 pm

  15. ok i know that it only prevents subclassing
    what will prevent u from doing
    new Creator.Secret();
    will be the “default access modifier”ed constructor
    which will not be visible except inside the Creator classes and its subclasses ( thats y i used final in Creator)

    Jaqoup

    August 19, 2008 at 12:42 pm

  16. To Abdallah:

    I will have to disagree. It’s wrong πŸ˜€ It’s only coz we both used the wrong syntax. I can still do this:
    Creator c = new Creator();
    Creator.Secret s = c.new Secret();

    Plus, I don’t want language specific solutions. Zaker Java kowayess ba2a πŸ˜›

    AlaaShaker

    August 19, 2008 at 1:21 pm

  17. I think I got it. Thanks for the hints πŸ™‚
    This time it should be bullet proof: no external classes, even subclasses of creator, can access the secret!

    class Secret
    {
    private Secret(){}
    public static GiveInstanceTo(Creator c)
    {
    c.SetSecret( new Secret() );
    }
    }

    class Creator
    {
    private Secret _secretInstance;
    public SetSecret(Secret s) { _secretInstance = s;}
    public Secret CreateSecret( )
    {
    Secret.GiveInstanceTo(this);
    return _secretInstance;
    }
    }

    Mohamed Samy

    August 19, 2008 at 9:51 pm

  18. WE HAVE A WINNER πŸ˜€
    Mohamed Samy is the first to solve it … CONGRATS!
    (It’s bullet proof this time ;))

    Let’s hope someone else does ..

    AlaaShaker

    August 19, 2008 at 10:22 pm

  19. ummmmm after thinking a lot to use the Factory method, but failed!!

    I thought to modify Mohamed Samy’s code ((as it was the closest :D))

    >Here is it

    class Secret
    {
    private Secret() { }
    public static void GiveInstanceTo(Creator c)
    {
    c.SecretInstance = new Secret();
    }
    }
    class Creator
    {
    private static Secret _secretInstance;
    public void CreateSecret()
    {
    if (_secretInstance == null)
    Secret.GiveInstanceTo(this);
    }
    public Secret SecretInstance
    {
    set
    {
    if (_secretInstance == null)
    _secretInstance = value;
    }
    }
    }

    I think its now liable to Singleton Pattern ((which is the Simplest Design Pattern too :D:D))…..
    Please confirm if thats the Correct Answer

    Shady Ahmed El-Yasaki

    August 20, 2008 at 11:41 am

  20. WE HAVE A SECOND WINNER πŸ˜€
    Good thinking Shady, u just revealed Mohamed Samy’s solution πŸ˜€

    It seems that Mohamed Samy’s solution plus my hints have made it easier … LOL
    Even though, I do have a somehow different solution .. will keep it till the end ..

    AlaaShaker

    August 20, 2008 at 3:43 pm

  21. If you don’t want to do some OO tricks , I see that the most simple solution will be to use a normal key-lock schema , just give the “Creator” some fixed GUID “as you do in com interfaces”
    and add to the class “Secret” :
    DWORD CreateInstance(GUID callerGuid, any other paramaters )
    {
    check the GUID if it matches the Creator GUID
    {

    πŸ˜€ can we count this

    }

    Mohammad Diab

    August 20, 2008 at 6:16 pm

  22. Secret should be an internal class inside of Creator with its ctor private,…

    That way only creator can use that ctor, so only creator can instantiate secret…

    Nice one Alaa ☺

    Mustafa

    August 20, 2008 at 9:10 pm

  23. To Mustafa:

    Thanks, but your solution isn’t quite correct πŸ˜€
    I believe if you declared the constructor of Secret as private, that won’t allow Creator to instantiate it, even if the first is a nested class in the latter.

    I need a coded solution plzzz, that compiles .. standard, and language independant πŸ˜€

    AlaaShaker

    August 20, 2008 at 9:35 pm

  24. ANOTHER THIRD WINNER πŸ˜€
    Congrats to MAD, your answer is the closest to mine ..

    AlaaShaker

    August 20, 2008 at 9:36 pm

  25. in C# at least it will πŸ™‚

    Mustafa

    August 22, 2008 at 2:44 am

  26. To Mustafa:
    No, it won’t .. try it πŸ˜€

    AlaaShaker

    August 22, 2008 at 6:32 pm

  27. To Mustafa:
    No, it won’t .. try it .. you should get:

    Error : ‘YourNamespace.Creator.Secret.Secret()’ is inaccessible due to its protection level

    AlaaShaker

    August 22, 2008 at 6:34 pm

  28. […] Creator SOLVED [Problem of the Week] After a vigorous week of solutions to this hard problem, I will now post my solution […]

  29. […] Easier One [Problem of the week] if you think last week’s problem from Alaa wasn’t that easy. and mine in the week before that was a little […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: