design problem with inheritance

Discussion in 'C++' started by alessio211734, Aug 23, 2011.

  1. I am reading a design pattern book.

    the example is a class duck that a method fly

    class duck
    {
    virtual void fly(){......}
    void display();

    }

    class FakeDuck: public duck()
    {
    void fly(){ override to nothing...}

    }

    if I have a FakeDuck class it's need to override the fly method to
    nothing because a FakeDuck can't fly.
    And so on for every subclass of duck that have no fly feature.


    book propose the pattern strategy and to extern the fly behavior as a
    external class

    class FlyBehavior
    {
    virtual void fly()=0;
    }

    class NoFly: public FlyBehavior
    {
    virtual void fly(){ printf("can't fly")};


    and the class duck became

    class duck
    {
    FlyBehavior * bhv;
    void performFly(){ bhv->fly(); }
    }

    I have doubts about the design proposed because book says
    encapsulating the algorithms in a class hierarchy and make them
    interchangeable.
    But ok if I need the private data about duck class to implement the
    fly method of NoFly class how can do it??
    What's the best solutions?


    Thanks in advance.

    Ale.
    alessio211734, Aug 23, 2011
    #1
    1. Advertising

  2. alessio211734

    Paul Guest

    On Aug 23, 3:09 pm, alessio211734 <> wrote:
    > I am reading a design pattern book.
    >
    > the example is a class duck that a method fly
    >
    > class duck
    > {
    >     virtual void fly(){......}
    >     void display();
    >
    > }
    >
    > class FakeDuck: public duck()
    > {
    >     void fly(){ override to nothing...}
    >
    > }
    >
    > if I have a  FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.
    >
    > book propose the pattern strategy and to extern the fly behavior as a
    > external class
    >
    > class FlyBehavior
    > {
    >      virtual void fly()=0;
    >
    > }
    >
    > class NoFly: public FlyBehavior
    > {
    >     virtual void fly(){ printf("can't fly")};
    >
    > and the class duck became
    >
    > class duck
    > {
    >     FlyBehavior * bhv;
    >     void performFly(){ bhv->fly(); }
    >
    > }
    >
    > I have doubts about the design proposed because book says
    > encapsulating the algorithms in a class hierarchy and make them
    > interchangeable.
    > But ok if I need the private data about duck class to implement the
    > fly method of NoFly class how can do it??
    > What's the best solutions?
    >

    Hi I see a problem with your ..
    void performFly(){ bhv->fly();

    bhv needs to be initialed to point to either a Fly or NoFly object. I
    did a little test program with an example of initialisng a default
    Constructor to NoFly and a Constructor that takes a bool value for fly
    or nofly.

    class FlyBehav{
    public:
    virtual void Fly()=0;
    };

    class NoFly: public FlyBehav{
    public:
    void Fly(){std::cout<<"Cannot Fly\n";}
    };
    class CanFly: public FlyBehav{
    public:
    void Fly(){std::cout<<"Flying across the sky\n";}
    };

    class Duck{
    FlyBehav* ptrFly;
    bool can_fly;
    public:
    Duck():can_fly(0),ptrFly(new NoFly){}
    Duck(bool b):can_fly(b){
    if(b)ptrFly=new CanFly;
    else ptrFly=new NoFly;
    }
    void PerformFly(){ptrFly->Fly();}
    ~Duck(){delete ptrFly;}
    };

    int main() {
    Duck flying_duck(1);
    d.PerformFly();
    }


    HTH
    Paul, Aug 23, 2011
    #2
    1. Advertising

  3. alessio211734

    Paul Guest

    On Aug 23, 4:52 pm, Paul <> wrote:
    > On Aug 23, 3:09 pm, alessio211734 <> wrote:

    <snip>
    >
    > int main() {
    >         Duck flying_duck(1);
    >         d.PerformFly();

    Above should be:
    flying_duck.PerformFly();

    :)
    Paul, Aug 23, 2011
    #3
  4. ok thanks for correction, I put a incomplete code but my problem is
    another, how with this design I can access to private data of class
    Duck
    when implements the Fly method?


    class NoFly: public FlyBehav{
    public:
    void Fly(){std::cout<<"Cannot Fly\n";}
    };

    class CanFly: public FlyBehav{
    public:
    void Fly()
    {
    // how get Duck private data???
    std::cout<<"Flying across the sky\n";
    }

    };

    if the Fly() method of CanFly or NoFly needs to privata data of the
    class Duck how can do it with this design?

    Maybe I could pass a pointer to base class Duck but so I can access
    only to public member of Duck. I would like access to Duck private
    data.


    class FlyBehav{
    public:
    FlyBehav(Duck * _ownClass)
    {
    ownClass=_ownClass;
    }
    virtual void Fly()=0;
    };

    class CanFly: public FlyBehav{
    public:
    CanFly(Duck * ownClass)
    {

    }
    void Fly()
    {
    std::cout<<"Flying across the sky\n";}
    ownClass->DuckPublicMethod();
    // no ways to acess to Duck private data or private
    method!!!
    }
    };
    alessio211734, Aug 23, 2011
    #4
  5. alessio211734

    Paul Guest

    On Aug 23, 5:53 pm, alessio211734 <> wrote:
    > ok thanks for correction, I put a incomplete code but my problem is
    > another, how with this design I can access to private data of class
    > Duck
    > when implements the Fly method?
    >
    > class NoFly: public FlyBehav{
    > public:
    >         void Fly(){std::cout<<"Cannot Fly\n";}
    >
    > };
    >
    > class CanFly: public FlyBehav{
    > public:
    >         void Fly()
    >         {
    >             // how get Duck private data???
    >             std::cout<<"Flying across the sky\n";
    >         }
    >
    > };
    >
    > if the Fly() method of CanFly or NoFly needs to privata data of the
    > class Duck how can do it with this design?
    >
    > Maybe I could pass a pointer to base class Duck but so I can access
    > only to public member of Duck. I would like access to Duck private
    > data.
    >
    > class FlyBehav{
    > public:
    >         FlyBehav(Duck * _ownClass)
    >         {
    >             ownClass=_ownClass;
    >         }
    >         virtual void Fly()=0;
    >
    > };
    >
    > class CanFly: public FlyBehav{
    > public:
    >         CanFly(Duck * ownClass)
    >         {
    >
    >         }
    >         void Fly()
    >         {
    >              std::cout<<"Flying across the sky\n";}
    >              ownClass->DuckPublicMethod();
    >              // no ways to acess to Duck private data or private
    > method!!!
    >         }
    >
    >
    >
    > };- Hide quoted text -
    >
    > - Show quoted text -


    Make it a friend class.

    class Duck{
    friend class CanFly;
    .....
    }

    This gives CanFly access to Ducks private members ^_^.
    I don't know how it works with inheritance OTTOMH but maybe its
    possible to make FlyBehav a friend and therefore allow its derived
    access too. Just a thought but I'd need to go read up on it to get all
    the details.

    And if you derived duck to e.g: fakeduck, again I don't know all the
    detialed rules of friend classes when inheritance gets a bit
    complicated. WOuld need to refer to a manual.

    HTH
    Paul, Aug 23, 2011
    #5
  6. On 8/23/2011 12:53 PM, alessio211734 wrote:
    >
    > ok thanks for correction, I put a incomplete code but my problem is
    > another, how with this design I can access to private data of class
    > Duck
    > when implements the Fly method?


    First off, what correction? If you post a reply, consider quoting or at
    least commenting on what you're referring to.

    Second, nobody but Duck (or its friends) can access private members of
    Duck. If you need to get to those from derived classes, provide an
    interface (possibly 'protected' to limit access to derived classes only)
    in the Duck itself.

    >
    >
    > class NoFly: public FlyBehav{
    > public:
    > void Fly(){std::cout<<"Cannot Fly\n";}
    > };
    >
    > class CanFly: public FlyBehav{
    > public:
    > void Fly()
    > {
    > // how get Duck private data???
    > std::cout<<"Flying across the sky\n";
    > }
    >
    > };
    >
    > if the Fly() method of CanFly or NoFly needs to privata data of the
    > class Duck how can do it with this design?
    >
    > Maybe I could pass a pointer to base class Duck but so I can access
    > only to public member of Duck. I would like access to Duck private
    > data.


    That's just a wrong premise. Private data are private for a very simple
    reason: nobody should have access to them, not even derived classes. If
    Duck needs to grant access to some data to the derived classes for
    whatever reason, make the members 'protected'.

    >
    >
    > class FlyBehav{
    > public:
    > FlyBehav(Duck * _ownClass)
    > {
    > ownClass=_ownClass;
    > }
    > virtual void Fly()=0;
    > };
    >
    > class CanFly: public FlyBehav{
    > public:
    > CanFly(Duck * ownClass)
    > {
    >
    > }
    > void Fly()
    > {
    > std::cout<<"Flying across the sky\n";}
    > ownClass->DuckPublicMethod();
    > // no ways to acess to Duck private data or private
    > method!!!
    > }
    > };
    >


    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 23, 2011
    #6
  7. Paul <> wrote:
    > Hi I see a problem with your ..
    > void performFly(){ bhv->fly();
    >
    > bhv needs to be initialed to point to either a Fly or NoFly object. I
    > did a little test program with an example of initialisng a default
    > Constructor to NoFly and a Constructor that takes a bool value for fly
    > or nofly.


    Your ability to always completely miss the point never ceases to
    amaze me.

    You are exactly the type of person that if someone told you
    that one morning when he was driving to work his car broke and he
    returned home to call a garage, only to find his wife cheating on him
    with the neighbor and asked you what to do, you would start explaining
    him what to check in the car to see what's broken.
    Juha Nieminen, Aug 23, 2011
    #7
  8. alessio211734

    Paul Guest

    On Aug 23, 6:57 pm, Juha Nieminen <> wrote:
    > Paul <> wrote:
    > > Hi I see a problem with your ..
    > > void performFly(){ bhv->fly();

    >
    > > bhv needs to be initialed to point to either a Fly or NoFly object. I
    > > did a little test program with an example of initialisng a default
    > > Constructor to NoFly and a Constructor that takes a bool value for fly
    > > or nofly.

    >
    >   Your ability to always completely miss the point never ceases to
    > amaze me.
    >
    >   You are exactly the type of person that if someone told you
    > that one morning when he was driving to work his car broke and he
    > returned home to call a garage, only to find his wife cheating on him
    > with the neighbor and asked you what to do, you would start explaining
    > him what to check in the car to see what's broken.


    Ha ha :)
    Paul, Aug 23, 2011
    #8
  9. > First off, what correction?  If you post a reply, consider quoting or at
    > least commenting on what you're referring to.
    >
    > Second, nobody but Duck (or its friends) can access private members of
    > Duck.  If you need to get to those from derived classes, provide an
    > interface (possibly 'protected' to limit access to derived classes only)
    > in the Duck itself.


    Ok thanks, you explain me how c++ work with friend and protected
    keyword but I ask you how adjust my design.
    In the initial design I have one class Duck and some derived class
    StandardDuck and FakeDuck both derived from Duck class.
    the class FakeDuck override the fly method and make it empty. I think
    this is a bad design.
    Book proposed to use a pattern strategy and use FlyBehav interface to
    handle behavior as fly and nofly

    class FlyBehav{
    public:
    virtual void Fly()=0;
    };

    class NoFly: public FlyBehav{
    public:
    void Fly(){std::cout<<"Cannot Fly\n";}
    };

    class CanFly: public FlyBehav{
    public:
    void Fly(){std::cout<<"Flying across the sky\n";}
    };

    I think this pattern is right if method Fly no needs private data of
    Duck class as in this example.
    but in a real case I think that the Fly method needs to data about
    Duck class. And so in this case what's the best design to solve my
    problem?
    I would like avoid to create a class FakeDuck with a empty method. I
    think Strategy it's not right.




    A.
    alessio211734, Aug 23, 2011
    #9
  10. On 8/23/2011 4:48 PM, alessio211734 wrote:
    >> First off, what correction? If you post a reply, consider quoting or at
    >> least commenting on what you're referring to.
    >>
    >> Second, nobody but Duck (or its friends) can access private members of
    >> Duck. If you need to get to those from derived classes, provide an
    >> interface (possibly 'protected' to limit access to derived classes only)
    >> in the Duck itself.

    >
    > Ok thanks, you explain me how c++ work with friend and protected
    > keyword but I ask you how adjust my design.


    How do you adjust a radio to give you coffee? You can't. A coffee
    machine is not going to play a tune, unless it is *also* a radio. If
    it's just a coffee machine, it cannot be "adjusted" to become a radio.

    > In the initial design I have one class Duck and some derived class
    > StandardDuck and FakeDuck both derived from Duck class.


    So?

    > the class FakeDuck override the fly method and make it empty. I think
    > this is a bad design.


    You didn't explain why it's bad.

    What's a Duck? Something that has the 'fly' method. By your design,
    since you derived 'FakeDuck' from 'Duck', publicly, you said,
    essentially, that a 'FakeDuck' *is-a* 'Duck', which means 'FakeDuck'
    *shall have* a 'fly' method. How is that "bad", if that's your design?
    If 'FakeDuck' is NOT a 'Duck', don't derive it from 'Duck'.

    > Book proposed to use a pattern strategy and use FlyBehav interface to
    > handle behavior as fly and nofly
    >
    > class FlyBehav{
    > public:
    > virtual void Fly()=0;
    > };
    >
    > class NoFly: public FlyBehav{
    > public:
    > void Fly(){std::cout<<"Cannot Fly\n";}
    > };
    >
    > class CanFly: public FlyBehav{
    > public:
    > void Fly(){std::cout<<"Flying across the sky\n";}
    > };


    Rename 'FlyBehav' to 'Duck', 'CanFly' to 'StandardDuck', and 'NoFly' to
    'FakeDuck', and you get the same hierarchy as before.

    > I think this pattern is right if method Fly no needs private data of
    > Duck class as in this example.


    I don't get it.

    > but in a real case I think that the Fly method needs to data about
    > Duck class. And so in this case what's the best design to solve my
    > problem?


    I don't know. WHAT PROBLEM?

    > I would like avoid to create a class FakeDuck with a empty method. I
    > think Strategy it's not right.


    So, don't use the Strategy.

    Perhaps you need to start with the PROBLEM you're trying to solve
    instead of the NON-WORKING solutions you have come up with.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Aug 23, 2011
    #10
  11. alessio211734

    Paul N Guest

    On Aug 23, 3:09 pm, alessio211734 <> wrote:
    > I am reading a design pattern book.
    >
    > the example is a class duck that a method fly
    >
    > class duck
    > {
    > virtual void fly(){......}
    > void display();
    >
    > }
    >
    > class FakeDuck: public duck()
    > {
    > void fly(){ override to nothing...}
    >
    > }
    >
    > if I have a FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.
    >
    > book propose the pattern strategy and to extern the fly behavior as a
    > external class
    >
    > class FlyBehavior
    > {
    > virtual void fly()=0;
    >
    > }
    >
    > class NoFly: public FlyBehavior
    > {
    > virtual void fly(){ printf("can't fly")};
    >
    > and the class duck became
    >
    > class duck
    > {
    > FlyBehavior * bhv;
    > void performFly(){ bhv->fly(); }
    >
    > }
    >
    > I have doubts about the design proposed because book says
    > encapsulating the algorithms in a class hierarchy and make them
    > interchangeable.
    > But ok if I need the private data about duck class to implement the
    > fly method of NoFly class how can do it??
    > What's the best solutions?


    I'm not an expert, but it seems to me that the proposed solution is
    trying to provide a "library" of different fly behaviours, with each
    type of duck able to choose any of them, presumably in a way that
    doesn't fit in well with the duck hierarchy. So if you want the fly
    behaviour to depend on details of the particular duck you are probably
    using the wrong solution.

    Of course, if the different fly behaviours get built out of standard
    blocks, you could define virtual functions to do these, perhaps
    something like:


    class Fly: public FlyBehavior
    {
    virtual void fly(duck *d) { d -> FlapWings(); } };

    class duck
    {
    ....
    virtual void FlapWings(); }

    Hope that helps.
    Paul.
    Paul N, Aug 23, 2011
    #11
  12. On Aug 23, 7:09 am, alessio211734 <> wrote:
    > I am reading a design pattern book.
    >
    > the example is a class duck that a method fly
    >
    > class duck
    > {
    >     virtual void fly(){......}
    >     void display();
    >
    > }
    >
    > class FakeDuck: public duck()
    > {
    >     void fly(){ override to nothing...}
    >
    > }
    >
    > if I have a  FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.
    >
    > book propose the pattern strategy and to extern the fly behavior as a
    > external class
    >
    > class FlyBehavior
    > {
    >      virtual void fly()=0;
    >
    > }
    >
    > class NoFly: public FlyBehavior
    > {
    >     virtual void fly(){ printf("can't fly")};
    >
    > and the class duck became
    >
    > class duck
    > {
    >     FlyBehavior * bhv;
    >     void performFly(){ bhv->fly(); }
    >
    > }
    >
    > I have doubts about the design proposed because book says
    > encapsulating the algorithms in a class hierarchy and make them
    > interchangeable.
    > But ok if I need the private data about duck class to implement the
    > fly method of NoFly class how can do it??
    > What's the best solutions?
    >
    > Thanks in advance.


    See the FAQ.

    http://www.parashift.com/c -faq-lite/proper-inheritance.html#faq-21.6

    There is no single right answer. A good answer depends heavily upon
    your particular problem, which you have not explained at all.
    Joshua Maurice, Aug 23, 2011
    #12
  13. On 24 Ago, 01:09, Paul N <> wrote:
    > On Aug 23, 3:09 pm, alessio211734 <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > I am reading a design pattern book.

    >
    > > the example is a class duck that a method fly

    >
    > > class duck
    > > {
    > >     virtual void fly(){......}
    > >     void display();

    >
    > > }

    >
    > > class FakeDuck: public duck()
    > > {
    > >     void fly(){ override to nothing...}

    >
    > > }

    >
    > > if I have a  FakeDuck class it's need to override the fly method to
    > > nothing because a FakeDuck can't fly.
    > > And so on for every subclass of duck that have no fly feature.

    >
    > > book propose the pattern strategy and to extern the fly behavior as a
    > > external class

    >
    > > class FlyBehavior
    > > {
    > >      virtual void fly()=0;

    >
    > > }

    >
    > > class NoFly: public FlyBehavior
    > > {
    > >     virtual void fly(){ printf("can't fly")};

    >
    > > and the class duck became

    >
    > > class duck
    > > {
    > >     FlyBehavior * bhv;
    > >     void performFly(){ bhv->fly(); }

    >
    > > }

    >
    > > I have doubts about the design proposed because book says
    > > encapsulating the algorithms in a class hierarchy and make them
    > > interchangeable.
    > > But ok if I need the private data about duck class to implement the
    > > fly method of NoFly class how can do it??
    > > What's the best solutions?

    >
    > I'm not an expert, but it seems to me that the proposed solution is
    > trying to provide a "library" of different fly behaviours, with each
    > type of duck able to choose any of them, presumably in a way that
    > doesn't fit in well with the duck hierarchy. So if you want the fly
    > behaviour to depend on details of the particular duck you are probably
    > using the wrong solution.
    >
    > Of course, if the different fly behaviours get built out of standard
    > blocks, you could define virtual functions to do these, perhaps
    > something like:
    >
    > class Fly: public FlyBehavior
    > {
    > virtual void fly(duck *d) { d -> FlapWings(); } };
    >
    > class duck
    > {
    > ...
    > virtual void FlapWings(); }
    >
    > Hope that helps.
    > Paul.


    Thanks, this is the first solution about this thread but if FlapWings
    is a private method I have no way to access to it?!?
    alessio211734, Aug 24, 2011
    #13
  14. alessio211734

    Paul Guest

    On Aug 24, 10:07 am, alessio211734 <> wrote:
    > On 24 Ago, 01:09, Paul N <> wrote:
    >
    >
    >
    >
    >
    > > On Aug 23, 3:09 pm, alessio211734 <> wrote:

    >
    > > > I am reading a design pattern book.

    >
    > > > the example is a class duck that a method fly

    >
    > > > class duck
    > > > {
    > > >     virtual void fly(){......}
    > > >     void display();

    >
    > > > }

    >
    > > > class FakeDuck: public duck()
    > > > {
    > > >     void fly(){ override to nothing...}

    >
    > > > }

    >
    > > > if I have a  FakeDuck class it's need to override the fly method to
    > > > nothing because a FakeDuck can't fly.
    > > > And so on for every subclass of duck that have no fly feature.

    >
    > > > book propose the pattern strategy and to extern the fly behavior as a
    > > > external class

    >
    > > > class FlyBehavior
    > > > {
    > > >      virtual void fly()=0;

    >
    > > > }

    >
    > > > class NoFly: public FlyBehavior
    > > > {
    > > >     virtual void fly(){ printf("can't fly")};

    >
    > > > and the class duck became

    >
    > > > class duck
    > > > {
    > > >     FlyBehavior * bhv;
    > > >     void performFly(){ bhv->fly(); }

    >
    > > > }

    >
    > > > I have doubts about the design proposed because book says
    > > > encapsulating the algorithms in a class hierarchy and make them
    > > > interchangeable.
    > > > But ok if I need the private data about duck class to implement the
    > > > fly method of NoFly class how can do it??
    > > > What's the best solutions?

    >
    > > I'm not an expert, but it seems to me that the proposed solution is
    > > trying to provide a "library" of different fly behaviours, with each
    > > type of duck able to choose any of them, presumably in a way that
    > > doesn't fit in well with the duck hierarchy. So if you want the fly
    > > behaviour to depend on details of the particular duck you are probably
    > > using the wrong solution.

    >
    > > Of course, if the different fly behaviours get built out of standard
    > > blocks, you could define virtual functions to do these, perhaps
    > > something like:

    >
    > > class Fly: public FlyBehavior
    > > {
    > > virtual void fly(duck *d) { d -> FlapWings(); } };

    >
    > > class duck
    > > {
    > > ...
    > > virtual void FlapWings(); }

    >
    > > Hope that helps.
    > > Paul.

    >
    > Thanks, this is the first solution about this thread but if FlapWings
    > is a private method I have no way to access to it?!?- Hide quoted text -
    >

    You would need to make flapwings public.
    Paul, Aug 24, 2011
    #14
  15. > You would need to make flapwings public.
    Yes this is the lack I see with this design, I should do public
    methods in the class Duck to access them from a external class.
    alessio211734, Aug 24, 2011
    #15
  16. On 24 août, 16:21, alessio211734 <> wrote:
    > > You would need to make flapwings public.

    >
    > Yes this is the lack I see with this design, I should do public
    > methods in the class Duck to access them from a external class.


    There is an alternative, make FlyBehavior a friend of Duck and code
    protected class member function in FlyBehavior for accessing duck's
    private members. That way, only class inheriting FlyBehavior can
    access those members.

    If you are afraid of cluttering the interface, you can also declare a
    protected nested class.
    Example:
    #include <iostream>

    class duck;

    class FlyBehavior
    {
    public: virtual void fly( duck* d) = 0;

    protected:
    friend class duck; // duck can declare DuckFlyBehavior a friend;
    class DuckFlyBehavior;
    };


    class duck
    {
    public:
    duck(FlyBehavior& f):_fb(&f){}

    void fly(){ _fb->fly(this); }

    protected:
    friend class FlyBehavior::DuckFlyBehavior; // DuckFlyBehavior can
    call FlapWings
    void FlapWings(){ std::cout<<"flap flap\n"; }

    private:
    FlyBehavior* _fb;
    };


    struct FlyBehavior::DuckFlyBehavior
    {
    // break encapsulation of duck
    static void FlapWings(duck* d){
    d->FlapWings();
    }
    };

    class Fly: public FlyBehavior
    {
    public:
    virtual void fly(duck *d) { DuckFlyBehavior::FlapWings(d); }
    };

    int main()
    {
    Fly fly;
    duck donald(fly);

    donald.fly();
    }

    --
    Michael
    Michael DOUBEZ, Aug 25, 2011
    #16
  17. alessio211734

    James Kanze Guest

    On Aug 23, 3:09 pm, alessio211734 <> wrote:
    > I am reading a design pattern book.


    > the example is a class duck that a method fly


    > class duck
    > {
    > virtual void fly(){......}
    > void display();
    > }


    > class FakeDuck: public duck()
    > {
    > void fly(){ override to nothing...}
    > }


    > if I have a FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.


    If there are many such subclasses, then perhaps fly shouldn't be
    a function of the base interface. If there are many such
    subclasses, however, Duck probably isn't a very good name for
    the base class. It's very, very exceptional that ducks can't
    fly.

    More generally, however, the problem might occur for Animal;
    some animals can fly, but most can't. The solution in such
    cases is generally to extend the interface:

    class Animal
    {
    // No function fly.
    };

    class FlyingAnimal : public virtual Animal
    {
    virtual void fly() = 0;
    };

    Animals which can fly implement FlyingAnimal; animals which
    can't implement Animal. Client code which needs to make the
    animal fly will first dynamic_cast the Animal* to FlyingAnimal*,
    and take whatever actions are appropriate if the dynamic_cast
    fails.

    (Note too that the inheritance is virtual. This should almost
    always be the case when extending an interface: one can easily
    imagine a SwimmingAnimal, a WalkingAnimal, etc., and concrete
    animals which implement more than one of these.)

    > book propose the pattern strategy and to extern the fly
    > behavior as a
    > class FlyBehavior
    > {
    > virtual void fly()=0;
    > }


    I think you're misunderstanding the book. The strategy pattern
    is about implementation, not interface.

    > class NoFly: public FlyBehavior
    > {
    > virtual void fly(){ printf("can't fly")};


    > and the class duck became


    > class duck
    > {
    > FlyBehavior * bhv;
    > void performFly(){ bhv->fly(); }
    > }


    > I have doubts about the design proposed because book says
    > encapsulating the algorithms in a class hierarchy and make them
    > interchangeable.
    > But ok if I need the private data about duck class to implement the
    > fly method of NoFly class how can do it??


    Then perhaps the strategy pattern is not the best solution. The
    big advantage of the strategy pattern is that it allows changing
    the strategy dynamically. If you don't need this, you can use
    the template method pattern, or mixins---a certain type of wing
    supports flying, and an animal which has this type of wing and
    can fly inherits (privately, since this is implementation) from
    this type of wing; the "member data" to which the function needs
    access is a class which implements the actual function.

    But it depends. In such cases, it's not rare that in certain
    cases, the concrete strategy is a member (usually private) of
    the concrete class. In this case, the concrete strategy has
    can have access to the member data.

    --
    James Kanze
    James Kanze, Aug 26, 2011
    #17
  18. alessio211734

    Noah Roberts Guest

    On Aug 23, 7:09 am, alessio211734 <> wrote:
    > I am reading a design pattern book.
    >
    > the example is a class duck that a method fly
    >
    > class duck
    > {
    >     virtual void fly(){......}
    >     void display();
    >
    > }
    >
    > class FakeDuck: public duck()
    > {
    >     void fly(){ override to nothing...}
    >
    > }
    >
    > if I have a  FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.
    >
    > book propose the pattern strategy and to extern the fly behavior as a
    > external class
    >


    It's a poor example and a poor reason to use a strategy. You use
    strategy patterns when it makes sense for the concept to have
    different behaviors in a certain area. For example, the sort-like
    routines in the standard library all allow you to override their
    comparison routine. This is because though you might compare
    differently among various types or situations, you will always make
    some sort of comparison or you wouldn't bother sorting. It makes zero
    sense to call sort with a noop comparator.

    What this book has done is show how to work around a questionable
    interface design in a questionable manner. I see no benefit to using
    the strategy over providing a noop stub in the subclass. In fact, of
    bad solutions I think the latter is probably the better. The real
    solution here is to realize that since not all ducks fly, pretending
    that they do is a bad design choice. The fly functionality should be
    an aspect only of those kinds of ducks that DO fly. Thus you have
    something more like so:

    struct duck
    {
    };

    struct flying_duck : duck
    {
    virtual void fly() = 0;
    };

    struct fake_duck : duck {};

    Alternatively one might propose completely different design choices
    since flight ability is a static property of some kinds of birds. One
    might use multiple inheritence to provide a can_fly interface that
    some animal derivatives can advertize...this allows one to use the
    same flight interface for bats as one does for birds.

    If the function overload here was "move" or "motivate" or something
    like that, one might use the strategy pattern to provide various
    alternatives such as fly, walk, slither, etc... For the case they've
    shown here though I see it as utterly inappropriate.
    Noah Roberts, Aug 27, 2011
    #18
  19. alessio211734

    Noah Roberts Guest

    On Aug 23, 7:09 am, alessio211734 <> wrote:
    > I am reading a design pattern book.
    >
    > the example is a class duck that a method fly
    >
    > class duck
    > {
    >     virtual void fly(){......}
    >     void display();
    >
    > }
    >
    > class FakeDuck: public duck()
    > {
    >     void fly(){ override to nothing...}
    >
    > }
    >
    > if I have a  FakeDuck class it's need to override the fly method to
    > nothing because a FakeDuck can't fly.
    > And so on for every subclass of duck that have no fly feature.
    >
    > book propose the pattern strategy and to extern the fly behavior as a
    > external class
    >


    Actually, I thought of a better example. I see the strategy pattern
    as a way to replace behavior dynamically. There is a static version
    of the strategy pattern in C++ using templates, but as far as "design
    patterns" goes I see this as primarily a runtime alteration.

    Consider various animals you might design classes for. Some animals
    fly, some walk, some run, some slither, etc... Some can do more than
    one thing. You could design these characteristics in a variety of
    ways but they'll remain primarily static choices, things that do not
    change based on the state of the program.

    What if though you wanted to write an escapePredation function?
    Consider then what ducks might do... Depending on the situation they
    might run into a lake and swim away. Other times they may fly to the
    same lake and swim. They might simply fly as far away as they can.
    Other times they run away into the woods or something, though more
    often toward some body of water. If its a mother duck it might not
    escape at all but turn and fight....or at least flap around violently.

    All of these are situational concerns that are based on the
    surroundings of the animal and its current state of mind. How
    frightened is it, etc... Some of these strategies are shared by other
    animals or birds. For example, most birds will use the fly strategy
    to flee in some situations. Your strategy here then becomes something
    that operates on animals and the interfaces you've set up, and this
    strategy could be returned by your duck class if you call a
    "getEscapeStrategy()" function.
    Noah Roberts, Aug 27, 2011
    #19
  20. alessio211734

    Rui Maciel Guest

    alessio211734 wrote:

    > But ok if I need the private data about duck class to implement the
    > fly method of NoFly class how can do it??
    > What's the best solutions?


    You should pass class duck's private data to the methods defined in class
    FlyBehavior as parameters. So, taking your example:

    <code>
    class FlyBehavior
    {
    virtual void fly(DuckData &)=0;
    }


    class NoFly
    : public FlyBehavior
    {
    virtual void fly(DuckData &){ std::cout << "couldn't fly" << std::endl;}
    };


    class duck
    {
    DuckData data;

    FlyBehavior * bhv;
    void performFly(){ bhv->fly(data); }
    }
    </code>


    Other things to note:
    - as Noah Roberts already pointed out, this example is a rather poor use of
    a strategy pattern. A much better example would be a class that implements
    some sort of file output where the intended file format is set through a
    strategy pattern.
    - try to avoid printf() and the like in C++. It may not look like it, but
    iostream is your friend.


    Hope this helps,
    Rui Maciel
    Rui Maciel, Aug 27, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,119
    Martijn van Steenbergen
    Dec 21, 2003
  2. cppsks
    Replies:
    0
    Views:
    805
    cppsks
    Oct 27, 2004
  3. Replies:
    4
    Views:
    329
    Noah Roberts
    Jul 13, 2006
  4. karthikbalaguru
    Replies:
    9
    Views:
    1,025
  5. Daniel Pitts
    Replies:
    27
    Views:
    1,874
    Mike Schilling
    Feb 27, 2008
Loading...

Share This Page